Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
- 'android/jni/**'
- 'scripts/test-*'
- 'scripts/lib/**'
# package.json `files` lists the submodule sources that ship.
- 'package.json'
- 'scripts/check-packlist.js'
# TS reference the C++ golden vectors are generated from.
- 'src/updateFlowCore.ts'
- 'scripts/generate-flow-vectors.ts'
Expand Down Expand Up @@ -80,6 +83,13 @@ jobs:
with:
submodules: recursive

# Before anything builds inside the submodules: the published package
# lists the HDiffPatch / lzma sources and headers one by one, so a
# header missing from package.json `files` would only surface in a
# consumer's pod install. Packs the real tarball and compiles from it.
- name: Packed native sources compile on their own
run: node scripts/check-packlist.js --compile

- name: Install build dependencies
# clang (+ libFuzzer runtime) is for the bounded fuzz step below.
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev libbz2-dev clang
Expand Down
21 changes: 19 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,25 @@
"android/src",
"!android/src/test",
"android/lib",
"android/jni",
"!android/jni/HDiffPatch/test",
"android/jni/*.mk",
"android/jni/HDiffPatch/LICENSE",
"android/jni/HDiffPatch/README.md",
"android/jni/HDiffPatch/decompress_plugin_demo.h",
"android/jni/HDiffPatch/dirDiffPatch/dir_patch/dir_patch_types.h",
"android/jni/HDiffPatch/file_for_patch.c",
"android/jni/HDiffPatch/file_for_patch.h",
"android/jni/HDiffPatch/libHDiffPatch/HPatch/patch.c",
"android/jni/HDiffPatch/libHDiffPatch/HPatch/patch.h",
"android/jni/HDiffPatch/libHDiffPatch/HPatch/patch_private.h",
"android/jni/HDiffPatch/libHDiffPatch/HPatch/patch_types.h",
"android/jni/lzma/DOC/lzma-sdk.txt",
"android/jni/lzma/C/7zTypes.h",
"android/jni/lzma/C/Compiler.h",
"android/jni/lzma/C/Precomp.h",
"android/jni/lzma/C/LzmaDec.c",
"android/jni/lzma/C/LzmaDec.h",
"android/jni/lzma/C/Lzma2Dec.c",
"android/jni/lzma/C/Lzma2Dec.h",
"android/build.gradle",
"android/proguard.pro",
"ios",
Expand Down
72 changes: 71 additions & 1 deletion scripts/check-packlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const { execFileSync } = require('child_process');
const { files: filesField } = require('../package.json');

const release = process.argv.includes('--release');
// Also compile the packed native sources (needs the submodules and a C
// compiler; test.yml's C++ job runs it).
const compile = process.argv.includes('--compile');

// A `files` entry (glob, file or directory) as a regex over packed paths:
// the entry itself or anything below it.
Expand Down Expand Up @@ -79,6 +82,10 @@ const required = [
'android/jni/HDiffPatch/file_for_patch.c',
'android/jni/lzma/C/LzmaDec.c',
'android/jni/lzma/C/Lzma2Dec.c',
// The submodules ship only these sources and headers, so their
// licenses must ship with them.
'android/jni/HDiffPatch/LICENSE',
'android/jni/lzma/DOC/lzma-sdk.txt',
]
: []),
];
Expand Down Expand Up @@ -120,6 +127,68 @@ for (const abi of requiredAbis) {
}
}

// The package must compile on its own (--compile): `files` lists the submodule
// sources and headers one by one (the rest of HDiffPatch / lzma does not
// ship), and the e2e builds copy the source tree, so they would not notice a
// header missing from the list. Unpack the real tarball and syntax-check the
// C sources the podspec (and Harmony's CMakeLists.txt) compile, plus the
// cores that include them, using only the unpacked files.
function compilePackedSources() {
const fs = require('fs');
const os = require('os');
const path = require('path');
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'rnu-packlist-'));
try {
const out = execFileSync(
'npm',
['pack', '--json', '--ignore-scripts', '--pack-destination', dir],
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }
);
const result = JSON.parse(out);
const tarball = (Array.isArray(result) ? result[0] : Object.values(result)[0])
.filename;
execFileSync('tar', ['-xzf', path.join(dir, path.basename(tarball)), '-C', dir]);
const root = path.join(dir, 'package');
const sources = [
'android/jni/HDiffPatch/libHDiffPatch/HPatch/patch.c',
'android/jni/HDiffPatch/file_for_patch.c',
'android/jni/lzma/C/LzmaDec.c',
'android/jni/lzma/C/Lzma2Dec.c',
...fs
.readdirSync(path.join(root, 'cpp/hpatch'))
.filter((name) => name.endsWith('.c'))
.map((name) => `cpp/hpatch/${name}`),
];
const cxxSources = fs
.readdirSync(path.join(root, 'cpp/patch_core'))
.filter((name) => name.endsWith('.cpp'))
.map((name) => `cpp/patch_core/${name}`);
for (const source of sources) {
try {
execFileSync('cc', ['-fsyntax-only', source], { cwd: root, stdio: 'pipe' });
} catch (e) {
problems.push(`packed ${source} does not compile: ${String(e.stderr).trim()}`);
}
}
for (const source of cxxSources) {
try {
execFileSync('c++', ['-std=c++17', '-fsyntax-only', source], {
cwd: root,
stdio: 'pipe',
});
} catch (e) {
problems.push(`packed ${source} does not compile: ${String(e.stderr).trim()}`);
}
}
} finally {
fs.rmSync(dir, { recursive: true, force: true });
}
}

if (compile && problems.length === 0) {
compilePackedSources();
}

if (problems.length > 0) {
console.error(
`check-packlist: ${problems.length} problem(s) in ${files.length} files`
Expand All @@ -130,5 +199,6 @@ if (problems.length > 0) {
process.exit(1);
}
console.log(
`check-packlist: ${files.length} files OK${release ? ' (release)' : ''}`
`check-packlist: ${files.length} files OK${release ? ' (release)' : ''}` +
`${compile ? ', packed native sources compile' : ''}`
);
Loading