Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 11 additions & 16 deletions src/Chest.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import { Log, Logger, Project, Registry, UpdaterType } from './Core'
import { Log, Logger, Project, Registry } from './Core'

export class Chest {
private static readonly log: Log = Logger('chest')

public static async run(root: string, ...args: string[]): Promise<void> {
Chest.log.debug('run', root, ...args)

const project = await Project.load(root)
public static run(cwd: string, ...args: string[]): Promise<void> {
Chest.log.info('run', cwd, ...args)
const updaters = Registry.all()

Object.keys(updaters)
.filter(key => args.some(arg => arg.toLowerCase() === key.toLowerCase()))
.map(async name => {
const updater = updaters[name]

if (updater.type === UpdaterType.Root) {
await updater.exec(root)
} else {
await Promise.all(project.children.map(child => updater.workspace(child)))
}
})
return Project.load(cwd)
.then(project => Promise.all(
Object.keys(updaters)
.filter(scriptname => args.some(arg => arg.toLowerCase() === scriptname.toLowerCase()))
.map(scriptname => updaters[scriptname])
.map(script => script.exec(project).then(proj => Chest.log.task('done', '[project]', proj.name)))
))
.then(() => Chest.log.done('done', cwd, args))
}
}
49 changes: 23 additions & 26 deletions src/Core/Actions/Packages.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as path from 'path'

import { Files, NPM, Project, Registry, UpdateScript, UpdaterType } from '../index'
import { Files, NPM, Project, Registry, UpdateScript } from '../index'

/*
* Propogates changes from the root package.json to child
Expand All @@ -10,33 +10,30 @@ class Script extends UpdateScript {
public static readonly Name: string = Files.extensionless(__filename)

constructor() {
super(Script.Name, UpdaterType.Projects)
super(Script.Name)
}

public async workspace(project: Project): Promise<Project> {
if (project.owner) {
const source = await project.owner.npm
const target = await project.npm

target.author = source.author
target.bugs = source.bugs
target.description = source.description
target.homepage = source.homepage
target.license = source.license
target.repository = source.repository

const filename = path.join(project.path, 'package.json')

if (this.testing) {
/* istanbul ignore next */
this.log.task('workspace', filename, JSON.stringify(target, null, 2))
} else {
await Files.save(filename, target)
this.log.task('workspace', filename)
}
}

return project
protected workspace(project: Project): Promise<Project> {
return super.workspace(project)
.then(async () => {
if (project.owner) {
const source = await project.owner.npm
const target = await project.npm

target.author = source.author
target.bugs = source.bugs
target.description = source.description
target.homepage = source.homepage
target.license = source.license
target.repository = source.repository

const filename = path.join(project.path, 'package.json')
await Files.save(filename, target)
this.log.task('workspace', filename)
}

return project
})
}
}

Expand Down
24 changes: 15 additions & 9 deletions src/Core/Actions/Typings.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'mocha'

import { expect } from 'chai'
import { Files, Registry, TypeScriptOptions } from '../index'
import { Files, Project, Registry, TypeScriptOptions } from '../index'

const TIMEOUT = 5000

const testables = Files.join(process.cwd(), 'testables')
const single = Files.join(testables, 'single')
Expand All @@ -11,16 +13,20 @@ describe('when collecting type declarations', () => {

it('should execute single', () => {
const script = Registry.get('typings')
return script.exec(single)
.then(project => project.json<TypeScriptOptions>('tsconfig.json'))
.then(json => expect(json.compilerOptions.types).to.contain('chalk'))
})
return Project.load(single).then(project =>
script.exec(project)
.then(project => project.json<TypeScriptOptions>('tsconfig.json'))
.then(json => expect(json.compilerOptions.types).to.contain('chalk'))
)
}).timeout(TIMEOUT)

it('should execute workspaces', () => {
const script = Registry.get('typings')
return script.exec(workspaces)
.then(project => project.json<TypeScriptOptions>('tsconfig.json'))
.then(json => expect(json.compilerOptions.types).to.contain('chalk'))
})
return Project.load(workspaces).then(project =>
script.exec(project)
.then(project => project.json<TypeScriptOptions>('tsconfig.json'))
.then(json => expect(json.compilerOptions.types).to.contain('chalk'))
)
}).timeout(TIMEOUT)

})
17 changes: 8 additions & 9 deletions src/Core/Actions/Typings.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Files, NPM, Project, Registry, TypeScriptOptions, UpdateScript, UpdaterType } from '../index'
import { Files, NPM, Project, Registry, TypeScriptOptions, UpdateScript } from '../index'

/*
* Updates the "types" property of "tsconfig.json" files by
Expand All @@ -8,16 +8,15 @@ class Script extends UpdateScript {
public static Name = Files.extensionless(__filename)

constructor() {
super(Script.Name, UpdaterType.Root)
super(Script.Name)
}

public exec(rootpath: string): Promise<Project> {
return Project.load(rootpath)
.then(project =>
this.declarations([project, ...project.children])
.then(typings => this.typings(project, typings))
.then(() => project)
)
public exec(project: Project): Promise<Project> {
return super.exec(project).then(project =>
this.declarations([project, ...project.children])
.then(typings => this.typings(project, typings))
.then(() => project)
)
}

private declarations(projects: Project[]): Promise<string[]> {
Expand Down
13 changes: 9 additions & 4 deletions src/Core/Actions/Yarn.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { UpdaterType } from '../Interfaces'
import { Project } from '../Project'
import { Registry } from '../Registry'
import { UpdateScript } from '../UpdateScript'
Expand All @@ -7,11 +6,17 @@ export class Yarn extends UpdateScript {
public static readonly Name: string = 'yarn'

constructor() {
super(Yarn.Name, UpdaterType.Root)
super(Yarn.Name)
}

public exec(rootpath: string): Promise<Project> {
return Project.load(rootpath).then(project => this.run(project, 'yarn').then(() => project))
public exec(project: Project): Promise<Project> {
return super.exec(project)
.then(project => this.run(project, 'yarn').then(() => project))
}

protected workspace(project: Project): Promise<Project> {
return super.exec(project)
.then(project => this.run(project, 'yarn').then(() => project))
}
}

Expand Down
31 changes: 14 additions & 17 deletions src/Core/Files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface Stat {
}

class InternalFiles {
private readonly log: Log = Logger('files')
private readonly log: Log = Logger('chest:files')

public basename(filepath: string): string {
return path.basename(filepath)
Expand Down Expand Up @@ -50,13 +50,12 @@ class InternalFiles {
return path.join(...args)
}

public async json<T>(filepath: string): Promise<T> {
if (await this.exists(filepath)) {
const buffer = await this.readfile(filepath)
return JSON.parse(buffer.toString())
}

throw new Error(`requested file ${filepath} does not exist`)
public json<T>(filepath: string): Promise<T> {
return this.exists(filepath).then(exists => {
return exists
? this.readfile(filepath).then(buffer => JSON.parse(buffer.toString()))
: Promise.reject(new Error(`requested file ${filepath} does not exist`))
})
}

public readfile(filepath: string): Promise<Buffer> {
Expand All @@ -72,14 +71,12 @@ class InternalFiles {
})
}

public async listdirs(filepath: string): Promise<string[]> {
const stats = await this.statfiles(filepath)
return stats.filter(stat => stat.dir).map(stat => stat.filename)
public listdirs(filepath: string): Promise<string[]> {
return this.statfiles(filepath).then(stats => stats.filter(stat => stat.dir).map(stat => stat.filename))
}

public async listfiles(filepath: string): Promise<string[]> {
const stats = await this.statfiles(filepath)
return stats.filter(stat => stat.file).map(stat => stat.filename)
public listfiles(filepath: string): Promise<string[]> {
return this.statfiles(filepath).then(stats => stats.filter(stat => stat.file).map(stat => stat.filename))
}

public mkdir(filepath: string): Promise<void> {
Expand All @@ -94,11 +91,11 @@ class InternalFiles {
})
}

public async save<T>(filepath: string, data: T): Promise<void> {
await this.writefile(filepath, JSON.stringify(data, null, 2))
public save<T>(filepath: string, data: T): Promise<void> {
return this.writefile(filepath, JSON.stringify(data, null, 2))
}

public async statfile(filepath: string): Promise<fs.Stats> {
public statfile(filepath: string): Promise<fs.Stats> {
return new Promise<fs.Stats>((resolve, reject) => {
fs.stat(filepath, (error: NodeJS.ErrnoException, stats: fs.Stats) => {
if (error) {
Expand Down
5 changes: 1 addition & 4 deletions src/Core/Interfaces/Updater.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { UpdaterType } from './UpdaterType'
import { Project } from '../Project'

export interface Updater {
name: string
type: UpdaterType
exec(rootpath: string): Promise<Project>
workspace(project: Project): Promise<Project>
exec(project: Project): Promise<Project>
}

export type Updaters = {
Expand Down
4 changes: 0 additions & 4 deletions src/Core/Interfaces/UpdaterType.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/Core/Interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ export * from './Dictionary'
export * from './NPM'
export * from './TypeScriptOptions'
export * from './Updater'
export * from './UpdaterType'
4 changes: 2 additions & 2 deletions src/Core/Logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ export function Logger(name: string, category?: string): Log {
const bold = (name: string) => chalk.default.bold(`[${name}${cat}]`)

const log = (...args: any[]) => {
if (process.env.DEBUG) {
if (process.env.DEBUG && process.env.NODE_ENV === 'development') {
console.log(...args)
}
}

return {
debug: (...args: any[]): void => {
log(chalk.default.yellow.inverse(bold(name), ...args))
log(chalk.default.yellow(bold(name), ...args))
},
error: (...args: any[]): void => {
log(chalk.default.red.inverse(bold(name), ...args))
Expand Down
9 changes: 2 additions & 7 deletions src/Core/Registry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'mocha'
import { expect } from 'chai'

import { Files } from './Files'
import { UpdaterType } from './Interfaces'
import { Registry } from './Registry'
import { UpdateScript } from './UpdateScript'

Expand All @@ -13,13 +12,13 @@ const ProjectsScriptName = `${ScriptName}-projects`

class DoesNothingGoesNowhereRoot extends UpdateScript {
constructor() {
super(RootScriptName, UpdaterType.Root)
super(RootScriptName)
}
}

class DoesNothingGoesNowhereProjects extends UpdateScript {
constructor() {
super(ProjectsScriptName, UpdaterType.Projects)
super(ProjectsScriptName)
}
}

Expand All @@ -40,8 +39,4 @@ describe('when using the script registry', () => {
expect(() => Registry.get('invalid')).to.throw()
})

it('should throw error when given unregistered scripts', () => {
expect(() => Registry.execute(process.cwd(), 'invalid')).to.throw()
})

})
5 changes: 0 additions & 5 deletions src/Core/Registry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Dictionary, Updater, Updaters } from './Interfaces'
import { Project } from './Project'

export class Registry {
private static readonly registrations: Updaters = {}
Expand All @@ -16,10 +15,6 @@ export class Registry {
return !!this.registrations[name.toLowerCase()]
}

public static execute(root: string, ...args: string[]): Promise<Project[]> {
return Promise.all(args.map(arg => arg.toLowerCase()).map(name => this.registrations[name].exec(root)))
}

public static get(name: string): Updater {
const key = name.toLowerCase()

Expand Down
39 changes: 0 additions & 39 deletions src/Core/UpdateScript.spec.ts

This file was deleted.

Loading