Skip to content

Commit

Permalink
fix(get): ffmpeg and symlinks
Browse files Browse the repository at this point in the history
* fix(get): create symlinks after extracting files from zip
* fix(get): do not use options.downloadUrl to set ffmpeg download url
* chore: fix lint command
  • Loading branch information
zkrige authored and ayushmanchhabra committed Feb 22, 2024
1 parent 2284d52 commit d5c1bf5
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 18 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
},
"scripts": {
"lint": "eslint ./src/**/*.js ./test/**/*.js",
"lint:fix": "eslint --fix ./**/*.{js,md} && markdownlint --fix ./README.md",
"lint:fix": "eslint --fix ./src/**/*.js ./test/**/*.js",
"markdown:fix": "markdownlint --fix ./README.md",
"docs": "jsdoc -d docs ./README.md ./src/index.js ./src/get.js ./src/run.js ./src/bld.js",
"test": "vitest run",
"demo": "cd test/fixture && node demo.js"
Expand Down
49 changes: 34 additions & 15 deletions src/get/decompress.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,50 @@ function modeFromEntry(entry) {
*/
async function unzip(zippedFile, cacheDir) {
const zip = await yauzl.open(zippedFile);

let entry = await zip.readEntry();
const symlinks = []; // Array to hold symbolic link entries

while (entry !== null) {
let entryPathAbs = path.join(cacheDir, entry.filename);
/* Create the directory beforehand to prevent `ENOENT: no such file or directory` errors. */
await fs.promises.mkdir(path.dirname(entryPathAbs), { recursive: true });
/* Check if entry is a symbolic link */
// Check if entry is a symbolic link
const isSymlink = ((modeFromEntry(entry) & 0o170000) === 0o120000);
const readStream = await entry.openReadStream();


if (isSymlink) {
const chunks = [];
/* Read stream into Array. */
readStream.on("data", (chunk) => chunks.push(chunk));
await stream.promises.finished(readStream);
const link = Buffer.concat(chunks).toString('utf8').trim();
await fs.promises.symlink(link, entryPathAbs)
// Store symlink entries to process later
symlinks.push(entry);
} else {
// Pipe read to write stream
const writeStream = fs.createWriteStream(entryPathAbs);
await stream.promises.pipeline(readStream, writeStream);
// Handle regular files and directories
await fs.promises.mkdir(path.dirname(entryPathAbs), {recursive: true});
if (!entry.filename.endsWith('/')) { // Skip directories
const readStream = await entry.openReadStream();
const writeStream = fs.createWriteStream(entryPathAbs);
await stream.promises.pipeline(readStream, writeStream);

// Set file permissions after the file has been written
const mode = modeFromEntry(entry);
await fs.promises.chmod(entryPathAbs, mode);
}
}

// Read next entry
entry = await zip.readEntry();
}

// Process symbolic links after all other files have been extracted
for (const symlinkEntry of symlinks) {
let entryPathAbs = path.join(cacheDir, symlinkEntry.filename);
const readStream = await symlinkEntry.openReadStream();
const chunks = [];
readStream.on("data", (chunk) => chunks.push(chunk));
await new Promise(resolve => readStream.on("end", resolve));
const linkTarget = Buffer.concat(chunks).toString('utf8').trim();

// Check if the symlink or a file/directory already exists at the destination
if (fs.existsSync(entryPathAbs)) {
//skip
} else {
// Create symbolic link
await fs.promises.symlink(linkTarget, entryPathAbs);
}
}
}
7 changes: 5 additions & 2 deletions src/get/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ async function get(options) {
*/
let ffmpegFilePath = path.resolve(
options.cacheDir,
`nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}.zip`,
`ffmpeg-${options.version}-${options.platform}-${options.arch}.zip`,
);

// If `options.cache` is false, then remove the compressed binary.
Expand All @@ -115,7 +115,10 @@ async function get(options) {
*/
const ffmpegFilePathExists = await util.fileExists(ffmpegFilePath);
if (ffmpegFilePathExists === false) {
ffmpegFilePath = await ffmpeg(options.downloadUrl, options.version, options.platform, options.arch, options.cacheDir);
// Do not update the options.downloadUrl with the ffmpeg URL here. Doing so would lead to error when options.ffmpeg and options.nativeAddon are both enabled.
const downloadUrl =
"https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download";
ffmpegFilePath = await ffmpeg(downloadUrl, options.version, options.platform, options.arch, options.cacheDir);
}

await decompress(ffmpegFilePath, options.cacheDir);
Expand Down

0 comments on commit d5c1bf5

Please sign in to comment.