Added pnpm support. Sloppy and incomplete. Unsure of what to do
with the symlinks without modifying the project. microsoft/vscode-vsce#421
This commit is contained in:
parent
5ade7bfa42
commit
f2c83c1bc3
7 changed files with 1445 additions and 25 deletions
|
@ -25,11 +25,11 @@
|
|||
},
|
||||
"scripts": {
|
||||
"copy-vsce": "mkdir -p out && cp src/vsce out/vsce",
|
||||
"compile": "tsc && yarn copy-vsce",
|
||||
"watch": "yarn copy-vsce && tsc --watch",
|
||||
"watch-test": "yarn copy-vsce && concurrently \"tsc --watch\" \"mocha --watch\"",
|
||||
"compile": "tsc && npm run copy-vsce",
|
||||
"watch": "npm run copy-vsce && tsc --watch",
|
||||
"watch-test": "npm run copy-vsce && concurrently \"tsc --watch\" \"mocha --watch\"",
|
||||
"test": "mocha",
|
||||
"prepublishOnly": "tsc && yarn copy-vsce && mocha",
|
||||
"prepublishOnly": "tsc && npm run copy-vsce && mocha",
|
||||
"vsce": "out/vsce"
|
||||
},
|
||||
"engines": {
|
||||
|
|
1301
pnpm-lock.yaml
generated
Normal file
1301
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load diff
20
src/api.ts
20
src/api.ts
|
@ -30,6 +30,11 @@ export interface ICreateVSIXOptions {
|
|||
* Should use Yarn instead of NPM.
|
||||
*/
|
||||
useYarn?: boolean;
|
||||
|
||||
/**
|
||||
* Select the package manager to use
|
||||
*/
|
||||
usePackageManager?: "yarn" | "pnpm" | "npm";
|
||||
}
|
||||
|
||||
export interface IPublishOptions {
|
||||
|
@ -62,6 +67,11 @@ export interface IPublishOptions {
|
|||
* Should use Yarn instead of NPM.
|
||||
*/
|
||||
useYarn?: boolean;
|
||||
|
||||
/**
|
||||
* Select the package manager to use
|
||||
*/
|
||||
usePackageManager?: "yarn" | "pnpm" | "npm";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,7 +79,8 @@ export interface IPublishOptions {
|
|||
*/
|
||||
export enum PackageManager {
|
||||
Npm,
|
||||
Yarn
|
||||
Yarn,
|
||||
Pnpm,
|
||||
}
|
||||
|
||||
export interface IListFilesOptions {
|
||||
|
@ -122,6 +133,11 @@ export interface IPublishVSIXOptions {
|
|||
* Should use Yarn instead of NPM.
|
||||
*/
|
||||
useYarn?: boolean;
|
||||
|
||||
/**
|
||||
* Select the package manager to use
|
||||
*/
|
||||
usePackageManager?: "yarn" | "pnpm" | "npm";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,7 +158,7 @@ export function publish(options: IPublishOptions = {}): Promise<any> {
|
|||
* Lists the files included in the extension's package.
|
||||
*/
|
||||
export function listFiles(options: IListFilesOptions = {}): Promise<string[]> {
|
||||
return _listFiles(options.cwd, options.packageManager === PackageManager.Yarn, options.packagedDependencies, options.ignoreFile);
|
||||
return _listFiles(options.cwd, options.packageManager === PackageManager.Yarn, <any>({ [PackageManager.Yarn]: "yarn", [PackageManager.Npm]: "npm", [PackageManager.Pnpm]: "pnpm" }[options.packageManager]), options.packagedDependencies, options.ignoreFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,9 +62,10 @@ module.exports = function (argv: string[]): void {
|
|||
.command('ls')
|
||||
.description('Lists all the files that will be published')
|
||||
.option('--yarn', 'Use yarn instead of npm')
|
||||
.option('--packageManager [yarn|npm|pnpm]', 'Use yarn, npm, or pnpm package manager')
|
||||
.option('--packagedDependencies <path>', 'Select packages that should be published only (includes dependencies)', (val, all) => all ? all.concat(val) : [val], undefined)
|
||||
.option('--ignoreFile [path]', 'Indicate alternative .vscodeignore')
|
||||
.action(({ yarn, packagedDependencies, ignoreFile }) => main(ls(undefined, yarn, packagedDependencies, ignoreFile)));
|
||||
.action(({ yarn, packagedDependencies, ignoreFile, packageManager }) => main(ls(undefined, yarn, packagedDependencies, ignoreFile, packageManager)));
|
||||
|
||||
program
|
||||
.command('package')
|
||||
|
@ -74,9 +75,10 @@ module.exports = function (argv: string[]): void {
|
|||
.option('--baseContentUrl [url]', 'Prepend all relative links in README.md with this url.')
|
||||
.option('--baseImagesUrl [url]', 'Prepend all relative image links in README.md with this url.')
|
||||
.option('--yarn', 'Use yarn instead of npm')
|
||||
.option('--packageManager [yarn|npm|pnpm]', 'Use yarn, npm, or pnpm package manager')
|
||||
.option('--ignoreFile [path]', 'Indicate alternative .vscodeignore')
|
||||
.option('--noGitHubIssueLinking', 'Prevent automatic expansion of GitHub-style issue syntax into links')
|
||||
.action(({ out, githubBranch, baseContentUrl, baseImagesUrl, yarn, ignoreFile, noGitHubIssueLinking }) => main(packageCommand({ packagePath: out, githubBranch, baseContentUrl, baseImagesUrl, useYarn: yarn, ignoreFile, expandGitHubIssueLinks: noGitHubIssueLinking })));
|
||||
.action(({ out, githubBranch, baseContentUrl, baseImagesUrl, yarn, ignoreFile, noGitHubIssueLinking, packageManager }) => main(packageCommand({ packagePath: out, githubBranch, baseContentUrl, baseImagesUrl, useYarn: yarn, ignoreFile, expandGitHubIssueLinks: noGitHubIssueLinking, usePackageManager: packageManager })));
|
||||
|
||||
program
|
||||
.command('publish [<version>]')
|
||||
|
@ -88,10 +90,11 @@ module.exports = function (argv: string[]): void {
|
|||
.option('--baseContentUrl [url]', 'Prepend all relative links in README.md with this url.')
|
||||
.option('--baseImagesUrl [url]', 'Prepend all relative image links in README.md with this url.')
|
||||
.option('--yarn', 'Use yarn instead of npm while packing extension files')
|
||||
.option('--packageManager [yarn|npm|pnpm]', 'Use yarn, npm, or pnpm package manager')
|
||||
.option('--noVerify')
|
||||
.option('--ignoreFile [path]', 'Indicate alternative .vscodeignore')
|
||||
.option('--web', 'Experimental flag to enable publishing web extensions. Note: This is supported only for selected extensions.')
|
||||
.action((version, { pat, message, packagePath, githubBranch, baseContentUrl, baseImagesUrl, yarn, noVerify, ignoreFile, web }) => main(publish({ pat, commitMessage: message, version, packagePath, githubBranch, baseContentUrl, baseImagesUrl, useYarn: yarn, noVerify, ignoreFile, web })));
|
||||
.action((version, { pat, message, packagePath, githubBranch, baseContentUrl, baseImagesUrl, yarn, noVerify, ignoreFile, web, packageManager }) => main(publish({ pat, commitMessage: message, version, packagePath, githubBranch, baseContentUrl, baseImagesUrl, useYarn: yarn, noVerify, ignoreFile, web, usePackageManager: packageManager })));
|
||||
|
||||
program
|
||||
.command('unpublish [<extensionid>]')
|
||||
|
|
88
src/npm.ts
88
src/npm.ts
|
@ -1,6 +1,7 @@
|
|||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as cp from 'child_process';
|
||||
import * as denodeify from 'denodeify';
|
||||
import * as parseSemver from 'parse-semver';
|
||||
import * as _ from 'lodash';
|
||||
import { CancellationToken } from './util';
|
||||
|
@ -71,6 +72,13 @@ export interface YarnDependency {
|
|||
children: YarnDependency[];
|
||||
}
|
||||
|
||||
interface PnpmTreeNode {
|
||||
name: string;
|
||||
from: string;
|
||||
version: string;
|
||||
dependencies: { [key:string]:PnpmTreeNode };
|
||||
}
|
||||
|
||||
function asYarnDependency(prefix: string, tree: YarnTreeNode, prune: boolean): YarnDependency | null {
|
||||
if (prune && /@[\^~]/.test(tree.name)) {
|
||||
return null;
|
||||
|
@ -99,6 +107,32 @@ function asYarnDependency(prefix: string, tree: YarnTreeNode, prune: boolean): Y
|
|||
return { name, path: dependencyPath, children };
|
||||
}
|
||||
|
||||
async function asPnpmDependency(prefix: string, tree: PnpmTreeNode, prune: boolean): Promise<YarnDependency | null> {
|
||||
if (prune && /^[\^~]/.test(tree.version)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let name = tree.name || tree.from;
|
||||
let s = path.sep;
|
||||
|
||||
const dependencyPath = await denodeify(fs.realpath)(`${prefix}${s}${name}`);
|
||||
const children: YarnDependency[] = [];
|
||||
|
||||
console.log(dependencyPath);
|
||||
|
||||
const deps = await Promise.all(
|
||||
_.values(tree.dependencies || {})
|
||||
.map(child => asPnpmDependency(`${dependencyPath}${s}..`, child, prune))
|
||||
);
|
||||
for(const dep of deps) {
|
||||
if (dep) {
|
||||
children.push(dep);
|
||||
}
|
||||
}
|
||||
|
||||
return { name, path: dependencyPath, children };
|
||||
}
|
||||
|
||||
function selectYarnDependencies(deps: YarnDependency[], packagedDependencies: string[]): YarnDependency[] {
|
||||
|
||||
const index = new class {
|
||||
|
@ -145,6 +179,30 @@ function selectYarnDependencies(deps: YarnDependency[], packagedDependencies: st
|
|||
return reached.values;
|
||||
}
|
||||
|
||||
async function getPnpmProductionDependencies(cwd: string, packagedDependencies?: string[]): Promise<YarnDependency[]> {
|
||||
const raw = await new Promise<string>((c, e) => cp.exec('pnpm list --depth 1000000 --prod --json --silent', { cwd, encoding: 'utf8', env: { ...process.env }, maxBuffer: 5000 * 1024 }, (err, stdout) => err ? e(err) : c(stdout)));
|
||||
const match = /^\s*\[[\s\S]*\]\s*$/m.exec(raw);
|
||||
|
||||
if (!match || match.length !== 1) {
|
||||
throw new Error('Could not parse result of `pnpm list --json`' + raw);
|
||||
}
|
||||
|
||||
const usingPackagedDependencies = Array.isArray(packagedDependencies);
|
||||
const trees = _.values(JSON.parse(match[0])[0].dependencies) as PnpmTreeNode[];
|
||||
|
||||
let result = (
|
||||
await Promise.all(
|
||||
trees.map(tree => asPnpmDependency(path.join(cwd, 'node_modules'), tree, !usingPackagedDependencies))
|
||||
)
|
||||
).filter(dep => !!dep);
|
||||
|
||||
if (usingPackagedDependencies) {
|
||||
result = selectYarnDependencies(result, packagedDependencies);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async function getYarnProductionDependencies(cwd: string, packagedDependencies?: string[]): Promise<YarnDependency[]> {
|
||||
const raw = await new Promise<string>((c, e) => cp.exec('yarn list --prod --json', { cwd, encoding: 'utf8', env: { ...process.env }, maxBuffer: 5000 * 1024 }, (err, stdout) => err ? e(err) : c(stdout)));
|
||||
const match = /^{"type":"tree".*$/m.exec(raw);
|
||||
|
@ -179,8 +237,34 @@ async function getYarnDependencies(cwd: string, packagedDependencies?: string[])
|
|||
return _.uniq(result);
|
||||
}
|
||||
|
||||
export function getDependencies(cwd: string, useYarn = false, packagedDependencies?: string[]): Promise<string[]> {
|
||||
return useYarn ? getYarnDependencies(cwd, packagedDependencies) : getNpmDependencies(cwd);
|
||||
async function getPnpmDependencies(cwd: string, packagedDependencies?: string[]): Promise<string[]> {
|
||||
const result: string[] = [cwd];
|
||||
|
||||
if (await new Promise(c => fs.exists(path.join(cwd, 'pnpm-lock.yaml'), c))) {
|
||||
const deps = await getPnpmProductionDependencies(cwd, packagedDependencies);
|
||||
const flatten = (dep: YarnDependency) => { result.push(dep.path); dep.children.forEach(flatten); };
|
||||
deps.forEach(flatten);
|
||||
}
|
||||
|
||||
return _.uniq(result);
|
||||
}
|
||||
|
||||
export function getDependencies(cwd: string, useYarn = false, usePackageManager: "yarn" | "npm" | "pnpm", packagedDependencies?: string[]): Promise<string[]> {
|
||||
if(useYarn) {
|
||||
return getYarnDependencies(cwd, packagedDependencies);
|
||||
}
|
||||
else if(usePackageManager == "npm") {
|
||||
return getNpmDependencies(cwd);
|
||||
}
|
||||
else if(usePackageManager == "pnpm") {
|
||||
return getPnpmDependencies(cwd, packagedDependencies);
|
||||
}
|
||||
else if(usePackageManager == "yarn") {
|
||||
return getYarnDependencies(cwd, packagedDependencies);
|
||||
}
|
||||
else {
|
||||
return getNpmDependencies(cwd);
|
||||
}
|
||||
}
|
||||
|
||||
export function getLatestVersion(name: string, cancellationToken?: CancellationToken): Promise<string> {
|
||||
|
|
|
@ -64,6 +64,7 @@ export interface IPackageOptions {
|
|||
baseContentUrl?: string;
|
||||
baseImagesUrl?: string;
|
||||
useYarn?: boolean;
|
||||
usePackageManager?: "yarn" | "npm" | "pnpm";
|
||||
dependencyEntryPoints?: string[];
|
||||
ignoreFile?: string;
|
||||
expandGitHubIssueLinks?: boolean;
|
||||
|
@ -919,8 +920,8 @@ const defaultIgnore = [
|
|||
'**/.vscode-test/**'
|
||||
];
|
||||
|
||||
function collectAllFiles(cwd: string, useYarn = false, dependencyEntryPoints?: string[]): Promise<string[]> {
|
||||
return getDependencies(cwd, useYarn, dependencyEntryPoints).then(deps => {
|
||||
function collectAllFiles(cwd: string, useYarn = false, usePackageManager: "yarn" | "npm" | "pnpm" = "npm", dependencyEntryPoints?: string[]): Promise<string[]> {
|
||||
return getDependencies(cwd, useYarn, usePackageManager, dependencyEntryPoints).then(deps => {
|
||||
const promises: Promise<string[]>[] = deps.map(dep => {
|
||||
return glob('**', { cwd: dep, nodir: true, dot: true, ignore: 'node_modules/**' })
|
||||
.then(files => files
|
||||
|
@ -932,8 +933,8 @@ function collectAllFiles(cwd: string, useYarn = false, dependencyEntryPoints?: s
|
|||
});
|
||||
}
|
||||
|
||||
function collectFiles(cwd: string, useYarn = false, dependencyEntryPoints?: string[], ignoreFile?: string): Promise<string[]> {
|
||||
return collectAllFiles(cwd, useYarn, dependencyEntryPoints).then(files => {
|
||||
function collectFiles(cwd: string, useYarn = false, usePackageManager: "yarn" | "npm" | "pnpm" = "npm", dependencyEntryPoints?: string[], ignoreFile?: string): Promise<string[]> {
|
||||
return collectAllFiles(cwd, useYarn, usePackageManager, dependencyEntryPoints).then(files => {
|
||||
files = files.filter(f => !/\r$/m.test(f));
|
||||
|
||||
return readFile(ignoreFile ? ignoreFile : path.join(cwd, '.vscodeignore'), 'utf8')
|
||||
|
@ -997,11 +998,12 @@ export function createDefaultProcessors(manifest: Manifest, options: IPackageOpt
|
|||
export function collect(manifest: Manifest, options: IPackageOptions = {}): Promise<IFile[]> {
|
||||
const cwd = options.cwd || process.cwd();
|
||||
const useYarn = options.useYarn || false;
|
||||
const usePackageManager = options.usePackageManager || "npm";
|
||||
const packagedDependencies = options.dependencyEntryPoints || undefined;
|
||||
const ignoreFile = options.ignoreFile || undefined;
|
||||
const processors = createDefaultProcessors(manifest, options);
|
||||
|
||||
return collectFiles(cwd, useYarn, packagedDependencies, ignoreFile).then(fileNames => {
|
||||
return collectFiles(cwd, useYarn, usePackageManager, packagedDependencies, ignoreFile).then(fileNames => {
|
||||
const files = fileNames.map(f => ({ path: `extension/${f}`, localPath: path.join(cwd, f) }));
|
||||
|
||||
return processFiles(processors, files);
|
||||
|
@ -1029,15 +1031,28 @@ function getDefaultPackageName(manifest: Manifest): string {
|
|||
return `${manifest.name}-${manifest.version}.vsix`;
|
||||
}
|
||||
|
||||
async function prepublish(cwd: string, manifest: Manifest, useYarn: boolean = false): Promise<void> {
|
||||
async function prepublish(cwd: string, manifest: Manifest, useYarn: boolean = false, usePackageManager: "yarn" | "npm" | "pnpm" = "npm"): Promise<void> {
|
||||
if (!manifest.scripts || !manifest.scripts['vscode:prepublish']) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Executing prepublish script '${useYarn ? 'yarn' : 'npm'} run vscode:prepublish'...`);
|
||||
let tool = 'npm';
|
||||
if(useYarn) {
|
||||
tool = 'yarn'
|
||||
}
|
||||
else if(usePackageManager == "npm") {
|
||||
tool = 'npm';
|
||||
}
|
||||
else if(usePackageManager == "pnpm") {
|
||||
tool = 'pnpm';
|
||||
}
|
||||
else if(usePackageManager == "yarn") {
|
||||
tool = 'yarn'
|
||||
}
|
||||
|
||||
console.log(`Executing prepublish script '${tool} run vscode:prepublish'...`);
|
||||
|
||||
await new Promise((c, e) => {
|
||||
const tool = useYarn ? 'yarn' : 'npm';
|
||||
const child = cp.spawn(tool, ['run', 'vscode:prepublish'], { cwd, shell: true, stdio: 'inherit' });
|
||||
child.on('exit', code => code === 0 ? c() : e(`${tool} failed with exit code ${code}`));
|
||||
child.on('error', e);
|
||||
|
@ -1067,7 +1082,7 @@ export async function pack(options: IPackageOptions = {}): Promise<IPackageResul
|
|||
|
||||
const manifest = await readManifest(cwd);
|
||||
|
||||
await prepublish(cwd, manifest, options.useYarn);
|
||||
await prepublish(cwd, manifest, options.useYarn, options.usePackageManager);
|
||||
|
||||
const files = await collect(manifest, options);
|
||||
const jsFiles = files.filter(f => /\.js$/i.test(f.path));
|
||||
|
@ -1103,17 +1118,17 @@ export async function packageCommand(options: IPackageOptions = {}): Promise<any
|
|||
/**
|
||||
* Lists the files included in the extension's package. Does not run prepublish.
|
||||
*/
|
||||
export function listFiles(cwd = process.cwd(), useYarn = false, packagedDependencies?: string[], ignoreFile?: string): Promise<string[]> {
|
||||
export function listFiles(cwd = process.cwd(), useYarn = false, usePackageManager: "yarn" | "npm" | "pnpm" = "npm", packagedDependencies?: string[], ignoreFile?: string): Promise<string[]> {
|
||||
return readManifest(cwd)
|
||||
.then(() => collectFiles(cwd, useYarn, packagedDependencies, ignoreFile));
|
||||
.then(() => collectFiles(cwd, useYarn, usePackageManager, packagedDependencies, ignoreFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists the files included in the extension's package. Runs prepublish.
|
||||
*/
|
||||
export function ls(cwd = process.cwd(), useYarn = false, packagedDependencies?: string[], ignoreFile?: string): Promise<void> {
|
||||
export function ls(cwd = process.cwd(), useYarn = false, usePackageManager?: "yarn" | "npm" | "pnpm", packagedDependencies?: string[], ignoreFile?: string): Promise<void> {
|
||||
return readManifest(cwd)
|
||||
.then(manifest => prepublish(cwd, manifest, useYarn))
|
||||
.then(() => collectFiles(cwd, useYarn, packagedDependencies, ignoreFile))
|
||||
.then(manifest => prepublish(cwd, manifest, useYarn, usePackageManager))
|
||||
.then(() => collectFiles(cwd, useYarn, usePackageManager, packagedDependencies, ignoreFile))
|
||||
.then(files => files.forEach(f => console.log(`${f}`)));
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ export interface IPublishOptions {
|
|||
baseContentUrl?: string;
|
||||
baseImagesUrl?: string;
|
||||
useYarn?: boolean;
|
||||
usePackageManager?: "yarn" | "npm" | "pnpm";
|
||||
noVerify?: boolean;
|
||||
ignoreFile?: string;
|
||||
web?: boolean;
|
||||
|
|
Loading…
Add table
Reference in a new issue