From f59db0f50cd2a8ff1e031aeec5d70a939d356ab8 Mon Sep 17 00:00:00 2001 From: Sebastiaan Brouwer Date: Mon, 22 Jun 2020 14:03:03 +0200 Subject: [PATCH 1/8] feat: support for yarn workspaces --- package.json | 1 + src/npm.ts | 109 +++++----- src/package.ts | 36 ++-- .../node_modules/.yarn-integrity | 25 +++ .../node_modules/curry/README.md | 130 ++++++++++++ .../node_modules/curry/curry.js | 97 +++++++++ .../node_modules/curry/curry.min.js | 1 + .../node_modules/curry/examples/usage.js | 38 ++++ .../node_modules/curry/package.json | 43 ++++ .../node_modules/curry/test/curry-test.js | 133 +++++++++++++ .../node_modules/in-array/LICENSE | 21 ++ .../node_modules/in-array/README.md | 76 +++++++ .../node_modules/in-array/index.js | 21 ++ .../node_modules/in-array/package.json | 61 ++++++ .../node_modules/is-number/LICENSE | 21 ++ .../node_modules/is-number/README.md | 187 ++++++++++++++++++ .../node_modules/is-number/index.js | 18 ++ .../node_modules/is-number/package.json | 82 ++++++++ .../yarnWorkspaces/node_modules/package-a | 1 + .../yarnWorkspaces/node_modules/package-b | 1 + src/test/fixtures/yarnWorkspaces/package.json | 15 ++ .../fixtures/yarnWorkspaces/packageA/main.js | 1 + .../yarnWorkspaces/packageA/package.json | 12 ++ .../fixtures/yarnWorkspaces/packageB/main.js | 1 + .../yarnWorkspaces/packageB/package.json | 12 ++ src/test/fixtures/yarnWorkspaces/yarn.lock | 18 ++ src/test/package.test.ts | 33 ++++ yarn.lock | 19 +- 28 files changed, 1142 insertions(+), 71 deletions(-) create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/curry/README.md create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/curry/curry.js create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/curry/curry.min.js create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/curry/examples/usage.js create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/curry/package.json create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/curry/test/curry-test.js create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/in-array/LICENSE create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/in-array/README.md create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/in-array/index.js create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/in-array/package.json create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/is-number/LICENSE create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/is-number/README.md create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/is-number/index.js create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/is-number/package.json create mode 120000 src/test/fixtures/yarnWorkspaces/node_modules/package-a create mode 120000 src/test/fixtures/yarnWorkspaces/node_modules/package-b create mode 100644 src/test/fixtures/yarnWorkspaces/package.json create mode 100644 src/test/fixtures/yarnWorkspaces/packageA/main.js create mode 100644 src/test/fixtures/yarnWorkspaces/packageA/package.json create mode 100644 src/test/fixtures/yarnWorkspaces/packageB/main.js create mode 100644 src/test/fixtures/yarnWorkspaces/packageB/package.json create mode 100644 src/test/fixtures/yarnWorkspaces/yarn.lock diff --git a/package.json b/package.json index c0ef4bfa..4958ca53 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "cheerio": "^1.0.0-rc.1", "commander": "^2.8.1", "denodeify": "^1.2.1", + "find-yarn-workspace-root": "^2.0.0", "glob": "^7.0.6", "leven": "^3.1.0", "lodash": "^4.17.15", diff --git a/src/npm.ts b/src/npm.ts index 71649a43..a6d363ea 100644 --- a/src/npm.ts +++ b/src/npm.ts @@ -1,9 +1,11 @@ import * as path from 'path'; import * as fs from 'fs'; import * as cp from 'child_process'; -import * as parseSemver from 'parse-semver'; import * as _ from 'lodash'; +import * as findWorkspaceRoot from 'find-yarn-workspace-root'; import { CancellationToken } from './util'; +import { Manifest } from './manifest'; +import { readNodeManifest } from './package'; interface IOptions { cwd?: string; @@ -52,51 +54,58 @@ function checkNPM(cancellationToken?: CancellationToken): Promise { }); } -function getNpmDependencies(cwd: string): Promise { +function getNpmDependencies(cwd: string): Promise { return checkNPM() .then(() => exec('npm list --production --parseable --depth=99999 --loglevel=error', { cwd, maxBuffer: 5000 * 1024 })) .then(({ stdout }) => stdout .split(/[\r\n]/) - .filter(dir => path.isAbsolute(dir))); -} - -interface YarnTreeNode { - name: string; - children: YarnTreeNode[]; + .filter(dir => path.isAbsolute(dir)) + .map(dir => { + return { + src: dir, + dest: path.relative(cwd, dir) + } + })); } export interface YarnDependency { name: string; - path: string; + path: DependencyPath; children: YarnDependency[]; } -function asYarnDependency(prefix: string, tree: YarnTreeNode, prune: boolean): YarnDependency | null { - if (prune && /@[\^~]/.test(tree.name)) { - return null; - } - - let name: string; - - try { - const parseResult = parseSemver(tree.name); - name = parseResult.name; - } catch (err) { - name = tree.name.replace(/^([^@+])@.*$/, '$1'); - } - - const dependencyPath = path.join(prefix, name); - const children: YarnDependency[] = []; - - for (const child of (tree.children || [])) { - const dep = asYarnDependency(path.join(prefix, name, 'node_modules'), child, prune); - - if (dep) { - children.push(dep); - } - } +export interface DependencyPath { + src: string; + dest: string; +} - return { name, path: dependencyPath, children }; +async function asYarnDependencies(root: string, rootDependencies: string[]): Promise { + const resolve = async (prefix: string, dependencies: string[]): Promise => await Promise.all(dependencies + .map(async (name: string) => { + let depPath = null, depManifest = null; + while (!depManifest && root.length <= prefix.length) { + depPath = path.join(prefix, 'node_modules', name); + try { + depManifest = await readNodeManifest(depPath); + } + catch (err) { + prefix = path.join(prefix, '..'); + if (prefix.length < root.length) { + throw err; + } + } + } + const children = await resolve(depPath, Object.keys(depManifest.dependencies || {})); + return { + name, + path: { + src: depPath, + dest: path.relative(root, depPath), + }, + children, + }; + })); + return resolve(root, rootDependencies); } function selectYarnDependencies(deps: YarnDependency[], packagedDependencies: string[]): YarnDependency[] { @@ -145,20 +154,10 @@ function selectYarnDependencies(deps: YarnDependency[], packagedDependencies: st return reached.values; } -async function getYarnProductionDependencies(cwd: string, packagedDependencies?: string[]): Promise { - const raw = await new Promise((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); - - if (!match || match.length !== 1) { - throw new Error('Could not parse result of `yarn list --json`'); - } - +async function getYarnProductionDependencies(root: string, manifest: Manifest, packagedDependencies?: string[]): Promise { const usingPackagedDependencies = Array.isArray(packagedDependencies); - const trees = JSON.parse(match[0]).data.trees as YarnTreeNode[]; - let result = trees - .map(tree => asYarnDependency(path.join(cwd, 'node_modules'), tree, !usingPackagedDependencies)) - .filter(dep => !!dep); + let result = await asYarnDependencies(root, Object.keys(manifest.dependencies || {})); if (usingPackagedDependencies) { result = selectYarnDependencies(result, packagedDependencies); @@ -167,20 +166,24 @@ async function getYarnProductionDependencies(cwd: string, packagedDependencies?: return result; } -async function getYarnDependencies(cwd: string, packagedDependencies?: string[]): Promise { - const result: string[] = [cwd]; +async function getYarnDependencies(cwd: string, manifest: Manifest, packagedDependencies?: string[]): Promise { + const root = findWorkspaceRoot(cwd) || cwd; + const result: DependencyPath[] = [{ + src: cwd, + dest: '' + }]; - if (await new Promise(c => fs.exists(path.join(cwd, 'yarn.lock'), c))) { - const deps = await getYarnProductionDependencies(cwd, packagedDependencies); + if (await new Promise(c => fs.exists(path.join(root, 'yarn.lock'), c))) { + const deps = await getYarnProductionDependencies(root, manifest, packagedDependencies); const flatten = (dep: YarnDependency) => { result.push(dep.path); dep.children.forEach(flatten); }; deps.forEach(flatten); } - return _.uniq(result); + return _.uniqBy(result, 'src'); } -export function getDependencies(cwd: string, useYarn = false, packagedDependencies?: string[]): Promise { - return useYarn ? getYarnDependencies(cwd, packagedDependencies) : getNpmDependencies(cwd); +export function getDependencies(cwd: string, manifest: Manifest, useYarn = false, packagedDependencies?: string[]): Promise { + return useYarn ? getYarnDependencies(cwd, manifest, packagedDependencies) : getNpmDependencies(cwd); } export function getLatestVersion(name: string, cancellationToken?: CancellationToken): Promise { diff --git a/src/package.ts b/src/package.ts index d6a72f8c..451daa81 100644 --- a/src/package.ts +++ b/src/package.ts @@ -731,10 +731,8 @@ export function validateManifest(manifest: Manifest): Manifest { return manifest; } -export function readManifest(cwd = process.cwd(), nls = true): Promise { +export function readNodeManifest(cwd = process.cwd()): Promise { const manifestPath = path.join(cwd, 'package.json'); - const manifestNLSPath = path.join(cwd, 'package.nls.json'); - const manifest = readFile(manifestPath, 'utf8') .catch(() => Promise.reject(`Extension manifest not found: ${manifestPath}`)) .then(manifestStr => { @@ -743,13 +741,19 @@ export function readManifest(cwd = process.cwd(), nls = true): Promise } catch (e) { return Promise.reject(`Error parsing 'package.json' manifest file: not a valid JSON file.`); } - }) - .then(validateManifest); + }); + return manifest; +} +export function readManifest(cwd = process.cwd(), nls = true): Promise { + const manifest = readNodeManifest(cwd) + .then(validateManifest); + if (!nls) { return manifest; } - + + const manifestNLSPath = path.join(cwd, 'package.nls.json'); const manifestNLS = readFile(manifestNLSPath, 'utf8') .catch(err => err.code !== 'ENOENT' ? Promise.reject(err) : Promise.resolve('{}')) .then(raw => { @@ -820,12 +824,12 @@ const defaultIgnore = [ '**/.vscode-test/**' ]; -function collectAllFiles(cwd: string, useYarn = false, dependencyEntryPoints?: string[]): Promise { - return getDependencies(cwd, useYarn, dependencyEntryPoints).then(deps => { +function collectAllFiles(cwd: string, manifest: Manifest, useYarn = false, dependencyEntryPoints?: string[]): Promise { + return getDependencies(cwd, manifest, useYarn, dependencyEntryPoints).then(deps => { const promises: Promise[] = deps.map(dep => { - return glob('**', { cwd: dep, nodir: true, dot: true, ignore: 'node_modules/**' }) + return glob('**', { cwd: dep.src, nodir: true, dot: true, ignore: 'node_modules/**' }) .then(files => files - .map(f => path.relative(cwd, path.join(dep, f))) + .map(f => path.join(dep.dest, f)) .map(f => f.replace(/\\/g, '/'))); }); @@ -833,8 +837,8 @@ function collectAllFiles(cwd: string, useYarn = false, dependencyEntryPoints?: s }); } -function collectFiles(cwd: string, useYarn = false, dependencyEntryPoints?: string[], ignoreFile?: string): Promise { - return collectAllFiles(cwd, useYarn, dependencyEntryPoints).then(files => { +function collectFiles(cwd: string, manifest: Manifest, useYarn = false, dependencyEntryPoints?: string[], ignoreFile?: string): Promise { + return collectAllFiles(cwd, manifest, useYarn, dependencyEntryPoints).then(files => { files = files.filter(f => !/\r$/m.test(f)); return readFile(ignoreFile ? ignoreFile : path.join(cwd, '.vscodeignore'), 'utf8') @@ -897,7 +901,7 @@ export function collect(manifest: Manifest, options: IPackageOptions = {}): Prom const ignoreFile = options.ignoreFile || undefined; const processors = createDefaultProcessors(manifest, options); - return collectFiles(cwd, useYarn, packagedDependencies, ignoreFile).then(fileNames => { + return collectFiles(cwd, manifest, useYarn, packagedDependencies, ignoreFile).then(fileNames => { const files = fileNames.map(f => ({ path: `extension/${f}`, localPath: path.join(cwd, f) })); return processFiles(processors, files); @@ -1000,7 +1004,7 @@ export async function packageCommand(options: IPackageOptions = {}): Promise { return readManifest(cwd) - .then(() => collectFiles(cwd, useYarn, packagedDependencies, ignoreFile)); + .then(manifest => collectFiles(cwd, manifest, useYarn, packagedDependencies, ignoreFile)); } /** @@ -1008,7 +1012,7 @@ export function listFiles(cwd = process.cwd(), useYarn = false, packagedDependen */ export function ls(cwd = process.cwd(), useYarn = false, packagedDependencies?: string[], ignoreFile?: string): Promise { return readManifest(cwd) - .then(manifest => prepublish(cwd, manifest, useYarn)) - .then(() => collectFiles(cwd, useYarn, packagedDependencies, ignoreFile)) + .then(manifest => prepublish(cwd, manifest, useYarn).then(() => manifest)) + .then(manifest => collectFiles(cwd, manifest, useYarn, packagedDependencies, ignoreFile)) .then(files => files.forEach(f => console.log(`${f}`))); } diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity b/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity new file mode 100644 index 00000000..8a558e68 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity @@ -0,0 +1,25 @@ +{ + "systemParams": "darwin-x64-72", + "modulesFolders": [ + "node_modules", + "node_modules", + "packageB/node_modules" + ], + "flags": [], + "linkedModules": [], + "topLevelPatterns": [ + "curry@*", + "in-array@*", + "is-number@*", + "package-a@*", + "package-a@1.0.0", + "package-b@1.0.0" + ], + "lockfileEntries": { + "curry@*": "https://registry.yarnpkg.com/curry/-/curry-1.2.0.tgz#9e6dd289548dba7e653d5ae3fe903fe7dfb33af2", + "in-array@*": "https://registry.yarnpkg.com/in-array/-/in-array-0.1.2.tgz#1a2683009177ab914ade0620a35c5039851f3715", + "is-number@*": "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + }, + "files": [], + "artifacts": {} +} \ No newline at end of file diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/curry/README.md b/src/test/fixtures/yarnWorkspaces/node_modules/curry/README.md new file mode 100644 index 00000000..8ae6ec36 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/curry/README.md @@ -0,0 +1,130 @@ +CURRY +===== + +A curry function without anything **too clever** +_(... because hunger is the finest spice)_ + +[![browser support](https://ci.testling.com/hughfdjackson/curry.png)](https://ci.testling.com/hughfdjackson/curry) + + +# Why + +If you don't know currying, or aren't sold on it's awesomeness, perhaps [a friendly blog post](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) will help. + + +# API + +### curry + +```javascript +var curry = require('curry'); + +//-- creating a curried function is pretty +//-- straight forward: +var add = curry(function(a, b){ return a + b }); + +//-- it can be called like normal: +add(1, 2) //= 3 + +//-- or, if you miss off any arguments, +//-- a new funtion that expects all (or some) of +//-- the remaining arguments will be created: +var add1 = add(1); +add1(2) //= 3; + +//-- curry knows how many arguments a function should take +//-- by the number of parameters in the parameter list + +//-- in this case, a function and two arrays is expected +//-- (fn, a, b). zipWith will combine two arrays using a function: +var zipWith = curry(function(fn, a, b){ + return a.map(function(val, i){ return fn(val, b[i]) }); +}); + +//-- if there are still more arguments required, a curried function +//-- will always return a new curried function: +var zipAdd = zipWith(add); +var zipAddWith123 = zipAdd([1, 2, 3]); + +//-- both functions are usable as you'd expect at any time: +zipAdd([1, 2, 3], [1, 2, 3]); //= [2, 4, 6] +zipAddWith123([5, 6, 7]); //= [6, 8, 10] + +//-- the number of arguments a function is expected to provide +//-- can be discovered by the .length property +zipWith.length; //= 3 +zipAdd.length; //= 2 +zipAddWith123.length; //= 1 +``` + +### curry.to + +Sometimes it's necessary (especially when wrapping variadic functions) to explicitly provide an arity for your curried function: + +```javascript +var sum = function(){ + var nums = [].slice.call(arguments); + return nums.reduce(function(a, b){ return a + b }); +} + +var sum3 = curry.to(3, sum); +var sum4 = curry.to(4, sum); + +sum3(1, 2)(3) //= 6 +sum4(1)(2)(3, 4) //= 10 +``` + +### curry.adapt + +It's a (sad?) fact that JavaScript functions are often written to take the 'context' object as the first argument. + +With curried functions, of course, we want it to be the last object. `curry.adapt` shifts the context to the last argument, +to give us a hand with this: + +```javascript +var delve = require('delve'); +var delveC = curry.adapt(delve); + +var getDataFromResponse = delveC('response.body.data'); +getDataFromResponse({ response: { body: { data: { x: 2 }} } }); //= { x: 2 } +``` + +### curry.adaptTo + +Like `curry.adapt`, but the arity explicitly provided: + +```javascript +var _ = require('lodash'); +var map = curry.adaptTo(2, _.map); +var mapInc = map(function(a){ return a + 1 }) + +mapInc([1, 2, 3]) //= [2, 3, 4] +``` + +# installation + +### node/npm + +```bash +npm install curry +``` + +### amd + +```javascript +define(['libs/curry.min'], function(curry){ + //-- assuming libs/curry.min.js is the downloaded minified version from this repo, + //-- curry will be available here +}); +``` + +### browser + +If you're not using tools like [browserify](https://github.com/substack/node-browserify) or [require.js](http://requirejs.org), you can load curry globally: +```html + + +``` +∏∏ diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/curry/curry.js b/src/test/fixtures/yarnWorkspaces/node_modules/curry/curry.js new file mode 100644 index 00000000..9d8fe5ae --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/curry/curry.js @@ -0,0 +1,97 @@ +var slice = Array.prototype.slice; +var toArray = function(a){ return slice.call(a) } +var tail = function(a){ return slice.call(a, 1) } + +// fn, [value] -> fn +//-- create a curried function, incorporating any number of +//-- pre-existing arguments (e.g. if you're further currying a function). +var createFn = function(fn, args, totalArity){ + var remainingArity = totalArity - args.length; + + switch (remainingArity) { + case 0: return function(){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 1: return function(a){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 2: return function(a,b){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 3: return function(a,b,c){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 4: return function(a,b,c,d){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 5: return function(a,b,c,d,e){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 6: return function(a,b,c,d,e,f){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 7: return function(a,b,c,d,e,f,g){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 8: return function(a,b,c,d,e,f,g,h){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 9: return function(a,b,c,d,e,f,g,h,i){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + case 10: return function(a,b,c,d,e,f,g,h,i,j){ return processInvocation(fn, concatArgs(args, arguments), totalArity) }; + default: return createEvalFn(fn, args, remainingArity); + } +} + +// [value], arguments -> [value] +//-- concat new arguments onto old arguments array +var concatArgs = function(args1, args2){ + return args1.concat(toArray(args2)); +} + +// fn, [value], int -> fn +//-- create a function of the correct arity by the use of eval, +//-- so that curry can handle functions of any arity +var createEvalFn = function(fn, args, arity){ + var argList = makeArgList(arity); + + //-- hack for IE's faulty eval parsing -- http://stackoverflow.com/a/6807726 + var fnStr = 'false||' + + 'function(' + argList + '){ return processInvocation(fn, concatArgs(args, arguments)); }'; + return eval(fnStr); +} + +var makeArgList = function(len){ + var a = []; + for ( var i = 0; i < len; i += 1 ) a.push('a' + i.toString()); + return a.join(','); +} + +var trimArrLength = function(arr, length){ + if ( arr.length > length ) return arr.slice(0, length); + else return arr; +} + +// fn, [value] -> value +//-- handle a function being invoked. +//-- if the arg list is long enough, the function will be called +//-- otherwise, a new curried version is created. +var processInvocation = function(fn, argsArr, totalArity){ + argsArr = trimArrLength(argsArr, totalArity); + + if ( argsArr.length === totalArity ) return fn.apply(null, argsArr); + return createFn(fn, argsArr, totalArity); +} + +// fn -> fn +//-- curries a function! <3 +var curry = function(fn){ + return createFn(fn, [], fn.length); +} + +// num, fn -> fn +//-- curries a function to a certain arity! <33 +curry.to = curry(function(arity, fn){ + return createFn(fn, [], arity); +}); + +// num, fn -> fn +//-- adapts a function in the context-first style +//-- to a curried version. <3333 +curry.adaptTo = curry(function(num, fn){ + return curry.to(num, function(context){ + var args = tail(arguments).concat(context); + return fn.apply(this, args); + }); +}) + +// fn -> fn +//-- adapts a function in the context-first style to +//-- a curried version. <333 +curry.adapt = function(fn){ + return curry.adaptTo(fn.length, fn) +} + + +module.exports = curry; diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/curry/curry.min.js b/src/test/fixtures/yarnWorkspaces/node_modules/curry/curry.min.js new file mode 100644 index 00000000..7a93ac9d --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/curry/curry.min.js @@ -0,0 +1 @@ +!function(e){if("function"==typeof bootstrap)bootstrap("curry",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeCurry=e}else"undefined"!=typeof window?window.curry=e():global.curry=e()}(function(){var define,ses,bootstrap,module,exports;return function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;slength)return arr.slice(0,length);else return arr};var processInvocation=function(fn,argsArr,totalArity){argsArr=trimArrLength(argsArr,totalArity);if(argsArr.length===totalArity)return fn.apply(null,argsArr);return createFn(fn,argsArr,totalArity)};var curry=function(fn){return createFn(fn,[],fn.length)};curry.to=curry(function(arity,fn){return createFn(fn,[],arity)});curry.adaptTo=curry(function(num,fn){return curry.to(num,function(context){var args=tail(arguments).concat(context);return fn.apply(this,args)})});curry.adapt=function(fn){return curry.adaptTo(fn.length,fn)};module.exports=curry},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/curry/examples/usage.js b/src/test/fixtures/yarnWorkspaces/node_modules/curry/examples/usage.js new file mode 100644 index 00000000..5a190c7f --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/curry/examples/usage.js @@ -0,0 +1,38 @@ +var curry = require('../'); + +//-- creating a curried function is pretty +//-- straight forward: +var add = curry(function(a, b){ return a + b }); + +//-- it can be called like normal: +add(1, 2) //= 3 + +//-- or, if you miss off any arguments, +//-- a new funtion that expects all (or some) of +//-- the remaining arguments will be created: +var add1 = add(1); +add1(2) //= 3; + +//-- curry knows how many arguments a function should take +//-- by the number of parameters in the parameter list + +//-- in this case, a function and two arrays is expected +//-- (fn, a, b). zipWith will combine two arrays using a function: +var zipWith = curry(function(fn, a, b){ + return a.map(function(val, i){ return fn(val, b[i]) }); +}); + +//-- if there are still more arguments required, a curried function +//-- will always return a new curried function: +var zipAdd = zipWith(add); +var zipAddWith123 = zipAdd([1, 2, 3]); + +//-- both functions are usable as you'd expect at any time: +zipAdd([1, 2, 3], [1, 2, 3]); //= [2, 4, 6] +zipAddWith123([5, 6, 7]); //= [6, 8, 10] + +//-- the number of arguments a function is expected to provide +//-- can be discovered by the .length property +zipWith.length; //= 3 +zipAdd.length; //= 2 +zipAddWith123.length; //= 1 diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/curry/package.json b/src/test/fixtures/yarnWorkspaces/node_modules/curry/package.json new file mode 100644 index 00000000..a96c633a --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/curry/package.json @@ -0,0 +1,43 @@ +{ + "name": "curry", + "description": "flexible but simple curry function", + "version": "1.2.0", + "homepage": "https://github.com/dominictarr/curry", + "repository": { + "type": "git", + "url": "git://github.com/dominictarr/curry.git" + }, + "author": "Dominic Tarr ", + "contributors": [ + "Hugh FD Jackson " + ], + "main": "./curry", + "devDependencies": { + "mocha": "1.8.1", + "browserify": "2.17.2", + "uglify-js": "2.3.6", + "lodash": "2.1.0", + "delve": "0.3.2" + }, + "testling": { + "files": "test/*-test.js", + "browsers": [ + "iexplore/6.0", + "iexplore/7.0", + "iexplore/8.0", + "iexplore/9.0", + "iexplore/10.0", + "chrome/4.0", + "chrome/23.0", + "firefox/3.0", + "firefox/17.0", + "safari/5.0.5", + "safari/5.1" + ], + "harness": "mocha" + }, + "scripts": { + "test": "./node_modules/mocha/bin/mocha test", + "prepublish": "./node_modules/browserify/bin/cmd.js --standalone curry -e curry.js | ./node_modules/uglify-js/bin/uglifyjs > curry.min.js" + } +} diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/curry/test/curry-test.js b/src/test/fixtures/yarnWorkspaces/node_modules/curry/test/curry-test.js new file mode 100644 index 00000000..53e1911c --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/curry/test/curry-test.js @@ -0,0 +1,133 @@ +var curry = require('../'); +var a = require('assert'); + + +describe('curry', function(){ + + it('should curry in the haskell sense, taking the arity from the function', function(){ + var sum5 = function(a, b, c, d, e){ return a + b + c + d + e }; + var sum5C = curry(sum5); + + a.equal(sum5(1, 2, 3, 4, 5), sum5C(1)(2)(3)(4)(5)); + }); + + it('should be pure - each new argument should not affect the overall list', function(){ + var add = curry(function(a, b){ return a + b }); + var add1 = add(1); + var add2 = add(2); + a.equal(add1(1), 2); + a.equal(add1(2), 3); + a.equal(add1(3), 4); + a.equal(add1(4), 5); + + a.equal(add2(1), 3); + a.equal(add2(2), 4); + a.equal(add2(3), 5); + a.equal(add2(4), 6); + }); + + it('should drop "extra" arguments', function(){ + var reportArgs = curry(function(a, b){ return [].slice.call(arguments) }); + + a.deepEqual(reportArgs('a', 'b', 'c', 'd', 'e'), ['a', 'b']); + }); + + it('should allow multiple arguments to be passed at a time', function(){ + var sum3 = curry(function(a, b, c){ return a + b + c }); + + a.equal(sum3(1, 2, 3), sum3(1, 2)(3)); + a.equal(sum3(1, 2, 3), sum3(1)(2, 3)); + a.equal(sum3(1, 2, 3), sum3(1)(2)(3)); + }); + + it('should report the arity of returned functions correctly', function(){ + var sum3 = curry(function(a, b, c){ return a + b + c }); + + a.equal(sum3.length, 3); + a.equal(sum3(1).length, 2); + a.equal(sum3(1)(2).length, 1); + + a.equal(curry(function(){}).length, 0) + a.equal(curry(function(a){}).length, 1) + a.equal(curry(function(a, b){}).length, 2) + a.equal(curry(function(a, b, c){}).length, 3) + a.equal(curry(function(a, b, c, d){}).length, 4) + a.equal(curry(function(a, b, c, d, e){}).length, 5) + a.equal(curry(function(a, b, c, d, e, f){}).length, 6) + a.equal(curry(function(a, b, c, d, e, f, g){}).length, 7) + a.equal(curry(function(a, b, c, d, e, f, g, h){}).length, 8) + a.equal(curry(function(a, b, c, d, e, f, g, h, i){}).length, 9) + a.equal(curry(function(a, b, c, d, e, f, g, h, i, j){}).length, 10) + a.equal(curry(function(a, b, c, d, e, f, g, h, i, j, k){}).length, 11) + a.equal(curry(function(a, b, c, d, e, f, g, h, i, j, k, l){}).length, 12) + a.equal(curry(function(a, b, c, d, e, f, g, h, i, j, k, l, m){}).length, 13) + a.equal(curry(function(a, b, c, d, e, f, g, h, i, j, k, l, m, n){}).length, 14) + a.equal(curry(function(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o){}).length, 15) + }); + + it('should allow 0 arg curried fns', function(){ + var noop = curry(function(){}); + + a.equal(noop(), undefined); + }); +}); + +describe('curry.to', function(){ + + it('should curry to the specified arity', function(){ + var noop = function(){}; + + for ( var i = 0; i < 15; i += 1 ) + a.equal(curry.to(i, noop).length, i); + }); + + it('should be curried', function(){ + var sum = function(){ + var nums = [].slice.call(arguments); + var count = 0; + + for ( var i = 0; i < nums.length; i += 1 ) count += nums[i]; + return count; + }; + + var sum3 = curry.to(3)(sum); + a.equal(sum3(1)(2)(3), 6); + }); +}); + +describe('curry.adapt', function(){ + it('should shift the first argument the end', function(){ + var noop = curry.adapt(function(){}); + var cat1 = curry.adapt(function(a){ return a }); + var cat2 = curry.adapt(function(a, b){ return a + b }); + var cat3 = curry.adapt(function(a, b, c){ return a + b + c }); + var cat4 = curry.adapt(function(a, b, c, d){ return a + b + c + d }); + + a.equal(noop(), undefined); + a.equal(cat1('a'), 'a'); + a.equal(cat2('a')('b'), 'ba'); + a.equal(cat3('a', 'b')('c'), 'bca'); + a.equal(cat4('a', 'b')('c', 'd'), 'bcda'); + }); +}); + +describe('curry.adaptTo', function(){ + it('should shift the first argument the end, and curry by a specified amount', function(){ + var cat = function(){ + var args = [].slice.call(arguments); + return args.join(''); + } + + var noop = curry.adaptTo(0)(cat); + var cat1 = curry.adaptTo(1)(cat); + var cat2 = curry.adaptTo(2)(cat); + var cat3 = curry.adaptTo(3)(cat); + var cat4 = curry.adaptTo(4)(cat); + + a.equal(noop(), ''); + a.equal(cat1('a'), 'a'); + a.equal(cat2('a')('b'), 'ba'); + a.equal(cat3('a', 'b')('c'), 'bca'); + a.equal(cat4('a', 'b')('c', 'd'), 'bcda'); + }); +}); diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/in-array/LICENSE b/src/test/fixtures/yarnWorkspaces/node_modules/in-array/LICENSE new file mode 100644 index 00000000..ce0a70f2 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/in-array/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/in-array/README.md b/src/test/fixtures/yarnWorkspaces/node_modules/in-array/README.md new file mode 100644 index 00000000..1e0219f0 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/in-array/README.md @@ -0,0 +1,76 @@ +# in-array [![NPM version](https://img.shields.io/npm/v/in-array.svg?style=flat)](https://www.npmjs.com/package/in-array) [![NPM downloads](https://img.shields.io/npm/dm/in-array.svg?style=flat)](https://npmjs.org/package/in-array) [![Build Status](https://img.shields.io/travis/jonschlinkert/in-array.svg?style=flat)](https://travis-ci.org/jonschlinkert/in-array) + +> Return true if a value exists in an array. Faster than using indexOf and won't blow up on null values. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install in-array --save +``` + +## Usage + +```js +var inArray = require('in-array'); +console.log(inArray(['a', 'b', 'c'], 'a')); +//=> true + +console.log(inArray(null, 'a')); +//=> false + +console.log(inArray(null)); +//=> false +``` + +## Related projects + +You might also be interested in these projects: + +* [arr-flatten](https://www.npmjs.com/package/arr-flatten): Recursively flatten an array or arrays. This is the fastest implementation of array flatten. | [homepage](https://github.com/jonschlinkert/arr-flatten) +* [arr-union](https://www.npmjs.com/package/arr-union): Combines a list of arrays, returning a single array with unique values, using strict equality… [more](https://www.npmjs.com/package/arr-union) | [homepage](https://github.com/jonschlinkert/arr-union) +* [is-plain-object](https://www.npmjs.com/package/is-plain-object): Returns true if an object was created by the `Object` constructor. | [homepage](https://github.com/jonschlinkert/is-plain-object) +* [isobject](https://www.npmjs.com/package/isobject): Returns true if the value is an object and not an array or null. | [homepage](https://github.com/jonschlinkert/isobject) + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/in-array/issues/new). + +## Building docs + +Generate readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install verb && npm run docs +``` + +Or, if [verb](https://github.com/verbose/verb) is installed globally: + +```sh +$ verb +``` + +## Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +## Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/in-array/blob/master/LICENSE). + +*** + +_This file was generated by [verb](https://github.com/verbose/verb), v, on March 27, 2016._ \ No newline at end of file diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/in-array/index.js b/src/test/fixtures/yarnWorkspaces/node_modules/in-array/index.js new file mode 100644 index 00000000..388c4faa --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/in-array/index.js @@ -0,0 +1,21 @@ +/*! + * in-array + * + * Copyright (c) 2014 Jon Schlinkert, contributors. + * Licensed under the MIT License + */ + +'use strict'; + +module.exports = function inArray (arr, val) { + arr = arr || []; + var len = arr.length; + var i; + + for (i = 0; i < len; i++) { + if (arr[i] === val) { + return true; + } + } + return false; +}; diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/in-array/package.json b/src/test/fixtures/yarnWorkspaces/node_modules/in-array/package.json new file mode 100644 index 00000000..8c5da4eb --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/in-array/package.json @@ -0,0 +1,61 @@ +{ + "name": "in-array", + "description": "Return true if a value exists in an array. Faster than using indexOf and won't blow up on null values.", + "version": "0.1.2", + "homepage": "https://github.com/jonschlinkert/in-array", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "repository": "jonschlinkert/in-array", + "bugs": { + "url": "https://github.com/jonschlinkert/in-array/issues" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "main": "index.js", + "engines": { + "node": ">=0.10.0" + }, + "scripts": { + "lint": "jshint *.js test/*.js", + "test": "npm run lint && mocha" + }, + "devDependencies": { + "benchmark": "^2.1.0", + "gulp-format-md": "^0.1.7" + }, + "keywords": [ + "array", + "check", + "element", + "find", + "index", + "index-of", + "of" + ], + "verb": { + "run": true, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "isobject", + "is-plain-object", + "arr-flatten", + "arr-union" + ] + }, + "reflinks": [ + "verb" + ], + "lint": { + "reflinks": true + } + } +} diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/is-number/LICENSE b/src/test/fixtures/yarnWorkspaces/node_modules/is-number/LICENSE new file mode 100644 index 00000000..9af4a67d --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/is-number/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/is-number/README.md b/src/test/fixtures/yarnWorkspaces/node_modules/is-number/README.md new file mode 100644 index 00000000..eb8149e8 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/is-number/README.md @@ -0,0 +1,187 @@ +# is-number [![NPM version](https://img.shields.io/npm/v/is-number.svg?style=flat)](https://www.npmjs.com/package/is-number) [![NPM monthly downloads](https://img.shields.io/npm/dm/is-number.svg?style=flat)](https://npmjs.org/package/is-number) [![NPM total downloads](https://img.shields.io/npm/dt/is-number.svg?style=flat)](https://npmjs.org/package/is-number) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/is-number.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/is-number) + +> Returns true if the value is a finite number. + +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save is-number +``` + +## Why is this needed? + +In JavaScript, it's not always as straightforward as it should be to reliably check if a value is a number. It's common for devs to use `+`, `-`, or `Number()` to cast a string value to a number (for example, when values are returned from user input, regex matches, parsers, etc). But there are many non-intuitive edge cases that yield unexpected results: + +```js +console.log(+[]); //=> 0 +console.log(+''); //=> 0 +console.log(+' '); //=> 0 +console.log(typeof NaN); //=> 'number' +``` + +This library offers a performant way to smooth out edge cases like these. + +## Usage + +```js +const isNumber = require('is-number'); +``` + +See the [tests](./test.js) for more examples. + +### true + +```js +isNumber(5e3); // true +isNumber(0xff); // true +isNumber(-1.1); // true +isNumber(0); // true +isNumber(1); // true +isNumber(1.1); // true +isNumber(10); // true +isNumber(10.10); // true +isNumber(100); // true +isNumber('-1.1'); // true +isNumber('0'); // true +isNumber('012'); // true +isNumber('0xff'); // true +isNumber('1'); // true +isNumber('1.1'); // true +isNumber('10'); // true +isNumber('10.10'); // true +isNumber('100'); // true +isNumber('5e3'); // true +isNumber(parseInt('012')); // true +isNumber(parseFloat('012')); // true +``` + +### False + +Everything else is false, as you would expect: + +```js +isNumber(Infinity); // false +isNumber(NaN); // false +isNumber(null); // false +isNumber(undefined); // false +isNumber(''); // false +isNumber(' '); // false +isNumber('foo'); // false +isNumber([1]); // false +isNumber([]); // false +isNumber(function () {}); // false +isNumber({}); // false +``` + +## Release history + +### 7.0.0 + +* Refactor. Now uses `.isFinite` if it exists. +* Performance is about the same as v6.0 when the value is a string or number. But it's now 3x-4x faster when the value is not a string or number. + +### 6.0.0 + +* Optimizations, thanks to @benaadams. + +### 5.0.0 + +**Breaking changes** + +* removed support for `instanceof Number` and `instanceof String` + +## Benchmarks + +As with all benchmarks, take these with a grain of salt. See the [benchmarks](./benchmark/index.js) for more detail. + +``` +# all +v7.0 x 413,222 ops/sec ±2.02% (86 runs sampled) +v6.0 x 111,061 ops/sec ±1.29% (85 runs sampled) +parseFloat x 317,596 ops/sec ±1.36% (86 runs sampled) +fastest is 'v7.0' + +# string +v7.0 x 3,054,496 ops/sec ±1.05% (89 runs sampled) +v6.0 x 2,957,781 ops/sec ±0.98% (88 runs sampled) +parseFloat x 3,071,060 ops/sec ±1.13% (88 runs sampled) +fastest is 'parseFloat,v7.0' + +# number +v7.0 x 3,146,895 ops/sec ±0.89% (89 runs sampled) +v6.0 x 3,214,038 ops/sec ±1.07% (89 runs sampled) +parseFloat x 3,077,588 ops/sec ±1.07% (87 runs sampled) +fastest is 'v6.0' +``` + +## About + +
+Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +
+ +
+Running Tests + +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` + +
+ +
+Building docs + +_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ + +To generate the readme, run the following command: + +```sh +$ npm install -g verbose/verb#dev verb-generate-readme && verb +``` + +
+ +### Related projects + +You might also be interested in these projects: + +* [is-plain-object](https://www.npmjs.com/package/is-plain-object): Returns true if an object was created by the `Object` constructor. | [homepage](https://github.com/jonschlinkert/is-plain-object "Returns true if an object was created by the `Object` constructor.") +* [is-primitive](https://www.npmjs.com/package/is-primitive): Returns `true` if the value is a primitive. | [homepage](https://github.com/jonschlinkert/is-primitive "Returns `true` if the value is a primitive. ") +* [isobject](https://www.npmjs.com/package/isobject): Returns true if the value is an object and not an array or null. | [homepage](https://github.com/jonschlinkert/isobject "Returns true if the value is an object and not an array or null.") +* [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of "Get the native type of a value.") + +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 49 | [jonschlinkert](https://github.com/jonschlinkert) | +| 5 | [charlike-old](https://github.com/charlike-old) | +| 1 | [benaadams](https://github.com/benaadams) | +| 1 | [realityking](https://github.com/realityking) | + +### Author + +**Jon Schlinkert** + +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) + +### License + +Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT License](LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on June 15, 2018._ \ No newline at end of file diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/is-number/index.js b/src/test/fixtures/yarnWorkspaces/node_modules/is-number/index.js new file mode 100644 index 00000000..27f19b75 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/is-number/index.js @@ -0,0 +1,18 @@ +/*! + * is-number + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +module.exports = function(num) { + if (typeof num === 'number') { + return num - num === 0; + } + if (typeof num === 'string' && num.trim() !== '') { + return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); + } + return false; +}; diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/is-number/package.json b/src/test/fixtures/yarnWorkspaces/node_modules/is-number/package.json new file mode 100644 index 00000000..37150726 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/is-number/package.json @@ -0,0 +1,82 @@ +{ + "name": "is-number", + "description": "Returns true if a number or string value is a finite number. Useful for regex matches, parsing, user input, etc.", + "version": "7.0.0", + "homepage": "https://github.com/jonschlinkert/is-number", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "contributors": [ + "Jon Schlinkert (http://twitter.com/jonschlinkert)", + "Olsten Larck (https://i.am.charlike.online)", + "Rouven Weßling (www.rouvenwessling.de)" + ], + "repository": "jonschlinkert/is-number", + "bugs": { + "url": "https://github.com/jonschlinkert/is-number/issues" + }, + "license": "MIT", + "files": [ + "index.js" + ], + "main": "index.js", + "engines": { + "node": ">=0.12.0" + }, + "scripts": { + "test": "mocha" + }, + "devDependencies": { + "ansi": "^0.3.1", + "benchmark": "^2.1.4", + "gulp-format-md": "^1.0.0", + "mocha": "^3.5.3" + }, + "keywords": [ + "cast", + "check", + "coerce", + "coercion", + "finite", + "integer", + "is", + "isnan", + "is-nan", + "is-num", + "is-number", + "isnumber", + "isfinite", + "istype", + "kind", + "math", + "nan", + "num", + "number", + "numeric", + "parseFloat", + "parseInt", + "test", + "type", + "typeof", + "value" + ], + "verb": { + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "related": { + "list": [ + "is-plain-object", + "is-primitive", + "isobject", + "kind-of" + ] + }, + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + } + } +} diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/package-a b/src/test/fixtures/yarnWorkspaces/node_modules/package-a new file mode 120000 index 00000000..ea7528af --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/package-a @@ -0,0 +1 @@ +../packageA \ No newline at end of file diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/package-b b/src/test/fixtures/yarnWorkspaces/node_modules/package-b new file mode 120000 index 00000000..b9b0c8fc --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/package-b @@ -0,0 +1 @@ +../packageB \ No newline at end of file diff --git a/src/test/fixtures/yarnWorkspaces/package.json b/src/test/fixtures/yarnWorkspaces/package.json new file mode 100644 index 00000000..899beedb --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/package.json @@ -0,0 +1,15 @@ +{ + "name": "yarn-workspaces-monorepo", + "publisher": "mocha", + "version": "1.0.0", + "private": true, + "engines": { "vscode": "*" }, + "workspaces": [ + "packageA", + "packageB" + ], + "dependencies": { + }, + "devDependencies": { + } +} diff --git a/src/test/fixtures/yarnWorkspaces/packageA/main.js b/src/test/fixtures/yarnWorkspaces/packageA/main.js new file mode 100644 index 00000000..90d2a58e --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/packageA/main.js @@ -0,0 +1 @@ +// Package A diff --git a/src/test/fixtures/yarnWorkspaces/packageA/package.json b/src/test/fixtures/yarnWorkspaces/packageA/package.json new file mode 100644 index 00000000..51a1a8d1 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/packageA/package.json @@ -0,0 +1,12 @@ +{ + "name": "package-a", + "publisher": "mocha", + "version": "1.0.0", + "engines": { "vscode": "*" }, + "dependencies": { + "curry": "*" + }, + "devDependencies": { + "is-number": "*" + } +} diff --git a/src/test/fixtures/yarnWorkspaces/packageB/main.js b/src/test/fixtures/yarnWorkspaces/packageB/main.js new file mode 100644 index 00000000..7fc1d307 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/packageB/main.js @@ -0,0 +1 @@ +// Package B diff --git a/src/test/fixtures/yarnWorkspaces/packageB/package.json b/src/test/fixtures/yarnWorkspaces/packageB/package.json new file mode 100644 index 00000000..496d7743 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/packageB/package.json @@ -0,0 +1,12 @@ +{ + "name": "package-b", + "publisher": "mocha", + "version": "1.0.0", + "engines": { "vscode": "*" }, + "dependencies": { + "package-a": "*" + }, + "devDependencies": { + "in-array": "*" + } +} diff --git a/src/test/fixtures/yarnWorkspaces/yarn.lock b/src/test/fixtures/yarnWorkspaces/yarn.lock new file mode 100644 index 00000000..c5404c86 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/yarn.lock @@ -0,0 +1,18 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +curry@*: + version "1.2.0" + resolved "https://registry.yarnpkg.com/curry/-/curry-1.2.0.tgz#9e6dd289548dba7e653d5ae3fe903fe7dfb33af2" + integrity sha1-nm3SiVSNun5lPVrj/pA/59+zOvI= + +in-array@*: + version "0.1.2" + resolved "https://registry.yarnpkg.com/in-array/-/in-array-0.1.2.tgz#1a2683009177ab914ade0620a35c5039851f3715" + integrity sha1-GiaDAJF3q5FK3gYgo1xQOYUfNxU= + +is-number@*: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== diff --git a/src/test/package.test.ts b/src/test/package.test.ts index 221cdda5..38a45b0f 100644 --- a/src/test/package.test.ts +++ b/src/test/package.test.ts @@ -220,6 +220,39 @@ describe('collect', function () { files.forEach(file => assert.ok(file.path.indexOf('/node_modules/which/') < 0, file.path)); }); }); + + it('should collect the right files when using yarn workspaces', async () => { + // PackageB will act as the extension here + const cwd = path.join(fixture('yarnWorkspaces'), 'packageB'); + const manifest = await readManifest(cwd); + + assert.equal(manifest.name, 'package-b'); + + const files = await collect(manifest, { cwd, useYarn: true }); + + [ + { + path: 'extension/main.js', + }, + { + path: 'extension/package.json', + }, + { + path: 'extension/node_modules/package-a/main.js', + }, + { + path: 'extension/node_modules/package-a/package.json', + }, + { + path: 'extension/node_modules/curry/curry.js', + }, + { + path: 'extension/node_modules/curry/package.json', + } + ].forEach(file => { + assert.ok(files.some(f => f.path === file.path), file.path); + }) + }) }); describe('readManifest', () => { diff --git a/yarn.lock b/yarn.lock index beeeea4c..52521a77 100644 --- a/yarn.lock +++ b/yarn.lock @@ -153,7 +153,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@~3.0.2: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -426,6 +426,13 @@ find-up@3.0.0, find-up@^3.0.0: dependencies: locate-path "^3.0.0" +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== + dependencies: + micromatch "^4.0.2" + flat@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" @@ -663,6 +670,14 @@ mdurl@^1.0.1: resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + mime@^1.3.4: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -881,7 +896,7 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= -picomatch@^2.0.4: +picomatch@^2.0.4, picomatch@^2.0.5: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== From 3725dc143c282f3ff647d6257406b3b567d254ec Mon Sep 17 00:00:00 2001 From: Sebastiaan Brouwer Date: Mon, 22 Jun 2020 15:58:02 +0200 Subject: [PATCH 2/8] fix: should have newPrefix for every dependency --- src/npm.ts | 12 +- .../node_modules/.yarn-integrity | 9 +- .../node_modules/filter-obj/index.d.ts | 39 +++++++ .../node_modules/filter-obj/index.js | 14 +++ .../node_modules/filter-obj/license | 9 ++ .../node_modules/filter-obj/package.json | 37 ++++++ .../node_modules/filter-obj/readme.md | 57 ++++++++++ .../node_modules/map-obj/index.d.ts | 106 ++++++++++++++++++ .../node_modules/map-obj/index.js | 54 +++++++++ .../node_modules/map-obj/license | 9 ++ .../node_modules/map-obj/package.json | 42 +++++++ .../node_modules/map-obj/readme.md | 76 +++++++++++++ .../yarnWorkspaces/packageA/package.json | 9 +- .../yarnWorkspaces/packageB/package.json | 7 +- src/test/fixtures/yarnWorkspaces/yarn.lock | 10 ++ 15 files changed, 477 insertions(+), 13 deletions(-) create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/index.d.ts create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/index.js create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/license create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/package.json create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/readme.md create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/map-obj/index.d.ts create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/map-obj/index.js create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/map-obj/license create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/map-obj/package.json create mode 100644 src/test/fixtures/yarnWorkspaces/node_modules/map-obj/readme.md diff --git a/src/npm.ts b/src/npm.ts index a6d363ea..03495ea9 100644 --- a/src/npm.ts +++ b/src/npm.ts @@ -82,15 +82,17 @@ export interface DependencyPath { async function asYarnDependencies(root: string, rootDependencies: string[]): Promise { const resolve = async (prefix: string, dependencies: string[]): Promise => await Promise.all(dependencies .map(async (name: string) => { - let depPath = null, depManifest = null; - while (!depManifest && root.length <= prefix.length) { - depPath = path.join(prefix, 'node_modules', name); + let newPrefix = prefix, depPath = null, depManifest = null; + while (!depManifest && root.length <= newPrefix.length) { + depPath = path.join(newPrefix, 'node_modules', name); + console.log(depPath); try { depManifest = await readNodeManifest(depPath); } catch (err) { - prefix = path.join(prefix, '..'); - if (prefix.length < root.length) { + newPrefix = path.join(newPrefix, '..'); + if (newPrefix.length < root.length) { + console.log(newPrefix, root) throw err; } } diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity b/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity index 8a558e68..1091c617 100644 --- a/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity +++ b/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity @@ -2,23 +2,26 @@ "systemParams": "darwin-x64-72", "modulesFolders": [ "node_modules", - "node_modules", - "packageB/node_modules" + "node_modules" ], "flags": [], "linkedModules": [], "topLevelPatterns": [ "curry@*", + "filter-obj@^2.0.1", "in-array@*", "is-number@*", + "map-obj@^4.1.0", "package-a@*", "package-a@1.0.0", "package-b@1.0.0" ], "lockfileEntries": { "curry@*": "https://registry.yarnpkg.com/curry/-/curry-1.2.0.tgz#9e6dd289548dba7e653d5ae3fe903fe7dfb33af2", + "filter-obj@^2.0.1": "https://registry.yarnpkg.com/filter-obj/-/filter-obj-2.0.1.tgz#34d9f0536786f072df7aeac3a8bda1c6e767aec6", "in-array@*": "https://registry.yarnpkg.com/in-array/-/in-array-0.1.2.tgz#1a2683009177ab914ade0620a35c5039851f3715", - "is-number@*": "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + "is-number@*": "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b", + "map-obj@^4.1.0": "https://registry.yarnpkg.com/map-obj/-/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" }, "files": [], "artifacts": {} diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/index.d.ts b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/index.d.ts new file mode 100644 index 00000000..4176d48c --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/index.d.ts @@ -0,0 +1,39 @@ +/** +Filter object keys and values into a new object. + +@param object - Source object to filter properties from. +@param predicate - Predicate function that detemines whether a property should be assigned to the new object. +@param includeKeys - Property names that should be assigned to the new object. + +@example +``` +import filterObject = require('filter-obj'); + +const object = { + foo: true, + bar: false +}; + +const newObject = filterObject(object, (key, value) => value === true); +//=> {foo: true} + +const newObject2 = filterObject(object, ['bar']); +//=> {bar: false} +``` +*/ +declare function filterObject( + object: ObjectType, + predicate: ( + key: keyof ObjectType, + value: ObjectType[keyof ObjectType] + ) => boolean +): Partial; +declare function filterObject< + ObjectType extends {[key: string]: any}, + IncludedKeys extends keyof ObjectType +>( + object: ObjectType, + includeKeys: ReadonlyArray +): Pick; + +export = filterObject; diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/index.js b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/index.js new file mode 100644 index 00000000..b05ed67c --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/index.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = (object, predicate) => { + const result = {}; + const isArray = Array.isArray(predicate); + + for (const [key, value] of Object.entries(object)) { + if (isArray ? predicate.includes(key) : predicate(key, value, object)) { + result[key] = value; + } + } + + return result; +}; diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/license b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/license new file mode 100644 index 00000000..e7af2f77 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/package.json b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/package.json new file mode 100644 index 00000000..3da71cc4 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/package.json @@ -0,0 +1,37 @@ +{ + "name": "filter-obj", + "version": "2.0.1", + "description": "Filter object keys and values into a new object", + "license": "MIT", + "repository": "sindresorhus/filter-obj", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "filter", + "object", + "key", + "keys", + "value", + "values", + "iterate", + "iterator" + ], + "devDependencies": { + "ava": "^2.4.0", + "tsd": "^0.9.0", + "xo": "^0.25.3" + } +} diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/readme.md b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/readme.md new file mode 100644 index 00000000..57c84ccd --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/filter-obj/readme.md @@ -0,0 +1,57 @@ +# filter-obj [![Build Status](https://travis-ci.org/sindresorhus/filter-obj.svg?branch=master)](https://travis-ci.org/sindresorhus/filter-obj) + +> Filter object keys and values into a new object + + +## Install + +``` +$ npm install filter-obj +``` + + +## Usage + +```js +const filterObject = require('filter-obj'); + +const object = { + foo: true, + bar: false +}; + +const newObject = filterObject(object, (key, value) => value === true); +//=> {foo: true} + +const newObject2 = filterObject(object, ['bar']); +//=> {bar: false} +``` + + +## API + +### filterObject(source, filter) +### filterObject(source, includeKeys) + +#### source + +Type: `object` + +Source object to filter properties from. + +#### filter + +Type: `Function` + +A predicate function that detemines whether a property should be assigned to the new object. The function has the signature `filterFunction(sourceKey, sourceValue, source)`. + +#### includeKeys + +Type: `string[]` + +Array of property names that should be assigned to the new object. + + +## Related + +- [map-obj](https://github.com/sindresorhus/map-obj) - Map object keys and values into a new object diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/index.d.ts b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/index.d.ts new file mode 100644 index 00000000..50b5e174 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/index.d.ts @@ -0,0 +1,106 @@ +declare namespace mapObject { + type Mapper< + SourceObjectType extends {[key: string]: any}, + MappedObjectKeyType extends string, + MappedObjectValueType + > = ( + sourceKey: keyof SourceObjectType, + sourceValue: SourceObjectType[keyof SourceObjectType], + source: SourceObjectType + ) => [MappedObjectKeyType, MappedObjectValueType]; + + interface Options { + /** + Recurse nested objects and objects in arrays. + + @default false + */ + deep?: boolean; + + /** + Target object to map properties on to. + + @default {} + */ + target?: {[key: string]: any}; + } + + interface DeepOptions extends Options { + deep: true; + } + + interface TargetOptions extends Options { + target: TargetObjectType; + } +} + +/** +Map object keys and values into a new object. + +@param source - Source object to copy properties from. +@param mapper - Mapping function. + +@example +``` +import mapObject = require('map-obj'); + +const newObject = mapObject({foo: 'bar'}, (key, value) => [value, key]); +//=> {bar: 'foo'} +``` +*/ +declare function mapObject< + SourceObjectType extends object, + TargetObjectType extends {[key: string]: any}, + MappedObjectKeyType extends string, + MappedObjectValueType +>( + source: SourceObjectType, + mapper: mapObject.Mapper< + SourceObjectType, + MappedObjectKeyType, + MappedObjectValueType + >, + options: mapObject.DeepOptions & mapObject.TargetOptions +): TargetObjectType & {[key: string]: unknown}; +declare function mapObject< + SourceObjectType extends object, + MappedObjectKeyType extends string, + MappedObjectValueType +>( + source: SourceObjectType, + mapper: mapObject.Mapper< + SourceObjectType, + MappedObjectKeyType, + MappedObjectValueType + >, + options: mapObject.DeepOptions +): {[key: string]: unknown}; +declare function mapObject< + SourceObjectType extends {[key: string]: any}, + TargetObjectType extends {[key: string]: any}, + MappedObjectKeyType extends string, + MappedObjectValueType +>( + source: SourceObjectType, + mapper: mapObject.Mapper< + SourceObjectType, + MappedObjectKeyType, + MappedObjectValueType + >, + options: mapObject.TargetOptions +): TargetObjectType & {[K in MappedObjectKeyType]: MappedObjectValueType}; +declare function mapObject< + SourceObjectType extends {[key: string]: any}, + MappedObjectKeyType extends string, + MappedObjectValueType +>( + source: SourceObjectType, + mapper: mapObject.Mapper< + SourceObjectType, + MappedObjectKeyType, + MappedObjectValueType + >, + options?: mapObject.Options +): {[K in MappedObjectKeyType]: MappedObjectValueType}; + +export = mapObject; diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/index.js b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/index.js new file mode 100644 index 00000000..4f1e4be9 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/index.js @@ -0,0 +1,54 @@ +'use strict'; + +const isObject = value => typeof value === 'object' && value !== null; + +// Customized for this use-case +const isObjectCustom = value => + isObject(value) && + !(value instanceof RegExp) && + !(value instanceof Error) && + !(value instanceof Date); + +const mapObject = (object, mapper, options, isSeen = new WeakMap()) => { + options = { + deep: false, + target: {}, + ...options + }; + + if (isSeen.has(object)) { + return isSeen.get(object); + } + + isSeen.set(object, options.target); + + const {target} = options; + delete options.target; + + const mapArray = array => array.map(element => isObjectCustom(element) ? mapObject(element, mapper, options, isSeen) : element); + if (Array.isArray(object)) { + return mapArray(object); + } + + for (const [key, value] of Object.entries(object)) { + let [newKey, newValue] = mapper(key, value, object); + + if (options.deep && isObjectCustom(newValue)) { + newValue = Array.isArray(newValue) ? + mapArray(newValue) : + mapObject(newValue, mapper, options, isSeen); + } + + target[newKey] = newValue; + } + + return target; +}; + +module.exports = (object, mapper, options) => { + if (!isObject(object)) { + throw new TypeError(`Expected an object, got \`${object}\` (${typeof object})`); + } + + return mapObject(object, mapper, options); +}; diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/license b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/license new file mode 100644 index 00000000..e7af2f77 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/package.json b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/package.json new file mode 100644 index 00000000..18cf63c3 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/package.json @@ -0,0 +1,42 @@ +{ + "name": "map-obj", + "version": "4.1.0", + "description": "Map object keys and values into a new object", + "license": "MIT", + "repository": "sindresorhus/map-obj", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "map", + "object", + "key", + "keys", + "value", + "values", + "iterate", + "iterator", + "rename", + "modify", + "deep", + "recurse", + "recursive" + ], + "devDependencies": { + "ava": "^2.0.0", + "tsd": "^0.7.3", + "xo": "^0.24.0" + } +} diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/readme.md b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/readme.md new file mode 100644 index 00000000..cd405f56 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/node_modules/map-obj/readme.md @@ -0,0 +1,76 @@ +# map-obj [![Build Status](https://travis-ci.org/sindresorhus/map-obj.svg?branch=master)](https://travis-ci.org/sindresorhus/map-obj) + +> Map object keys and values into a new object + + +## Install + +``` +$ npm install map-obj +``` + + +## Usage + +```js +const mapObject = require('map-obj'); + +const newObject = mapObject({foo: 'bar'}, (key, value) => [value, key]); +//=> {bar: 'foo'} +``` + + +## API + +### mapObject(source, mapper, options?) + +#### source + +Type: `object` + +Source object to copy properties from. + +#### mapper + +Type: `Function` + +Mapping function. + +- It has signature `mapper(sourceKey, sourceValue, source)`. +- It must return a two item array: `[targetKey, targetValue]`. + +#### options + +Type: `object` + +##### deep + +Type: `boolean`
+Default: `false` + +Recurse nested objects and objects in arrays. + +##### target + +Type: `object`
+Default: `{}` + +Target object to map properties on to. + + +## Related + +- [filter-obj](https://github.com/sindresorhus/filter-obj) - Filter object keys and values into a new object + + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
diff --git a/src/test/fixtures/yarnWorkspaces/packageA/package.json b/src/test/fixtures/yarnWorkspaces/packageA/package.json index 51a1a8d1..741a1e2f 100644 --- a/src/test/fixtures/yarnWorkspaces/packageA/package.json +++ b/src/test/fixtures/yarnWorkspaces/packageA/package.json @@ -2,11 +2,14 @@ "name": "package-a", "publisher": "mocha", "version": "1.0.0", - "engines": { "vscode": "*" }, + "engines": { + "vscode": "*" + }, "dependencies": { - "curry": "*" + "curry": "1.2.0", + "filter-obj": "2.0.1" }, "devDependencies": { - "is-number": "*" + "is-number": "7.0.0" } } diff --git a/src/test/fixtures/yarnWorkspaces/packageB/package.json b/src/test/fixtures/yarnWorkspaces/packageB/package.json index 496d7743..4c5c6fa2 100644 --- a/src/test/fixtures/yarnWorkspaces/packageB/package.json +++ b/src/test/fixtures/yarnWorkspaces/packageB/package.json @@ -2,11 +2,14 @@ "name": "package-b", "publisher": "mocha", "version": "1.0.0", - "engines": { "vscode": "*" }, + "engines": { + "vscode": "*" + }, "dependencies": { + "map-obj": "4.1.0", "package-a": "*" }, "devDependencies": { - "in-array": "*" + "in-array": "0.1.2" } } diff --git a/src/test/fixtures/yarnWorkspaces/yarn.lock b/src/test/fixtures/yarnWorkspaces/yarn.lock index c5404c86..0aec7b78 100644 --- a/src/test/fixtures/yarnWorkspaces/yarn.lock +++ b/src/test/fixtures/yarnWorkspaces/yarn.lock @@ -7,6 +7,11 @@ curry@*: resolved "https://registry.yarnpkg.com/curry/-/curry-1.2.0.tgz#9e6dd289548dba7e653d5ae3fe903fe7dfb33af2" integrity sha1-nm3SiVSNun5lPVrj/pA/59+zOvI= +filter-obj@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-2.0.1.tgz#34d9f0536786f072df7aeac3a8bda1c6e767aec6" + integrity sha512-yDEp513p7+iLdFHWBVdZFnRiOYwg8ZqmpaAiZCMjzqsbo7tCS4Qm4ulXOht337NGzkukKa9u3W4wqQ9tQPm3Ug== + in-array@*: version "0.1.2" resolved "https://registry.yarnpkg.com/in-array/-/in-array-0.1.2.tgz#1a2683009177ab914ade0620a35c5039851f3715" @@ -16,3 +21,8 @@ is-number@*: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +map-obj@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" + integrity sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g== From b3490530f9a7d1f33780083f71e452522d79fa76 Mon Sep 17 00:00:00 2001 From: Sebastiaan Brouwer Date: Mon, 22 Jun 2020 16:03:35 +0200 Subject: [PATCH 3/8] fix: remove console.log --- src/npm.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/npm.ts b/src/npm.ts index 03495ea9..4520ba01 100644 --- a/src/npm.ts +++ b/src/npm.ts @@ -85,14 +85,12 @@ async function asYarnDependencies(root: string, rootDependencies: string[]): Pro let newPrefix = prefix, depPath = null, depManifest = null; while (!depManifest && root.length <= newPrefix.length) { depPath = path.join(newPrefix, 'node_modules', name); - console.log(depPath); try { depManifest = await readNodeManifest(depPath); } catch (err) { newPrefix = path.join(newPrefix, '..'); if (newPrefix.length < root.length) { - console.log(newPrefix, root) throw err; } } From 10298f606441e5f1f6c02712af3357ba49d06e48 Mon Sep 17 00:00:00 2001 From: Sebastiaan Brouwer Date: Mon, 22 Jun 2020 18:38:29 +0200 Subject: [PATCH 4/8] fix: localPath was missing the src depencency folder --- src/npm.ts | 12 ++++----- src/package.ts | 25 +++++++++++-------- .../node_modules/.yarn-integrity | 20 +++++++-------- src/test/fixtures/yarnWorkspaces/yarn.lock | 10 ++++---- src/test/package.test.ts | 19 +++++++++++--- 5 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/npm.ts b/src/npm.ts index 4520ba01..9200a755 100644 --- a/src/npm.ts +++ b/src/npm.ts @@ -54,7 +54,7 @@ function checkNPM(cancellationToken?: CancellationToken): Promise { }); } -function getNpmDependencies(cwd: string): Promise { +function getNpmDependencies(cwd: string): Promise { return checkNPM() .then(() => exec('npm list --production --parseable --depth=99999 --loglevel=error', { cwd, maxBuffer: 5000 * 1024 })) .then(({ stdout }) => stdout @@ -70,11 +70,11 @@ function getNpmDependencies(cwd: string): Promise { export interface YarnDependency { name: string; - path: DependencyPath; + path: SourceAndDestination; children: YarnDependency[]; } -export interface DependencyPath { +export interface SourceAndDestination { src: string; dest: string; } @@ -166,9 +166,9 @@ async function getYarnProductionDependencies(root: string, manifest: Manifest, p return result; } -async function getYarnDependencies(cwd: string, manifest: Manifest, packagedDependencies?: string[]): Promise { +async function getYarnDependencies(cwd: string, manifest: Manifest, packagedDependencies?: string[]): Promise { const root = findWorkspaceRoot(cwd) || cwd; - const result: DependencyPath[] = [{ + const result: SourceAndDestination[] = [{ src: cwd, dest: '' }]; @@ -182,7 +182,7 @@ async function getYarnDependencies(cwd: string, manifest: Manifest, packagedDepe return _.uniqBy(result, 'src'); } -export function getDependencies(cwd: string, manifest: Manifest, useYarn = false, packagedDependencies?: string[]): Promise { +export function getDependencies(cwd: string, manifest: Manifest, useYarn = false, packagedDependencies?: string[]): Promise { return useYarn ? getYarnDependencies(cwd, manifest, packagedDependencies) : getNpmDependencies(cwd); } diff --git a/src/package.ts b/src/package.ts index 451daa81..d9c2f49c 100644 --- a/src/package.ts +++ b/src/package.ts @@ -15,7 +15,7 @@ import * as url from 'url'; import { lookup } from 'mime'; import * as urljoin from 'url-join'; import { validatePublisher, validateExtensionName, validateVersion, validateEngineCompatibility, validateVSCodeTypesCompatibility } from './validation'; -import { getDependencies } from './npm'; +import { getDependencies, SourceAndDestination } from './npm'; const readFile = denodeify(fs.readFile); const unlink = denodeify(fs.unlink as any); @@ -824,22 +824,26 @@ const defaultIgnore = [ '**/.vscode-test/**' ]; -function collectAllFiles(cwd: string, manifest: Manifest, useYarn = false, dependencyEntryPoints?: string[]): Promise { +function collectAllFiles(cwd: string, manifest: Manifest, useYarn = false, dependencyEntryPoints?: string[]): Promise { return getDependencies(cwd, manifest, useYarn, dependencyEntryPoints).then(deps => { - const promises: Promise[] = deps.map(dep => { + const promises: Promise[] = deps.map(dep => { return glob('**', { cwd: dep.src, nodir: true, dot: true, ignore: 'node_modules/**' }) .then(files => files - .map(f => path.join(dep.dest, f)) - .map(f => f.replace(/\\/g, '/'))); + .map(f => { + return { + src: path.relative(cwd, path.join(dep.src, f.replace(/\\/g, '/'))), + dest: path.join(dep.dest, f).replace(/\\/g, '/') + } + })) }); return Promise.all(promises).then(util.flatten); }); } -function collectFiles(cwd: string, manifest: Manifest, useYarn = false, dependencyEntryPoints?: string[], ignoreFile?: string): Promise { +function collectFiles(cwd: string, manifest: Manifest, useYarn = false, dependencyEntryPoints?: string[], ignoreFile?: string): Promise { return collectAllFiles(cwd, manifest, useYarn, dependencyEntryPoints).then(files => { - files = files.filter(f => !/\r$/m.test(f)); + files = files.filter(f => !/\r$/m.test(f.src)); return readFile(ignoreFile ? ignoreFile : path.join(cwd, '.vscodeignore'), 'utf8') .catch(err => err.code !== 'ENOENT' ? Promise.reject(err) : ignoreFile ? Promise.reject(err) : Promise.resolve('')) @@ -858,7 +862,7 @@ function collectFiles(cwd: string, manifest: Manifest, useYarn = false, dependen .then(r => ({ ignore: r[0], negate: r[1] })) // Filter out files - .then(({ ignore, negate }) => files.filter(f => !ignore.some(i => minimatch(f, i, MinimatchOptions)) || negate.some(i => minimatch(f, i.substr(1), MinimatchOptions)))); + .then(({ ignore, negate }) => files.filter(f => !ignore.some(i => minimatch(f.src, i, MinimatchOptions)) || negate.some(i => minimatch(f.src, i.substr(1), MinimatchOptions)))); }); } @@ -902,7 +906,7 @@ export function collect(manifest: Manifest, options: IPackageOptions = {}): Prom const processors = createDefaultProcessors(manifest, options); return collectFiles(cwd, manifest, useYarn, packagedDependencies, ignoreFile).then(fileNames => { - const files = fileNames.map(f => ({ path: `extension/${f}`, localPath: path.join(cwd, f) })); + const files = fileNames.map(f => ({ path: `extension/${f.dest}`, localPath: path.join(cwd, f.src) })); return processFiles(processors, files); }); @@ -1004,7 +1008,8 @@ export async function packageCommand(options: IPackageOptions = {}): Promise { return readManifest(cwd) - .then(manifest => collectFiles(cwd, manifest, useYarn, packagedDependencies, ignoreFile)); + .then(manifest => collectFiles(cwd, manifest, useYarn, packagedDependencies, ignoreFile)) + .then(files => files.map(f => f.src)); } /** diff --git a/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity b/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity index 1091c617..ea5f503d 100644 --- a/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity +++ b/src/test/fixtures/yarnWorkspaces/node_modules/.yarn-integrity @@ -7,21 +7,21 @@ "flags": [], "linkedModules": [], "topLevelPatterns": [ - "curry@*", - "filter-obj@^2.0.1", - "in-array@*", - "is-number@*", - "map-obj@^4.1.0", + "curry@1.2.0", + "filter-obj@2.0.1", + "in-array@0.1.2", + "is-number@7.0.0", + "map-obj@4.1.0", "package-a@*", "package-a@1.0.0", "package-b@1.0.0" ], "lockfileEntries": { - "curry@*": "https://registry.yarnpkg.com/curry/-/curry-1.2.0.tgz#9e6dd289548dba7e653d5ae3fe903fe7dfb33af2", - "filter-obj@^2.0.1": "https://registry.yarnpkg.com/filter-obj/-/filter-obj-2.0.1.tgz#34d9f0536786f072df7aeac3a8bda1c6e767aec6", - "in-array@*": "https://registry.yarnpkg.com/in-array/-/in-array-0.1.2.tgz#1a2683009177ab914ade0620a35c5039851f3715", - "is-number@*": "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b", - "map-obj@^4.1.0": "https://registry.yarnpkg.com/map-obj/-/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" + "curry@1.2.0": "https://registry.yarnpkg.com/curry/-/curry-1.2.0.tgz#9e6dd289548dba7e653d5ae3fe903fe7dfb33af2", + "filter-obj@2.0.1": "https://registry.yarnpkg.com/filter-obj/-/filter-obj-2.0.1.tgz#34d9f0536786f072df7aeac3a8bda1c6e767aec6", + "in-array@0.1.2": "https://registry.yarnpkg.com/in-array/-/in-array-0.1.2.tgz#1a2683009177ab914ade0620a35c5039851f3715", + "is-number@7.0.0": "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b", + "map-obj@4.1.0": "https://registry.yarnpkg.com/map-obj/-/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" }, "files": [], "artifacts": {} diff --git a/src/test/fixtures/yarnWorkspaces/yarn.lock b/src/test/fixtures/yarnWorkspaces/yarn.lock index 0aec7b78..8dcbbab5 100644 --- a/src/test/fixtures/yarnWorkspaces/yarn.lock +++ b/src/test/fixtures/yarnWorkspaces/yarn.lock @@ -2,27 +2,27 @@ # yarn lockfile v1 -curry@*: +curry@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/curry/-/curry-1.2.0.tgz#9e6dd289548dba7e653d5ae3fe903fe7dfb33af2" integrity sha1-nm3SiVSNun5lPVrj/pA/59+zOvI= -filter-obj@^2.0.1: +filter-obj@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-2.0.1.tgz#34d9f0536786f072df7aeac3a8bda1c6e767aec6" integrity sha512-yDEp513p7+iLdFHWBVdZFnRiOYwg8ZqmpaAiZCMjzqsbo7tCS4Qm4ulXOht337NGzkukKa9u3W4wqQ9tQPm3Ug== -in-array@*: +in-array@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/in-array/-/in-array-0.1.2.tgz#1a2683009177ab914ade0620a35c5039851f3715" integrity sha1-GiaDAJF3q5FK3gYgo1xQOYUfNxU= -is-number@*: +is-number@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -map-obj@^4.1.0: +map-obj@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" integrity sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g== diff --git a/src/test/package.test.ts b/src/test/package.test.ts index 38a45b0f..df26cc95 100644 --- a/src/test/package.test.ts +++ b/src/test/package.test.ts @@ -223,7 +223,8 @@ describe('collect', function () { it('should collect the right files when using yarn workspaces', async () => { // PackageB will act as the extension here - const cwd = path.join(fixture('yarnWorkspaces'), 'packageB'); + const root = fixture('yarnWorkspaces'); + const cwd = path.join(root, 'packageB'); const manifest = await readManifest(cwd); assert.equal(manifest.name, 'package-b'); @@ -233,25 +234,37 @@ describe('collect', function () { [ { path: 'extension/main.js', + localPath: path.resolve(cwd, 'main.js') }, { path: 'extension/package.json', + localPath: path.resolve(cwd, 'package.json') }, { path: 'extension/node_modules/package-a/main.js', + localPath: path.resolve(root, 'node_modules/package-a/main.js') }, { path: 'extension/node_modules/package-a/package.json', + localPath: path.resolve(root, 'node_modules/package-a/package.json') }, { path: 'extension/node_modules/curry/curry.js', + localPath: path.resolve(root, 'node_modules/curry/curry.js') }, { path: 'extension/node_modules/curry/package.json', + localPath: path.resolve(root, 'node_modules/curry/package.json') + } + ].forEach(expected => { + const found = files.find(f => f.path === expected.path || f.localPath === expected.localPath); + if (found) { + assert.equal(found.path, expected.path, 'path'); + assert.equal(found.localPath, expected.localPath, 'localPath'); } - ].forEach(file => { - assert.ok(files.some(f => f.path === file.path), file.path); }) + const ignore = files.find(f => f.path === 'extension/node_modules/package-a/output.log'); + assert.ok(!ignore, 'should ignore ' + ignore.path) }) }); From 8286a91373dff6d5e0153cad72923fdbaad18a4b Mon Sep 17 00:00:00 2001 From: Sebastiaan Brouwer Date: Tue, 23 Jun 2020 10:18:28 +0200 Subject: [PATCH 5/8] test: skip ignore files for now --- src/test/package.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/package.test.ts b/src/test/package.test.ts index df26cc95..3f35bdc8 100644 --- a/src/test/package.test.ts +++ b/src/test/package.test.ts @@ -263,8 +263,6 @@ describe('collect', function () { assert.equal(found.localPath, expected.localPath, 'localPath'); } }) - const ignore = files.find(f => f.path === 'extension/node_modules/package-a/output.log'); - assert.ok(!ignore, 'should ignore ' + ignore.path) }) }); From 5dffd3d502ba3aca3201b6f882958ada91fd4395 Mon Sep 17 00:00:00 2001 From: Sebastiaan Brouwer Date: Wed, 7 Oct 2020 10:52:36 +0200 Subject: [PATCH 6/8] fix circular depPath resolving problem --- package.json | 2 +- src/npm.ts | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 06ba2597..7ed93b90 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "commander": "^2.8.1", "denodeify": "^1.2.1", "find-yarn-workspace-root": "^2.0.0", - "glob": "^7.0.6", + "glob": "^7.0.6", "leven": "^3.1.0", "lodash": "^4.17.15", "markdown-it": "^10.0.0", diff --git a/src/npm.ts b/src/npm.ts index 4f60ae1e..39f92f16 100644 --- a/src/npm.ts +++ b/src/npm.ts @@ -86,11 +86,11 @@ export interface SourceAndDestination { } async function asYarnDependencies(root: string, rootDependencies: string[]): Promise { - const resolve = async (prefix: string, dependencies: string[]): Promise => await Promise.all(dependencies + const resolve = async (prefix: string, dependencies: string[], collected: Map = new Map()): Promise => await Promise.all(dependencies .map(async (name: string) => { let newPrefix = prefix, depPath = null, depManifest = null; while (!depManifest && root.length <= newPrefix.length) { - depPath = path.join(newPrefix, 'node_modules', name); + depPath = path.join(newPrefix, 'node_modules', name); try { depManifest = await readNodeManifest(depPath); } @@ -101,15 +101,20 @@ async function asYarnDependencies(root: string, rootDependencies: string[]): Pro } } } - const children = await resolve(depPath, Object.keys(depManifest.dependencies || {})); - return { + const result = { name, path: { src: depPath, dest: path.relative(root, depPath), }, - children, + children: [], }; + const shouldResolveChildren = !collected.has(depPath); + collected.set(depPath, result); + if (shouldResolveChildren) { + result.children = await resolve(depPath, Object.keys(depManifest.dependencies || {}), collected); + } + return result; })); return resolve(root, rootDependencies); } From ebc6e622551f1227719233a830e7ffdd2e2d9858 Mon Sep 17 00:00:00 2001 From: Sebastiaan Brouwer Date: Wed, 3 Mar 2021 15:10:40 +0100 Subject: [PATCH 7/8] yarn workspaces test for .vscodeignore functionality --- .../fixtures/yarnWorkspaces/packageA/important/prod.log | 1 + src/test/fixtures/yarnWorkspaces/packageA/logger.log | 1 + src/test/fixtures/yarnWorkspaces/packageB/.vscodeignore | 5 +++++ src/test/package.test.ts | 7 +++++++ 4 files changed, 14 insertions(+) create mode 100644 src/test/fixtures/yarnWorkspaces/packageA/important/prod.log create mode 100644 src/test/fixtures/yarnWorkspaces/packageA/logger.log create mode 100644 src/test/fixtures/yarnWorkspaces/packageB/.vscodeignore diff --git a/src/test/fixtures/yarnWorkspaces/packageA/important/prod.log b/src/test/fixtures/yarnWorkspaces/packageA/important/prod.log new file mode 100644 index 00000000..6bfe6b19 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/packageA/important/prod.log @@ -0,0 +1 @@ +log diff --git a/src/test/fixtures/yarnWorkspaces/packageA/logger.log b/src/test/fixtures/yarnWorkspaces/packageA/logger.log new file mode 100644 index 00000000..6bfe6b19 --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/packageA/logger.log @@ -0,0 +1 @@ +log diff --git a/src/test/fixtures/yarnWorkspaces/packageB/.vscodeignore b/src/test/fixtures/yarnWorkspaces/packageB/.vscodeignore new file mode 100644 index 00000000..20e9ce5b --- /dev/null +++ b/src/test/fixtures/yarnWorkspaces/packageB/.vscodeignore @@ -0,0 +1,5 @@ +# pattern of file name +../node_modules/package-a/*.log + +# include files using negate +!../node_modules/package-a/important diff --git a/src/test/package.test.ts b/src/test/package.test.ts index 4dba02ea..60112462 100644 --- a/src/test/package.test.ts +++ b/src/test/package.test.ts @@ -282,6 +282,10 @@ describe('collect', function () { path: 'extension/node_modules/package-a/package.json', localPath: path.resolve(root, 'node_modules/package-a/package.json') }, + { + path: 'extension/node_modules/package-a/important/prod.log', + localPath: path.resolve(root, 'node_modules/package-a/important/prod.log') + }, { path: 'extension/node_modules/curry/curry.js', localPath: path.resolve(root, 'node_modules/curry/curry.js') @@ -297,6 +301,9 @@ describe('collect', function () { assert.equal(found.localPath, expected.localPath, 'localPath'); } }) + const ignoreFilename = 'extension/node_modules/package-a/logger.log'; + const ignore = files.find(f => f.path === ignoreFilename); + assert.ok(!ignore, 'should ignore ' + ignoreFilename) }) }); From 2eda166f0d33d5d8665398cc23b4c76e0fa89023 Mon Sep 17 00:00:00 2001 From: Sebastiaan Brouwer Date: Wed, 3 Mar 2021 16:17:27 +0100 Subject: [PATCH 8/8] support yarn detection as well --- src/npm.ts | 12 ++++++------ src/test/package.test.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/npm.ts b/src/npm.ts index 55c25763..46b0d0a7 100644 --- a/src/npm.ts +++ b/src/npm.ts @@ -184,8 +184,7 @@ async function getYarnProductionDependencies(root: string, manifest: Manifest, p return result; } -async function getYarnDependencies(cwd: string, manifest: Manifest, packagedDependencies?: string[]): Promise { - const root = findWorkspaceRoot(cwd) || cwd; +async function getYarnDependencies(cwd: string, root: string, manifest: Manifest, packagedDependencies?: string[]): Promise { const result: SourceAndDestination[] = [{ src: cwd, dest: '' @@ -203,9 +202,9 @@ async function getYarnDependencies(cwd: string, manifest: Manifest, packagedDepe return _.uniqBy(result, 'src'); } -export async function detectYarn(cwd: string) { +export async function detectYarn(root: string) { for (const file of ['yarn.lock', '.yarnrc']) { - if (await exists(path.join(cwd, file))) { + if (await exists(path.join(root, file))) { if (!process.env['VSCE_TESTS']) { log.info( `Detected presence of ${file}. Using 'yarn' instead of 'npm' (to override this pass '--no-yarn' on the command line).` @@ -223,8 +222,9 @@ export async function getDependencies( useYarn?: boolean, packagedDependencies?: string[] ): Promise { - return (useYarn !== undefined ? useYarn : await detectYarn(cwd)) - ? await getYarnDependencies(cwd, manifest, packagedDependencies) + const root = findWorkspaceRoot(cwd) || cwd; + return (useYarn !== undefined ? useYarn : await detectYarn(root)) + ? await getYarnDependencies(cwd, root, manifest, packagedDependencies) : await getNpmDependencies(cwd); } diff --git a/src/test/package.test.ts b/src/test/package.test.ts index 60112462..130f278d 100644 --- a/src/test/package.test.ts +++ b/src/test/package.test.ts @@ -263,7 +263,7 @@ describe('collect', function () { assert.equal(manifest.name, 'package-b'); - const files = await collect(manifest, { cwd, useYarn: true }) as ILocalFile[]; + const files = await collect(manifest, { cwd }) as ILocalFile[]; [ {