UNPKG

3.7 kBJavaScriptView Raw
1'use strict';
2
3const CoreObject = require('core-object');
4const fs = require('fs-extra');
5const path = require('path');
6const debug = require('debug')('ember-try:dependency-manager-adapter:workspaces');
7const walkSync = require('walk-sync');
8
9const NpmAdapter = require('./npm');
10
11module.exports = CoreObject.extend({
12 init() {
13 this._super.apply(this, arguments);
14 this.run = this.run || require('../utils/run');
15
16 if (!this.useYarnCommand) {
17 throw new Error(
18 'workspaces are currently only supported by Yarn, you must set `useYarn` to true'
19 );
20 }
21 let packageJSON = JSON.parse(fs.readFileSync(this.packageJSON));
22 let workspaceGlobs;
23
24 if (Array.isArray(packageJSON.workspaces)) {
25 workspaceGlobs = packageJSON.workspaces;
26 }
27
28 if (packageJSON.workspaces && Array.isArray(packageJSON.workspaces.packages)) {
29 workspaceGlobs = packageJSON.workspaces.packages;
30 }
31
32 if (!workspaceGlobs || !workspaceGlobs.length) {
33 throw new Error(
34 'you must define the `workspaces` property in package.json with at least one workspace to use workspaces with ember-try'
35 );
36 }
37
38 // workspaces is a list of globs, loop over the list and find
39 // all paths that contain a `package.json` file
40 let workspacePaths = walkSync('.', { globs: workspaceGlobs }).filter((workspacePath) => {
41 let packageJSONPath = path.join(this.cwd, workspacePath, 'package.json');
42 return fs.existsSync(packageJSONPath);
43 });
44
45 this._packageAdapters = workspacePaths.map((workspacePath) => {
46 return new NpmAdapter({
47 cwd: workspacePath,
48 run: this.run,
49 managerOptions: this.managerOptions,
50 useYarnCommand: true,
51 buildManagerOptions: this.buildManagerOptions,
52 });
53 });
54 },
55
56 packageJSON: 'package.json',
57
58 setup(options) {
59 if (!options) {
60 options = {};
61 }
62
63 return Promise.all(this._packageAdapters.map((adapter) => adapter.setup(options)));
64 },
65
66 async changeToDependencySet(depSet) {
67 // TODO: What should this do for tables? Nesting? Needs different output
68 this._packageAdapters.forEach((adapter) => {
69 adapter.applyDependencySet(depSet);
70 });
71
72 await this._install(depSet);
73 let deps = Object.assign({}, depSet.dependencies, depSet.devDependencies);
74 let currentDeps = Object.keys(deps).map((dep) => {
75 return {
76 name: dep,
77 versionExpected: deps[dep],
78 versionSeen: this._findCurrentVersionOf(dep),
79 packageManager: 'yarn',
80 };
81 });
82
83 debug('Switched to dependencies: \n', currentDeps);
84
85 return currentDeps;
86 },
87
88 cleanup() {
89 return Promise.all(this._packageAdapters.map((adapter) => adapter.cleanup()));
90 },
91
92 _install(depSet) {
93 let mgrOptions = this.managerOptions || [];
94
95 // buildManagerOptions overrides all default
96 if (typeof this.buildManagerOptions === 'function') {
97 mgrOptions = this.buildManagerOptions(depSet);
98
99 if (!Array.isArray(mgrOptions)) {
100 throw new Error('buildManagerOptions must return an array of options');
101 }
102 } else {
103 if (mgrOptions.indexOf('--no-lockfile') === -1) {
104 mgrOptions = mgrOptions.concat(['--no-lockfile']);
105 }
106 // npm warns on incompatible engines
107 // yarn errors, not a good experience
108 if (mgrOptions.indexOf('--ignore-engines') === -1) {
109 mgrOptions = mgrOptions.concat(['--ignore-engines']);
110 }
111 }
112
113 debug('Run yarn install with options %s', mgrOptions);
114
115 return this.run('yarn', ['install', ...mgrOptions], { cwd: this.cwd });
116 },
117
118 _findCurrentVersionOf(dep) {
119 return this._packageAdapters[0]._findCurrentVersionOf(dep);
120 },
121});