Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into 4972_BUG_prevent_…
Browse files Browse the repository at this point in the history
…readdir_files

* upstream/master:
  fix(cli): Write Node4+ error message to stderr (yarnpkg#5094)
  test(jest): Upgrade jest to latest available version (yarnpkg#5018)
  fix(git): Ignores irrelevant output from ls-remote (yarnpkg#5081)
  test(integration): Fix failing react-scripts test due to unexpected
warning (yarnpkg#5076)
  feat(help) Add command descriptions to commander output (yarnpkg#5033)
  ci(circle): Fix cache key setup for proper node_modules sharing
(yarnpkg#5060)
  fixed (yarnpkg#5034)
  fix(fetcher): offline mirror name collision w/ private registries and
scopes (yarnpkg#4822)
  fix(add): Make semver flags compatible with versioned requests (yarnpkg#4999)
  [yarnpkg#5021] Add help comment to --json flag (yarnpkg#5045)
  fix(git): match git dependencies by name instead of whole url
  fix(install): connectionOptions passes in localhost as its host to
prevent popup on MacOsx. (yarnpkg#5006)
  chore(eslint): ignore packages dir (yarnpkg#4963)
  • Loading branch information
Andrew Goldis committed Dec 18, 2017
2 parents 57b156e + 0691037 commit 70e7716
Show file tree
Hide file tree
Showing 62 changed files with 1,073 additions and 527 deletions.
29 changes: 10 additions & 19 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,27 @@ attach_workspace: &attach_workspace
attach_workspace:
at: ~/project

restore_cache: &restore_cache
restore_cache:
name: Restore node_modules cache
keys:
- v1-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}
- v1-node-{{ arch }}-{{ .Branch }}-
- v1-node-{{ arch }}-

install_steps: &install_steps
steps:
- checkout
- *attach_workspace
- *restore_cache
- restore_cache:
name: Restore node_modules cache
keys:
# WARNING: add `{{ arch }}` into the keys below and separate the installation steps
# for Linux and macOS if you ever need platform-specific dependencies
# (anything using node-gyp etc.)
- v2-node-{{ .Branch }}-{{ checksum "yarn.lock" }}
- v2-node-{{ .Branch }}-
- v2-node-
- run:
name: Install Dependencies
command: yarn install --frozen-lockfile
- save_cache:
name: Save node_modules cache
key: v1-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}
key: v2-node-{{ .Branch }}-{{ checksum "yarn.lock" }}
paths:
- node_modules/
- run:
name: Remove node_modules to cleanup workspace
command: rm -r node_modules/
- persist_to_workspace:
root: ~/project
paths:
Expand All @@ -62,7 +59,6 @@ test_run: &test_run
test_steps: &test_steps
steps:
- *attach_workspace
- *restore_cache
- *test_build
- *test_run

Expand All @@ -78,15 +74,13 @@ jobs:
<<: *docker_defaults
steps:
- *attach_workspace
- *restore_cache
- run:
name: Lint
command: yarn lint
build:
<<: *docker_defaults
steps:
- *attach_workspace
- *restore_cache
- run:
name: Build distribution
command: |
Expand Down Expand Up @@ -125,7 +119,6 @@ jobs:
HOMEBREW_NO_AUTO_UPDATE=1 brew install node@8
yarn global add node-gyp
- *attach_workspace
- *restore_cache
- *test_build
- *test_run
test-macos-node6:
Expand All @@ -139,15 +132,13 @@ jobs:
brew link --force node@6
yarn global add node-gyp
- *attach_workspace
- *restore_cache
- *test_build
- *test_run

publish:
<<: *docker_defaults
steps:
- *attach_workspace
- *restore_cache
- run:
name: Publish
command: |
Expand Down
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ scripts
updates
artifacts
dist
packages
44 changes: 42 additions & 2 deletions __tests__/commands/add.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* @flow */

import type {Prompt} from 'inquirer';

import {ConsoleReporter} from '../../src/reporters/index.js';
import * as reporters from '../../src/reporters/index.js';
import {
Expand All @@ -21,6 +23,7 @@ import semver from 'semver';
import {promisify} from '../../src/util/promise';
import fsNode from 'fs';
import inquirer from 'inquirer';
import invariant from 'invariant';

jasmine.DEFAULT_TIMEOUT_INTERVAL = 150000;

Expand Down Expand Up @@ -147,6 +150,16 @@ test.concurrent('install with --optional flag', (): Promise<void> => {
});
});

test.concurrent('install with --tilde flag', (): Promise<void> => {
return runAdd(['isarray@2.0.1'], {tilde: true}, 'add-with-flag', async config => {
const lockfile = explodeLockfile(await fs.readFile(path.join(config.cwd, 'yarn.lock')));
const pkg = await fs.readJson(path.join(config.cwd, 'package.json'));

expect(lockfile.indexOf('isarray@~2.0.1:')).toEqual(0);
expect(pkg.dependencies).toEqual({isarray: '~2.0.1'});
});
});

// Test if moduleAlreadyInManifest warning is displayed
const moduleAlreadyInManifestChecker = ({expectWarnings}: {expectWarnings: boolean}) => async (
args,
Expand Down Expand Up @@ -609,6 +622,27 @@ test.concurrent('upgrade scenario 2 (with sub dependencies)', (): Promise<void>
});
});

test.concurrent('install another fork of an existing package', (): Promise<void> => {
// When installing a package with the same name as an existing one but from a different repo,
// the old one should be replaced with the new one in the lock file.
const firstSource = 'davidreis97/example-yarn-package#master';
const secondSource = 'yarnpkg/example-yarn-package#master';
const pkgName = 'example-yarn-package';
return runAdd([firstSource], {}, 'install-forked-git', async (config, reporter): Promise<void> => {
let lockfile = explodeLockfile(await fs.readFile(path.join(config.cwd, 'yarn.lock')));
expect(lockfile.indexOf(`${pkgName}@${firstSource}:`)).toEqual(0);
expect(lockfile.indexOf(`${pkgName}@${secondSource}:`)).toEqual(-1);

const add = new Add([secondSource], {}, config, reporter, await Lockfile.fromDirectory(config.cwd));
await add.init();

lockfile = explodeLockfile(await fs.readFile(path.join(config.cwd, 'yarn.lock')));

expect(lockfile.indexOf(`${pkgName}@${firstSource}:`)).toEqual(-1);
expect(lockfile.indexOf(`${pkgName}@${secondSource}:`)).toEqual(0);
});
});

test.concurrent('downgrade scenario', (): Promise<void> => {
// left-pad first installed 1.1.0 then downgraded to 0.0.9
// files in mirror, yarn.lock, package.json and node_modules should reflect that
Expand Down Expand Up @@ -801,8 +835,14 @@ test.skip('add asks for correct package version if user passes an incorrect one'
inquirer.prompt = jest.fn(questions => {
expect(questions).toHaveLength(1);
expect(questions[0].name).toEqual('package');
expect(questions[0].choices.length).toBeGreaterThan(0);
chosenVersion = questions[0].choices[0];

const choices = questions[0].choices;
invariant(Array.isArray(choices));
expect(choices.length).toBeGreaterThan(0);
invariant(choices.length > 0);
chosenVersion = choices[0];
invariant(typeof chosenVersion === 'string');
// $FlowFixMe: No sane way to return an "extended" Promise object
return Promise.resolve({package: chosenVersion});
});
},
Expand Down
53 changes: 22 additions & 31 deletions __tests__/commands/cache.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
/* @flow */

import * as reporters from '../../src/reporters/index.js';
import {JSONReporter, BufferReporter} from '../../src/reporters/index.js';
import * as fs from '../../src/util/fs.js';
import {run} from '../../src/cli/commands/cache.js';
import {run as buildRun, runInstall} from './_helpers.js';

const path = require('path');
const stream = require('stream');

const fixturesLoc = path.join(__dirname, '..', 'fixtures', 'cache');

jasmine.DEFAULT_TIMEOUT_INTERVAL = 150000;

const runCache = buildRun.bind(
null,
reporters.JSONReporter,
JSONReporter,
fixturesLoc,
async (args, flags, config, reporter, lockfile, getStdout): Promise<string> => {
await run(config, reporter, flags, args);
Expand All @@ -22,87 +23,79 @@ const runCache = buildRun.bind(

test('list', async (): Promise<void> => {
await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {
const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();
await run(config, reporter, {}, ['list']);
const stdout = String(out.read());
const stdout = reporter.getBufferText();
expect(stdout).toContain('dummy');
expect(stdout).toContain('0.0.0');
});
});

test('ls with scoped package', async (): Promise<void> => {
await runInstall({}, 'install-from-authed-private-registry', async (config): Promise<void> => {
const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();
await run(config, reporter, {}, ['list']);
const stdout = String(out.read());
const stdout = reporter.getBufferText();
expect(stdout).toContain('@types/lodash');
expect(stdout).toContain('4.14.37');
});
});

test('ls with filter that matches cache', async (): Promise<void> => {
await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {
const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();
await run(config, reporter, {pattern: 'dummy'}, ['list']);
const stdout = String(out.read());
const stdout = reporter.getBufferText();
expect(stdout).toContain('dummy');
expect(stdout).toContain('0.0.0');
});
});

test('ls with filter that matches cache with wildcard', async (): Promise<void> => {
await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {
const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();
await run(config, reporter, {pattern: 'dum*'}, ['list']);
const stdout = String(out.read());
const stdout = reporter.getBufferText();
expect(stdout).toContain('dummy');
expect(stdout).toContain('0.0.0');
});
});

test('ls with multiple patterns, one matching', async (): Promise<void> => {
await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {
const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();
await run(config, reporter, {pattern: 'dum|dummy'}, ['list']);
const stdout = String(out.read());
const stdout = reporter.getBufferText();
expect(stdout).toContain('dummy');
expect(stdout).toContain('0.0.0');
});
});

test('ls with pattern that only partially matches', async (): Promise<void> => {
await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {
const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();
await run(config, reporter, {pattern: 'dum'}, ['list']);
const stdout = String(out.read());
const stdout = reporter.getBufferText();
expect(stdout).toContain('dummy');
expect(stdout).toContain('0.0.0');
});
});

test('ls with filter that does not match', async (): Promise<void> => {
await runInstall({}, 'artifacts-finds-and-saves', async (config): Promise<void> => {
const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();
await run(config, reporter, {pattern: 'noMatch'}, ['list']);
const stdout = String(out.read());
const stdout = reporter.getBufferText();
expect(stdout).not.toContain('dummy');
expect(stdout).not.toContain('0.0.0');
});
});

test('ls filter by pattern with scoped package', async (): Promise<void> => {
await runInstall({}, 'install-from-authed-private-registry', async (config): Promise<void> => {
const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();
await run(config, reporter, {pattern: '@types/*'}, ['list']);
const stdout = String(out.read());
const stdout = reporter.getBufferText();
expect(stdout).toContain('@types/lodash');
expect(stdout).toContain('4.14.37');
});
Expand All @@ -126,8 +119,7 @@ test('clean', async (): Promise<void> => {
// an install script.
expect(files.length).toEqual(3);

const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();
await run(config, reporter, {}, ['clean']);

expect(await fs.exists(config.cacheFolder)).toBeTruthy();
Expand All @@ -142,8 +134,7 @@ test('clean with package name', async (): Promise<void> => {
let files = await fs.readdir(config.cacheFolder);
expect(files.length).toEqual(3);

const out = new stream.PassThrough();
const reporter = new reporters.JSONReporter({stdout: out});
const reporter = new BufferReporter();

await run(config, reporter, {}, ['clean', 'unknownname']);
expect(await fs.exists(config.cacheFolder)).toBeTruthy();
Expand Down
44 changes: 44 additions & 0 deletions __tests__/fetchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,47 @@ test('TarballFetcher.fetch properly stores tarball of scoped package in offline
const exists = await fs.exists(path.join(offlineMirrorDir, '@exponent-configurator-1.0.2.tgz'));
expect(exists).toBe(true);
});

test('TarballFetcher.fetch properly stores tarball for scoped package resolved from artifactory registry', async () => {
const dir = await mkdir('tarball-fetcher');
const offlineMirrorDir = await mkdir('offline-mirror');

const config = await Config.create();
config.registries.npm.config['yarn-offline-mirror'] = offlineMirrorDir;

const fetcher = new TarballFetcher(
dir,
{
type: 'tarball',
hash: '6f0ab73cdd7b82d8e81e80838b49e9e4c7fbcc44',
reference:
'https://artifactory.internal.site:443/artifactory/api/npm/external-mirror/@exponent/configurator/-/configurator-1.0.2.tgz',
registry: 'npm',
},
config,
);

expect(fetcher.getTarballMirrorPath()).toBe(path.join(offlineMirrorDir, '@exponent-configurator-1.0.2.tgz'));
});

test('TarballFetcher.fetch properly stores tarball for scoped package resolved from new style URLs', async () => {
const dir = await mkdir('tarball-fetcher');
const offlineMirrorDir = await mkdir('offline-mirror');

const config = await Config.create();
config.registries.npm.config['yarn-offline-mirror'] = offlineMirrorDir;

const fetcher = new TarballFetcher(
dir,
{
type: 'tarball',
hash: '6f0ab73cdd7b82d8e81e80838b49e9e4c7fbcc44',
reference:
'https://artifactory.internal.site:443/artifactory/api/npm/external-mirror/@exponent/configurator/-/@exponent/configurator-1.0.2.tgz',
registry: 'npm',
},
config,
);

expect(fetcher.getTarballMirrorPath()).toBe(path.join(offlineMirrorDir, '@exponent-configurator-1.0.2.tgz'));
});
6 changes: 6 additions & 0 deletions __tests__/fixtures/add/install-forked-git/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "install-forked-git",
"version": "1.0.0",
"main": "index.js",
"license": "MIT"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
var fs = require('fs');
fs.writeFileSync('dummy.txt', 'foobar');
if (!fs.existsSync('dummy')) {
fs.mkdirSync('dummy');
}
fs.writeFileSync('dummy/dummy.txt', 'foobar');
const fs = require('fs');
const util = require('util');

const thrower = (err) => {
if (err) {
throw err;
}
};

fs.writeFile('dummy.txt', 'foobar', thrower);
fs.mkdir('dummy', err => {
if (err && err.code !== 'EEXIST')
throw err;
fs.writeFile('dummy/dummy.txt', 'foobar', thrower)
});
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit 70e7716

Please sign in to comment.