diff --git a/package.json b/package.json index caf6ac5..2c70cc1 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "license": "MIT", "main": "./lib/CLI.js", "typings": "./lib/index.d.ts", - "version": "2.0.0-alpha-4", + "version": "2.0.0-alpha-5", "dependencies": { "chalk": "^2.3.0" }, diff --git a/src/Chest.spec.ts b/src/Chest.spec.ts index 0583953..9444af7 100644 --- a/src/Chest.spec.ts +++ b/src/Chest.spec.ts @@ -35,26 +35,29 @@ describe('when using RootProject to load a project', () => { expect(projects[0].owner).to.not.equal(undefined) }) - it('should return static InvalidProject when single project does not exist', async () => { + it('should return static InvalidProject when single project does not exist', () => { const directory = Files.join(process.cwd(), 'testables', 'nonexistant') - Chest.project(directory).then(project => Chest.projects(project).should.eventually.equal(Project.InvalidProject)) + + return Chest.project(directory).then(project => expect(project).to.equal(Project.InvalidProject)) }) - it('should throw error when workspace project has no child projects', async () => { + it('should throw error when workspace project has no child projects', () => { const directory = Files.join(process.cwd(), 'testables', 'workspaces-invalid') - Chest.project(directory).then(project => Chest.projects(project).should.eventually.throw()) + return Chest.project(directory).then(async project => { + const projects = await Chest.projects(project) + expect(projects).to.deep.equal([Project.InvalidProject]) + }) }) - it('should run scripts for single project', (done) => { + it('should run scripts for single project', () => { const directory = Files.join(process.cwd(), 'testables', 'single') const args = Object.keys(Registry.all()) - Chest.run(directory, ...args).then(() => done()) + return Chest.run(directory, ...args) }) - it('should run scripts for workspace project', (done) => { + it('should run scripts for workspace project', () => { const directory = Files.join(process.cwd(), 'testables', 'workspaces') const args = Object.keys(Registry.all()) - Chest.run(directory, ...args).then(() => done()) + return Chest.run(directory, ...args) }) - }) diff --git a/src/Chest.ts b/src/Chest.ts index bb8de3d..9ab572e 100644 --- a/src/Chest.ts +++ b/src/Chest.ts @@ -25,7 +25,7 @@ export class Chest { const npmfile = path.join(root, 'package.json') if (await Files.exists(npmfile) === false) { - Chest.Log.error(new Error(`failed to find ${npmfile} in ${root}`)) + Chest.Log.error(new Error(`failed to find ${npmfile} in [${root}]`)) return Project.InvalidProject } @@ -36,6 +36,7 @@ export class Chest { public static async projects(owner: Project): Promise { const project = await Chest.project(owner.path) const npm = await project.package + this.Log.debug('project', project.name) if (npm.private && npm.workspace) { return npm.workspace.map(workspaceRoot => Chest.workspaces(project, workspaceRoot)) @@ -49,15 +50,18 @@ export class Chest { workspaceRoot = Files.join(owner.path, workspaceRoot.substring(0, workspaceRoot.indexOf('/*'))) if (await Files.exists(workspaceRoot) === false) { - throw new Error(`failed to find workspace ${workspaceRoot} in ${owner.name}`) + Chest.Log.error(new Error(`[workspace] failed to find ${workspaceRoot} in [${owner.name}]`)) + return [Project.InvalidProject] } const projects = await Files.listdirs(workspaceRoot) - return Promise.all(projects.map(async project => { - const npmfile = path.join(project, 'package.json') + return Promise.all(projects.map(async projectPath => { + const npmfile = path.join(projectPath, 'package.json') const npm = await Files.json(npmfile) - return new Project(npm.name, project, owner) + const project = new Project(npm.name, projectPath, owner) + this.Log.debug('project.workspace', owner.name, '->', project.name) + return project })) } } diff --git a/src/Core/Actions/Typings.ts b/src/Core/Actions/Typings.ts index ddaeb8d..f9cb509 100644 --- a/src/Core/Actions/Typings.ts +++ b/src/Core/Actions/Typings.ts @@ -25,12 +25,17 @@ class Script extends UpdateScript { public async exec(rootpath: string): Promise { const tsconfigfile = path.join(rootpath, 'tsconfig.json') const packagedir = path.join(rootpath, 'node_modules') + this.log.debug('exec', this.name, rootpath, packagedir) if (await Files.exists(tsconfigfile) && await Files.exists(packagedir)) { const packagedirs = await Files.listdirs(packagedir) const tsconfig = await Files.json(tsconfigfile) - const dependencies = await Promise.all(packagedirs.map(async packagedir => await this.map(packagedir))) + const dependencies = await Promise.all(packagedirs.map(packagedir => { + this.log.debug('dependencies', packagedir) + return this.dependencies(packagedir) + })) + const typings = dependencies.reduce((previous, current) => previous.concat(current.filter(c => !!c.typings)), []) tsconfig.compilerOptions.types = typings.map(typing => typing.npmname).sort() @@ -44,13 +49,13 @@ class Script extends UpdateScript { } } - private async map(packagedir: string): Promise { + private async dependencies(packagedir: string): Promise { const dirname = path.basename(packagedir) if (dirname[0] === '@') { const scopedirs = await Files.listdirs(packagedir) - return await Promise.all(scopedirs + return Promise.all(scopedirs .map(scope => [scope, path.join(scope, 'package.json')]) .map(async ([scope, scopepath]): Promise => { const npm = await Files.json(path.join(scope, 'package.json')) diff --git a/src/Core/Files.spec.ts b/src/Core/Files.spec.ts index e652c53..259227c 100644 --- a/src/Core/Files.spec.ts +++ b/src/Core/Files.spec.ts @@ -7,7 +7,7 @@ import { Files } from './Files' const expect = chai.expect -describe('', () => { +describe('when working with files', () => { before(async () => { const artifacts = Files.join(process.cwd(), 'artifacts') @@ -21,7 +21,7 @@ describe('', () => { it('should write file', () => { const filename = Files.join(process.cwd(), 'artifacts', 'test.json') - Files.writefile(filename, {}).should.eventually.not.throw() + return Files.writefile(filename, {}) }) }) diff --git a/src/Core/Registry.spec.ts b/src/Core/Registry.spec.ts index b6bd4ad..ff4cc79 100644 --- a/src/Core/Registry.spec.ts +++ b/src/Core/Registry.spec.ts @@ -1,14 +1,12 @@ import 'mocha' -import * as chai from 'chai' -import * as chaiAsPromised from 'chai-as-promised' +import { expect } from 'chai' import { Files } from './Files' import { UpdaterType } from './Interfaces' import { Registry } from './Registry' import { UpdateScript } from './UpdateScript' -const expect = chai.expect const ScriptName = Files.extensionless(__filename) const RootScriptName = `${ScriptName}-root` const ProjectsScriptName = `${ScriptName}-projects` @@ -25,12 +23,7 @@ class DoesNothingGoesNowhereProjects extends UpdateScript { } } -describe('', () => { - - beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) - }) +describe('when using the script registry', () => { it('should return registered script names', () => { expect(Registry.names().length).to.be.gt(0) @@ -44,7 +37,6 @@ describe('', () => { }) it('should throw error when calling "get" and script does not exist', () => { - expect(() => Registry.get('invalid')).to.throw(Error) + expect(() => Registry.get('invalid')).to.throw() }) - }) diff --git a/src/Core/UpdateScript.ts b/src/Core/UpdateScript.ts index 46d8150..d5b53cf 100644 --- a/src/Core/UpdateScript.ts +++ b/src/Core/UpdateScript.ts @@ -48,11 +48,14 @@ export abstract class UpdateScript implements Updater { protected run(project: Project, command: string, ...args: string[]): Promise { return new Promise((resolve, reject) => { this.log.debug('run', project.name, command, ...args) + const child = cp.exec(`${command} ${args.join(' ')}`, { cwd: project.path }, error => { if (error) this.log.error(error) }) + child.stderr.on('data', data => this.args(project, process.stderr, data).map(lines => lines).forEach(args => this.log.error(...args))) child.stdout.on('data', data => this.args(project, process.stdout, data).map(lines => lines).forEach(args => this.log.task(...args))) + child.addListener('exit', (code: number, signal: string) => { if (code === 0) { resolve() diff --git a/testables/single/tsconfig.json b/testables/single/tsconfig.json new file mode 100644 index 0000000..875cb60 --- /dev/null +++ b/testables/single/tsconfig.json @@ -0,0 +1,3 @@ +{ + "compilerOptions": {} +} diff --git a/testables/workspaces-invalid/package.json b/testables/workspaces-invalid/package.json index 9d1a800..097624d 100644 --- a/testables/workspaces-invalid/package.json +++ b/testables/workspaces-invalid/package.json @@ -7,6 +7,7 @@ "@types/chalk": "*" }, "name": "project-single", + "private": true, "version": "1.0.0", "workspace": [ "packages/*" diff --git a/testables/workspaces-invalid/tsconfig.json b/testables/workspaces-invalid/tsconfig.json new file mode 100644 index 0000000..875cb60 --- /dev/null +++ b/testables/workspaces-invalid/tsconfig.json @@ -0,0 +1,3 @@ +{ + "compilerOptions": {} +} diff --git a/testables/workspaces/packages/simple-package/tsconfig.json b/testables/workspaces/packages/simple-package/tsconfig.json new file mode 100644 index 0000000..875cb60 --- /dev/null +++ b/testables/workspaces/packages/simple-package/tsconfig.json @@ -0,0 +1,3 @@ +{ + "compilerOptions": {} +} diff --git a/testables/workspaces/projects/simple-project/tsconfig.json b/testables/workspaces/projects/simple-project/tsconfig.json new file mode 100644 index 0000000..875cb60 --- /dev/null +++ b/testables/workspaces/projects/simple-project/tsconfig.json @@ -0,0 +1,3 @@ +{ + "compilerOptions": {} +} diff --git a/testables/workspaces/tsconfig.json b/testables/workspaces/tsconfig.json new file mode 100644 index 0000000..875cb60 --- /dev/null +++ b/testables/workspaces/tsconfig.json @@ -0,0 +1,3 @@ +{ + "compilerOptions": {} +}