Skip to content

Commit

Permalink
fix: revert "feat: allow providing properties (such as unpack) in `…
Browse files Browse the repository at this point in the history
…ordering` input file" (#356)

Revert "feat: allow providing properties (such as `unpack`) in `ordering` inp…"

This reverts commit b2f73c8.
  • Loading branch information
yangannyx authored Feb 11, 2025
1 parent b2f73c8 commit 9b7ccfe
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 115 deletions.
126 changes: 50 additions & 76 deletions src/asar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,73 +33,6 @@ function isUnpackedDir(dirPath: string, pattern: string, unpackDirs: string[]) {
}
}

export type FileProperties = {
filepath: string;
properties: {
unpack?: boolean;
};
};

async function getFileOrdering(
options: CreateOptions,
src: string,
filenames: string[],
): Promise<FileProperties[]> {
if (!options.ordering) {
return filenames.map<FileProperties>((filepath) => ({ filepath, properties: {} }));
}
const orderingMap: FileProperties[] = (await fs.readFile(options.ordering))
.toString()
.split('\n')
.map<FileProperties>((line) => {
line = line.trim();
const config: FileProperties = { filepath: line, properties: {} };
const colonIndex = line.indexOf(':');
if (colonIndex > -1) {
config.filepath = line.substring(0, colonIndex); // file path
const props = line.substring(colonIndex + 1); // props on other side of the `:`
config.properties = props.length > 2 ? JSON.parse(props) : {}; // file properties
}
if (config.filepath.startsWith('/')) {
config.filepath = config.filepath.slice(1);
}
return config;
});

const ordering: FileProperties[] = [];
for (const config of orderingMap) {
const pathComponents = config.filepath.split(path.sep);
let str = src;
for (const pathComponent of pathComponents) {
str = path.join(str, pathComponent);
ordering.push({ filepath: str, properties: config.properties });
}
}

let missing = 0;
const total = filenames.length;

const fileOrderingSorted: FileProperties[] = [];
const isAlreadySorted = (file: string) =>
fileOrderingSorted.findIndex((config) => file === config.filepath) > -1;

for (const config of ordering) {
if (!isAlreadySorted(config.filepath) && filenames.includes(config.filepath)) {
fileOrderingSorted.push(config);
}
}

for (const file of filenames) {
if (!isAlreadySorted(file)) {
fileOrderingSorted.push({ filepath: file, properties: {} });
missing += 1;
}
}

console.log(`Ordering file has ${((total - missing) / total) * 100}% coverage.`);
return fileOrderingSorted;
}

export async function createPackage(src: string, dest: string) {
return createPackageWithOptions(src, dest, {});
}
Expand Down Expand Up @@ -151,10 +84,54 @@ export async function createPackageFromFiles(
const links: disk.BasicFilesArray = [];
const unpackDirs: string[] = [];

const filenamesSorted: FileProperties[] = await getFileOrdering(options, src, filenames);
let filenamesSorted: string[] = [];
if (options.ordering) {
const orderingFiles = (await fs.readFile(options.ordering))
.toString()
.split('\n')
.map((line) => {
if (line.includes(':')) {
line = line.split(':').pop()!;
}
line = line.trim();
if (line.startsWith('/')) {
line = line.slice(1);
}
return line;
});

const ordering: string[] = [];
for (const file of orderingFiles) {
const pathComponents = file.split(path.sep);
let str = src;
for (const pathComponent of pathComponents) {
str = path.join(str, pathComponent);
ordering.push(str);
}
}

let missing = 0;
const total = filenames.length;

for (const file of ordering) {
if (!filenamesSorted.includes(file) && filenames.includes(file)) {
filenamesSorted.push(file);
}
}

for (const file of filenames) {
if (!filenamesSorted.includes(file)) {
filenamesSorted.push(file);
missing += 1;
}
}

const handleFile = async function (config: FileProperties) {
const filename = config.filepath;
console.log(`Ordering file has ${((total - missing) / total) * 100}% coverage.`);
} else {
filenamesSorted = filenames;
}

const handleFile = async function (filename: string) {
if (!metadata[filename]) {
const fileType = await determineFileType(filename);
if (!fileType) {
Expand All @@ -169,9 +146,6 @@ export async function createPackageFromFiles(
unpack: string | undefined,
unpackDir: string | undefined,
) {
if (config.properties.unpack != null) {
return config.properties.unpack;
}
let shouldUnpack = false;
if (unpack) {
shouldUnpack = minimatch(filename, unpack, { matchBase: true });
Expand Down Expand Up @@ -216,12 +190,12 @@ export async function createPackageFromFiles(

const names = filenamesSorted.slice();

const next = async function (config?: FileProperties) {
if (!config) {
const next = async function (name?: string) {
if (!name) {
return insertsDone();
}

await handleFile(config);
await handleFile(name);
return next(names.shift());
};

Expand Down
12 changes: 2 additions & 10 deletions test/cli-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,9 @@ describe('command line interface', function () {
);
});
it('should unpack static framework with all underlying symlinks unpacked', async () => {
const { tmpPath, buildOrderingData } = createSymlinkApp('ordered-app');
const orderingPath = path.join(tmpPath, '../ordered-app-ordering.txt');

// this is functionally the same as `-unpack *.txt --unpack-dir var`
const data = buildOrderingData((filepath) => ({
unpack: filepath.endsWith('.txt') || filepath.includes('var'),
}));
await fs.writeFile(orderingPath, data);

const { tmpPath } = createSymlinkApp('app');
await execAsar(
`p ${tmpPath} tmp/packthis-with-symlink.asar --ordering=${orderingPath} --exclude-hidden`,
`p ${tmpPath} tmp/packthis-with-symlink.asar --unpack *.txt --unpack-dir var --exclude-hidden`,
);

assert.ok(fs.existsSync('tmp/packthis-with-symlink.asar.unpacked/private/var/file.txt'));
Expand Down
30 changes: 1 addition & 29 deletions test/util/createSymlinkApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,5 @@ module.exports = (testName) => {
const appPath = path.join(varPath, 'app');
fs.mkdirpSync(appPath);
fs.symlinkSync('../file.txt', path.join(appPath, 'file.txt'));

const ordering = walk(tmpPath).map((filepath) => filepath.substring(tmpPath.length)); // convert to paths relative to root

return {
appPath,
tmpPath,
varPath,
// helper function for generating the `ordering.txt` file data
buildOrderingData: (getProps) =>
ordering.reduce((prev, curr) => {
return `${prev}${curr}:${JSON.stringify(getProps(curr))}\n`;
}, ''),
};
};

// returns a list of all directories, files, and symlinks. Automates testing `ordering` logic easy.
const walk = (root) => {
const getPaths = (filepath, filter) =>
fs
.readdirSync(filepath, { withFileTypes: true })
.filter((dirent) => filter(dirent))
.map(({ name }) => path.join(filepath, name));

const dirs = getPaths(root, (dirent) => dirent.isDirectory());
const files = dirs.map((dir) => walk(dir)).flat();
return files.concat(
dirs,
getPaths(root, (dirent) => dirent.isFile() || dirent.isSymbolicLink()),
);
return { appPath, tmpPath, varPath };
};

0 comments on commit 9b7ccfe

Please sign in to comment.