Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Gluegun #32

Closed
wants to merge 4 commits into from
Closed
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
10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
*.log
.DS_Store
node_modules
.rts2_cache_cjs
.rts2_cache_es
.rts2_cache_umd
dist
npm-debug.log
coverage
.nyc_output
dist
build
16 changes: 16 additions & 0 deletions __tests__/cli-integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const { system, filesystem } = require('gluegun')

const src = filesystem.path(__dirname, '..')

const cli = async cmd =>
system.run('node ' + filesystem.path(src, 'bin', 'tsdx') + ` ${cmd}`)

test('outputs version', async () => {
const output = await cli('--version')
expect(output).toContain('0.0.1')
})

test('outputs help', async () => {
const output = await cli('--help')
expect(output).toContain('0.0.1')
})
21 changes: 21 additions & 0 deletions bin/tsdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env node


/* tslint:disable */
// check if we're running in dev mode
var devMode = require('fs').existsSync(`${__dirname}/../src`)
// or want to "force" running the compiled version with --compiled-build
var wantsCompiled = process.argv.indexOf('--compiled-build') >= 0

if (wantsCompiled || !devMode) {
// this runs from the compiled javascript source
require(`${__dirname}/../build/cli`).run(process.argv)
} else {
// this runs from the typescript source (for dev only)
// hook into ts-node so we can run typescript on the fly
require('ts-node').register({
project: `${__dirname}/../tsconfig.json`
})
// run the CLI with the current process arguments
require(`${__dirname}/../src/cli`).run(process.argv)
}
3 changes: 3 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Command Reference for tsd2

TODO: Add your command reference here
49 changes: 49 additions & 0 deletions docs/plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Plugin guide for tsdx

Plugins allow you to add features to tsdx, such as commands and
extensions to the `toolbox` object that provides the majority of the functionality
used by tsd2.

Creating a tsd2 plugin is easy. Just create a repo with two folders:

```
commands/
extensions/
```

A command is a file that looks something like this:

```js
// commands/foo.js

module.exports = {
run: toolbox => {
const { print, filesystem } = toolbox

const desktopDirectories = filesystem.subdirectories(`~/Desktop`)
print.info(desktopDirectories)
}
}
```

An extension lets you add additional features to the `toolbox`.

```js
// extensions/bar-extension.js

module.exports = toolbox => {
const { print } = toolbox

toolbox.bar = () => {
print.info('Bar!')
}
}
```

This is then accessible in your plugin's commands as `toolbox.bar`.

# Loading a plugin

To load a particular plugin (which has to start with `tsd2-*`),
install it to your project using `npm install --save-dev tsd2-PLUGINNAME`,
and tsd2 will pick it up automatically.
40 changes: 30 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
{
"name": "tsdx",
"version": "0.3.2",
"license": "MIT",
"version": "0.0.1",
"description": "tsdx CLI",
"private": true,
"bin": {
"tsdx": "./dist/index.js"
"tsdx": "bin/tsdx"
},
"scripts": {
"build": "tsc -p tsconfig.json",
"prepare": "npm run build"
"format": "prettier --write **/*.{js,ts,tsx,json}",
"lint": "tslint -p .",
"compile": "tsc -p .",
"build": "yarn format && yarn lint && yarn compile",
"test": "jest",
"watch": "jest --watch",
"snapupdate": "jest --updateSnapshot",
"coverage": "jest --coverage"
},
"files": [
"dist",
"template"
"tsconfig.json",
"tslint.json",
"build",
"LICENSE",
"readme.md",
"docs",
"bin"
],
"license": "MIT",
"dependencies": {
"@babel/core": "^7.2.2",
"ansi-escapes": "^3.1.0",
Expand All @@ -25,6 +38,7 @@
"cross-env": "5.0.5",
"execa": "^1.0.0",
"fs-extra": "^7.0.1",
"gluegun": "^2.1.0",
"jest": "23.6.0",
"jpjs": "^1.2.1",
"mkdirp": "^0.5.1",
Expand All @@ -44,21 +58,27 @@
"sade": "^1.4.2",
"tiny-glob": "^0.2.6",
"ts-jest": "^23.10.5",
"ts-node": "^7.0.1",
"tslib": "^1.9.3",
"typescript": "^3.2.2"
},
"devDependencies": {
"@types/camelcase": "^4.1.0",
"@types/fs-extra": "^5.0.4",
"@types/node": "^10.12.18",
"@types/jest": "^23.3.13",
"@types/node": "^10.12.12",
"@types/rollup": "^0.54.0",
"husky": "^1.3.1",
"lint-staged": "^8.1.0",
"prettier": "^1.16.1",
"prettier": "^1.12.1",
"tslint": "^5.12.0",
"tslint-config-palmerhq": "^1.0.2",
"tslint-config-prettier": "^1.17.0",
"tslint-react": "^3.6.0"
},
"jest": {
"preset": "ts-jest",
"testEnvironment": "node"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
Expand Down
23 changes: 23 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { build } = require('gluegun')

/**
* Create the cli and kick it off
*/
async function run(argv: any) {
// create a CLI runtime
const cli = build()
.brand('tsdx')
.src(__dirname)
.plugins('./node_modules', { matching: 'tsdx-*', hidden: true })
.help() // provides default for help, h, --help, -h
.version() // provides default for version, v, --version, -v
.create()

// and run it
const toolbox = await cli.run(argv)

// send it back (for testing, mostly)
return toolbox
}

module.exports = { run }
23 changes: 23 additions & 0 deletions src/commands/generate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { GluegunToolbox } from 'gluegun'

module.exports = {
name: 'generate',
alias: ['g'],
run: async (toolbox: GluegunToolbox) => {
const {
parameters,
template: { generate },
print: { info }
} = toolbox

const name = parameters.first

await generate({
template: 'model.js.ejs',
target: `models/${name}-model.js`,
props: { name }
})

info(`Generated file at models/${name}-model.js`)
}
}
64 changes: 64 additions & 0 deletions src/commands/tsdx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { GluegunToolbox } from 'gluegun';
import { watch, RollupWatchOptions } from 'rollup';
import { createRollupConfig } from '../config/createRollupConfig';
import { CoreOptions } from '../types';

module.exports = {
name: 'tsdx',
run: async (toolbox: GluegunToolbox) => {
const {
print,
parameters: { options: rawOptions },
} = toolbox;

const options: CoreOptions = {
format: rawOptions.format || 'cjs,es,umd',
target: rawOptions.target || 'web',
name: rawOptions.name || '@todo',
watch: rawOptions.watch || false,
input: 'src/index.ts',
};

if (options.watch) {
// watch mode
const spinner = print.spin('Preparing...');
await watch(
[
createRollupConfig(
'cjs',
'production',
options
) as RollupWatchOptions,
].map(inputOptions => ({
watch: {
silent: true,
include: ['src/**'],
exclude: ['node_modules/**'],
clearScreen: true,
},
...inputOptions,
}))
).on('event', async event => {
if (event.code === 'START') {
spinner.start('Building...');
}
if (event.code === 'ERROR') {
spinner.fail(print.colors.error('Build failure'));
toolbox.logError(event.error);
}
if (event.code === 'FATAL') {
spinner.fail(print.colors.error('Build failure'));
toolbox.logError(event.error);
}
if (event.code === 'END') {
spinner.succeed('Build suceeded. Watching for changes....');
// try {
// await moveTypes();
// } catch (_error) {}
}
});
}

// const spinner = print.spin('Building...');
},
};
File renamed without changes.
File renamed without changes.
13 changes: 9 additions & 4 deletions src/createRollupConfig.js → src/config/createRollupConfig.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { safeVariableName, resolveApp, removeScope, external } from './utils';
import { paths, appPackageJson } from './constants';
import { sizeSnapshot } from 'rollup-plugin-size-snapshot';
import { terser } from 'rollup-plugin-terser';
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
Expand All @@ -10,6 +9,8 @@ import resolve from 'rollup-plugin-node-resolve';
import sourceMaps from 'rollup-plugin-sourcemaps';
import typescript from 'rollup-plugin-typescript2';
import shebangPlugin from 'rollup-plugin-preserve-shebang';
import { OutputOptions, RollupFileOptions } from 'rollup';
import { CoreOptions } from '../types';

const replacements = [{ original: 'lodash', replacement: 'lodash-es' }];

Expand All @@ -22,7 +23,11 @@ const babelOptions = {
],
};

export function createRollupConfig(format, env, opts) {
export function createRollupConfig(
format: OutputOptions['format'],
env: 'production' | 'development',
opts: CoreOptions
): RollupFileOptions {
let shebang;
return {
// Tell Rollup the entry point to the package
Expand Down Expand Up @@ -73,7 +78,7 @@ export function createRollupConfig(format, env, opts) {
jsnext: true,
browser: opts.target !== 'node',
}),
env === 'umd' &&
format === 'umd' &&
commonjs({
// use a regex to make sure to include eventual hoisted packages
include: /\/node_modules\//,
Expand All @@ -100,7 +105,7 @@ export function createRollupConfig(format, env, opts) {
'process.env.NODE_ENV': JSON.stringify(env),
}),
sourceMaps(),
sizeSnapshot(),
// sizeSnapshot(),
env === 'production' &&
terser({
sourcemap: true,
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/utils.js → src/config/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'fs-extra';
import path from 'path';
import camelCase from 'camelcase';
import path from 'path';

// Remove the package name scope if it exists
export const removeScope = name => name.replace(/^@.*\//, '');
Expand Down
Loading