From 3cd6ca0faaafd87b31d56f793b626b709ad36b26 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 18 Sep 2024 11:27:04 +0200 Subject: [PATCH 1/3] Fix regression with workdir symlinks If a workdir was refering a symlink directory, we would pass it to yazl, which would error out because it's a directory. glob recommends using `follow: true` to consider directory symlinks as directories in the collection. --- src/package.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.ts b/src/package.ts index 682deff3..c3cb6489 100644 --- a/src/package.ts +++ b/src/package.ts @@ -1617,7 +1617,7 @@ async function collectAllFiles( ): Promise { const deps = await getDependencies(cwd, dependencies, dependencyEntryPoints); const promises = deps.map(dep => - glob('**', { cwd: dep, nodir: true, dot: true, ignore: 'node_modules/**' }).then(files => + glob('**', { cwd: dep, nodir: true, follow: true, dot: true, ignore: 'node_modules/**' }).then(files => files.map(f => path.relative(cwd, path.join(dep, f))).map(f => f.replace(/\\/g, '/')) ) ); From 51e122af452144b12c5231a2615a81404fda32a1 Mon Sep 17 00:00:00 2001 From: Enguerrand de Ribaucourt Date: Wed, 9 Oct 2024 17:18:24 +0200 Subject: [PATCH 2/3] Make follow-symlinks optional This new behavior fixes packaging with symlinks to directories in extensions. We make it optional in case someone wants to keep the intermediate behavior. --- src/main.ts | 13 ++++++++++--- src/package.ts | 25 +++++++++++++++++-------- src/publish.ts | 7 ++++++- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/main.ts b/src/main.ts index a08c467d..4c35dcec 100644 --- a/src/main.ts +++ b/src/main.ts @@ -75,8 +75,9 @@ module.exports = function (argv: string[]): void { .option('--dependencies', 'Enable dependency detection via npm or yarn', undefined) .option('--no-dependencies', 'Disable dependency detection via npm or yarn', undefined) .option('--readme-path ', 'Path to README file (defaults to README.md)') - .action(({ tree, yarn, packagedDependencies, ignoreFile, dependencies, readmePath }) => - main(ls({ tree, useYarn: yarn, packagedDependencies, ignoreFile, dependencies, readmePath })) + .option('--follow-symlinks', 'Recurse into symlinked directories instead of treating them as files') + .action(({ tree, yarn, packagedDependencies, ignoreFile, dependencies, readmePath, followSymlinks }) => + main(ls({ tree, useYarn: yarn, packagedDependencies, ignoreFile, dependencies, readmePath, followSymlinks })) ); program @@ -119,6 +120,7 @@ module.exports = function (argv: string[]): void { .option('--allow-unused-files-pattern', 'Allow include patterns for the files field in package.json that does not match any file') .option('--skip-license', 'Allow packaging without license file') .option('--sign-tool ', 'Path to the VSIX signing tool. Will be invoked with two arguments: `SIGNTOOL `.') + .option('--follow-symlinks', 'Recurse into symlinked directories instead of treating them as files') .action( ( version, @@ -147,6 +149,7 @@ module.exports = function (argv: string[]): void { allowUnusedFilesPattern, skipLicense, signTool, + followSymlinks, } ) => main( @@ -176,6 +179,7 @@ module.exports = function (argv: string[]): void { allowUnusedFilesPattern, skipLicense, signTool, + followSymlinks, }) ) ); @@ -229,6 +233,7 @@ module.exports = function (argv: string[]): void { .option('--allow-unused-files-pattern', 'Allow include patterns for the files field in package.json that does not match any file') .option('--skip-duplicate', 'Fail silently if version already exists on the marketplace') .option('--skip-license', 'Allow publishing without license file') + .option('--follow-symlinks', 'Recurse into symlinked directories instead of treating them as files') .action( ( version, @@ -263,6 +268,7 @@ module.exports = function (argv: string[]): void { skipDuplicate, skipLicense, signTool, + followSymlinks, } ) => main( @@ -297,7 +303,8 @@ module.exports = function (argv: string[]): void { allowUnusedFilesPattern, skipDuplicate, skipLicense, - signTool + signTool, + followSymlinks }) ) ); diff --git a/src/package.ts b/src/package.ts index c3cb6489..f8aa23fd 100644 --- a/src/package.ts +++ b/src/package.ts @@ -95,11 +95,16 @@ export interface IPackageOptions { * `target` is set. For example, if `target` is `linux-x64` and there are * folders named `win32-x64`, `darwin-arm64` or `web`, the files inside * those folders will be ignored. - * + * * @default false */ readonly ignoreOtherTargetFolders?: boolean; + /** + * Recurse into symlinked directories instead of treating them as files. + */ + readonly followSymlinks?: boolean; + readonly commitMessage?: string; readonly gitTagVersion?: boolean; readonly updatePackageJson?: boolean; @@ -1613,11 +1618,12 @@ const defaultIgnore = [ async function collectAllFiles( cwd: string, dependencies: 'npm' | 'yarn' | 'none' | undefined, - dependencyEntryPoints?: string[] + dependencyEntryPoints?: string[], + followSymlinks:boolean = true ): Promise { const deps = await getDependencies(cwd, dependencies, dependencyEntryPoints); const promises = deps.map(dep => - glob('**', { cwd: dep, nodir: true, follow: true, dot: true, ignore: 'node_modules/**' }).then(files => + glob('**', { cwd: dep, nodir: true, follow: followSymlinks, dot: true, ignore: 'node_modules/**' }).then(files => files.map(f => path.relative(cwd, path.join(dep, f))).map(f => f.replace(/\\/g, '/')) ) ); @@ -1647,11 +1653,12 @@ function collectFiles( ignoreFile?: string, manifestFileIncludes?: string[], readmePath?: string, + followSymlinks:boolean = false ): Promise { readmePath = readmePath ?? 'README.md'; const notIgnored = ['!package.json', `!${readmePath}`]; - return collectAllFiles(cwd, dependencies, dependencyEntryPoints).then(files => { + return collectAllFiles(cwd, dependencies, dependencyEntryPoints, followSymlinks).then(files => { files = files.filter(f => !/\r$/m.test(f)); return ( @@ -1666,7 +1673,7 @@ function collectFiles( manifestFileIncludes ? // include all files in manifestFileIncludes and ignore the rest Promise.resolve(manifestFileIncludes.map(file => `!${file}`).concat(['**']).join('\n\r')) : - // "files" property not used in package.json + // "files" property not used in package.json Promise.resolve('') ) @@ -1758,7 +1765,7 @@ export function collect(manifest: ManifestPackage, options: IPackageOptions = {} const ignoreFile = options.ignoreFile || undefined; const processors = createDefaultProcessors(manifest, options); - return collectFiles(cwd, getDependenciesOption(options), packagedDependencies, ignoreFile, manifest.files, options.readmePath).then(fileNames => { + return collectFiles(cwd, getDependenciesOption(options), packagedDependencies, ignoreFile, manifest.files, options.readmePath, options.followSymlinks).then(fileNames => { const files = fileNames.map(f => ({ path: util.filePathToVsixPath(f), localPath: path.join(cwd, f) })); return processFiles(processors, files); @@ -1931,6 +1938,7 @@ export interface IListFilesOptions { readonly dependencies?: boolean; readonly prepublish?: boolean; readonly readmePath?: string; + readonly followSymlinks?: boolean; } /** @@ -1944,7 +1952,7 @@ export async function listFiles(options: IListFilesOptions = {}): Promise 0 && !options.allowUnusedFilesPattern) { const localPaths = (files.filter(f => !isInMemoryFile(f)) as ILocalFile[]).map(f => util.normalize(f.localPath)); diff --git a/src/publish.ts b/src/publish.ts index 853371ef..8d96a6d9 100644 --- a/src/publish.ts +++ b/src/publish.ts @@ -58,6 +58,11 @@ export interface IPublishOptions { readonly dependencyEntryPoints?: string[]; readonly ignoreFile?: string; + /** + * Recurse into symlinked directories instead of treating them as files + */ + readonly followSymlinks?: boolean; + /** * The Personal Access Token to use. * @@ -352,4 +357,4 @@ export async function getPAT(publisher: string, options: IPublishOptions | IUnpu } return (await getPublisher(publisher)).pat; -} \ No newline at end of file +} From 4335f9c271c175da78be44254dcef1d0b64fee38 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Thu, 10 Oct 2024 09:22:02 +0200 Subject: [PATCH 3/3] closes #1064 --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index a08c467d..aa44fe91 100644 --- a/src/main.ts +++ b/src/main.ts @@ -46,7 +46,7 @@ function main(task: Promise): void { task.catch(fatal).then(() => { if (latestVersion && semver.gt(latestVersion, pkg.version)) { - log.info(`The latest version of ${pkg.name} is ${latestVersion} and you have ${pkg.version}.\nUpdate it now: npm install -g ${pkg.name}`); + log.warn(`The latest version of ${pkg.name} is ${latestVersion} and you have ${pkg.version}.\nUpdate it now: npm install -g ${pkg.name}`); } else { token.cancel(); }