UNPKG

3.61 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3const { spawn, execSync } = require('child_process')
4const { writeFileSync } = require('fs')
5const inquirer = require('inquirer')
6const slug = require('slug')
7
8const configTemplate = require('./templates/config')
9const variablesTemplate = require('./templates/variables.scss')
10const htmlConfigTemplate = require('./templates/html.config')
11
12const DIR_PATH = process.env.PWD
13
14const DEBUGGING = process.argv.includes('--debug')
15
16const env = Object.assign(process.env, {
17 DIR_PATH,
18 DEBUGGING,
19})
20
21const 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(`
107Ocular CLI
108----------
109
110Available 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
117You can provide the --debug flag to print the computed webpack config.
118`)
119 },
120}
121
122const command = process.argv[2]
123if (!commands[command]) {
124 return commands.help()
125}
126
127commands[command]()