1 | #!/usr/bin/env node
|
2 |
|
3 | const { spawn, execSync } = require('child_process')
|
4 | const { writeFileSync } = require('fs')
|
5 | const inquirer = require('inquirer')
|
6 | const slug = require('slug')
|
7 |
|
8 | const configTemplate = require('./templates/config')
|
9 | const variablesTemplate = require('./templates/variables.scss')
|
10 | const htmlConfigTemplate = require('./templates/html.config')
|
11 |
|
12 | const DIR_PATH = process.env.PWD
|
13 |
|
14 | const DEBUGGING = process.argv.includes('--debug')
|
15 |
|
16 | const env = Object.assign(process.env, {
|
17 | DIR_PATH,
|
18 | DEBUGGING,
|
19 | })
|
20 |
|
21 | const commands = {
|
22 | init: () => {
|
23 | inquirer
|
24 | .prompt([
|
25 | {
|
26 | name: 'name',
|
27 | message: 'What will be the name of your project?',
|
28 | validate: v => Boolean(v) || 'You should provide a name.',
|
29 | },
|
30 | {
|
31 | type: 'list',
|
32 | choices: ['github', 'phab'],
|
33 | name: 'type',
|
34 | message: 'Where will your project be hosted?',
|
35 | },
|
36 | {
|
37 | name: 'org',
|
38 | message: 'Which organisation will host the repo?',
|
39 | validate: v => Boolean(v) || 'You should provide an org.',
|
40 | when: ({ type }) => type === 'github',
|
41 | },
|
42 | {
|
43 | name: 'phabUrl',
|
44 | message: 'What is the phabricator url?',
|
45 | validate: v => Boolean(v) || 'You should provide an url.',
|
46 | when: ({ type }) => type === 'phab',
|
47 | },
|
48 | {
|
49 | name: 'desc',
|
50 | message: 'Provide a basic description of your project',
|
51 | validate: v => Boolean(v) || 'You should provide a description.',
|
52 | },
|
53 | ])
|
54 | .then(res => {
|
55 | execSync('mkdir -p static src src/styles')
|
56 |
|
57 | const json = require(`${DIR_PATH}/package.json`)
|
58 |
|
59 | json.name = slug(res.name)
|
60 | json.description = res.desc
|
61 |
|
62 | json.scripts = {
|
63 | start: 'ocular start',
|
64 | build: 'ocular build',
|
65 | lint: 'ocular lint',
|
66 | }
|
67 |
|
68 | writeFileSync(`${DIR_PATH}/package.json`, `${JSON.stringify(json, null, 2)}\n`)
|
69 | writeFileSync(`${DIR_PATH}/html.config.js`, htmlConfigTemplate(res))
|
70 | writeFileSync(`${DIR_PATH}/src/config.js`, configTemplate(res))
|
71 | writeFileSync(`${DIR_PATH}/src/mdRoutes.js`, 'export default [];\n')
|
72 | writeFileSync(`${DIR_PATH}/src/demos.js`, 'export default {};\n')
|
73 | writeFileSync(`${DIR_PATH}/src/styles/index.scss`, '')
|
74 | writeFileSync(`${DIR_PATH}/src/styles/_variables.scss`, variablesTemplate())
|
75 | })
|
76 | },
|
77 |
|
78 | start: () => {
|
79 | const shouldOpen = process.argv.includes('open')
|
80 |
|
81 | spawn(
|
82 | `${DIR_PATH}/node_modules/.bin/webpack-dev-server`,
|
83 | [...(shouldOpen ? ['--open'] : []), '--config', 'webpack/dev'],
|
84 | { cwd: __dirname, stdio: 'inherit', env }
|
85 | )
|
86 | },
|
87 |
|
88 | lint: () => {
|
89 | spawn(`${DIR_PATH}/node_modules/.bin/eslint`, [`${DIR_PATH}/src`, '-c', '.eslintrc'], {
|
90 | cwd: __dirname,
|
91 | stdio: 'inherit',
|
92 | })
|
93 | },
|
94 |
|
95 | build: () => {
|
96 | execSync(`rm -rf ${DIR_PATH}/dist`)
|
97 |
|
98 | spawn(`${DIR_PATH}/node_modules/.bin/webpack`, ['--config', 'webpack/build'], {
|
99 | cwd: __dirname,
|
100 | stdio: 'inherit',
|
101 | env: Object.assign(env, { NODE_ENV: 'production' }),
|
102 | })
|
103 | },
|
104 |
|
105 | help: () => {
|
106 | console.log(`
|
107 | Ocular CLI
|
108 | ----------
|
109 |
|
110 | Available commands:
|
111 |
|
112 | - init: create the bootstrap files in the current project
|
113 | - start: launch webpack in dev mode (accepts 'open' arg)
|
114 | - lint: run eslint on the current project
|
115 | - build: generate the bundle and dist files
|
116 |
|
117 | You can provide the --debug flag to print the computed webpack config.
|
118 | `)
|
119 | },
|
120 | }
|
121 |
|
122 | const command = process.argv[2]
|
123 | if (!commands[command]) {
|
124 | return commands.help()
|
125 | }
|
126 |
|
127 | commands[command]()
|