Skip to content

Commit 8b0ae11

Browse files
author
Nick Balestra
committed
interactive init
1 parent 707bad6 commit 8b0ae11

File tree

4 files changed

+174
-82
lines changed

4 files changed

+174
-82
lines changed

packages/cycle-scripts/scripts/init.js

Lines changed: 167 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,100 @@ const fs = require('fs-extra')
44
const path = require('path')
55
const chalk = require('chalk')
66
const spawn = require('cross-spawn')
7+
const inquirer = require('inquirer')
78

8-
// To be moved to separate module
9-
const basicDependencies = [
10-
'@cycle/dom@16.0.0',
11-
'@cycle/run@3.0.0',
12-
'xstream@10.3.0'
13-
]
9+
// Ask the user for which language and which stream library he want to use
10+
const dependencies = {
11+
basics: [
12+
'@cycle/dom@17.1.0'
13+
],
14+
language: {
15+
'JavaScript': [],
16+
'TypeScript': []
17+
},
18+
streamLib: {
19+
xstream: [
20+
'@cycle/run@3.1.0',
21+
'xstream@10.5.0'
22+
],
23+
rxjs: [
24+
'@cycle/rxjs-run@7.0.0',
25+
'rxjs@5.3.0'
26+
],
27+
most: [
28+
'@cycle/most-run@7.1.0',
29+
'most@1.2.2'
30+
]
31+
}
32+
}
1433

15-
function patchGitignore (appPath) {
16-
// Rename gitignore after the fact to prevent npm from renaming it to .npmignore
17-
// See: https://github.com/npm/npm/issues/1862
18-
const gitignorePath = path.join(appPath, 'gitignore')
19-
const dotGitignorePath = path.join(appPath, '.gitignore')
20-
fs.move(gitignorePath, dotGitignorePath, [], (err) => {
21-
if (err) {
22-
// Append if there's already a `.gitignore` file there
23-
if (err.code === 'EEXIST') {
24-
const content = fs.readFileSync(gitignorePath)
25-
fs.appendFileSync(dotGitignorePath, content)
26-
fs.unlinkSync(gitignorePath)
27-
} else {
28-
throw err
29-
}
30-
}
31-
})
34+
const replacements = {
35+
xstream: {
36+
run: '@cycle/run',
37+
import: 'import xs from \'xstream\'',
38+
stream: 'xs'
39+
},
40+
rxjs: {
41+
run: '@cycle/rxjs-run',
42+
import: 'import Rx from \'rxjs/Rx\'',
43+
stream: 'Rx.Observable'
44+
},
45+
most: {
46+
run: '@cycle/most-run',
47+
import: 'import * as most from \'most\'',
48+
stream: 'most'
49+
}
3250
}
3351

52+
const initQuestions = [
53+
{
54+
type: 'list',
55+
name: 'language',
56+
default: 0,
57+
choices: ['JavaScript', 'TypeScript'],
58+
message: 'Which language do you want to use to write your cycle app?'
59+
},
60+
{
61+
type: 'list',
62+
name: 'streamLib',
63+
default: 0,
64+
choices: [
65+
{
66+
name: 'XStream, tailored for Cycle.js',
67+
value: 'xstream'
68+
},
69+
{
70+
name: 'Most.js, a blazing fast stream library',
71+
value: 'most'
72+
},
73+
{
74+
name: 'RxJS',
75+
value: 'rxjs'
76+
}
77+
],
78+
message: 'Which reactive stream library do you want to use?'
79+
}
80+
]
81+
82+
// function patchGitignore (appPath) {
83+
// // Rename gitignore after the fact to prevent npm from renaming it to .npmignore
84+
// // See: https://github.com/npm/npm/issues/1862
85+
// const gitignorePath = path.join(appPath, 'gitignore')
86+
// const dotGitignorePath = path.join(appPath, '.gitignore')
87+
// fs.move(gitignorePath, dotGitignorePath, [], (err) => {
88+
// if (err) {
89+
// // Append if there's already a `.gitignore` file there
90+
// if (err.code === 'EEXIST') {
91+
// const content = fs.readFileSync(gitignorePath)
92+
// fs.appendFileSync(dotGitignorePath, content)
93+
// fs.unlinkSync(gitignorePath)
94+
// } else {
95+
// throw err
96+
// }
97+
// }
98+
// })
99+
// }
100+
34101
function successMsg (appName, appPath) {
35102
console.log()
36103
console.log(`Success! Created ${appName} at ${appPath}`)
@@ -68,63 +135,85 @@ module.exports = function init (appPath, appName, verbose, originalDirectory) {
68135
const appPackageJson = path.join(appPath, 'package.json')
69136
const appPackage = require(appPackageJson)
70137

71-
// Manipulate app's package.json
72-
// To be moved to separate module
73-
appPackage.dependencies = appPackage.dependencies || {}
74-
appPackage.devDependencies = appPackage.devDependencies || {}
75-
appPackage.scripts = {
76-
'start': 'cycle-scripts start',
77-
'test': 'cycle-scripts test',
78-
'build': 'cycle-scripts build',
79-
'eject': 'cycle-scripts eject'
80-
}
138+
inquirer.prompt(initQuestions).then(answers => {
139+
const language = answers.language
140+
const streamLib = answers.streamLib
81141

82-
// appPackage.babel = {
83-
// presets: [
84-
// [ 'env', {
85-
// 'targets': {
86-
// 'browsers': ['last 2 versions'],
87-
// uglify: true
88-
// }
89-
// }]
90-
// ],
91-
// plugins: [
92-
// ['transform-react-jsx', { pragma: 'Snabbdom.createElement' }]
93-
// ]
94-
// }
95-
96-
fs.writeFileSync(
97-
appPackageJson,
98-
JSON.stringify(appPackage, null, 2)
99-
)
100-
101-
// Copy flavor files
102-
fs.copySync(path.join(ownPath, 'template'), appPath)
103-
patchGitignore(appPath)
104-
105-
const listOfbasicDependencies = basicDependencies
106-
.slice(0, (basicDependencies.length - 1))
107-
.join(', ')
108-
.concat(` and ${basicDependencies.slice(-1)}`)
109-
110-
console.log(`Installing ${listOfbasicDependencies} using npm...`)
111-
console.log()
142+
const basicDependencies = dependencies.basics
143+
const languageDependencies = dependencies.language[language]
144+
const streamLibDependencies = dependencies.streamLib[streamLib]
145+
146+
const depsToInstall = basicDependencies.concat(languageDependencies).concat(streamLibDependencies)
112147

113-
const args = [
114-
'install'
115-
].concat(
116-
basicDependencies
117-
).concat([
118-
'--save',
119-
verbose && '--verbose'
120-
]).filter(Boolean)
121-
122-
var proc = spawn('npm', args, {stdio: 'inherit'})
123-
proc.on('close', function (code) {
124-
if (code !== 0) {
125-
console.error(chalk.red('`npm ' + args.join(' ') + '` failed'))
126-
return
148+
// Manipulate app's package.json
149+
// To be moved to separate module
150+
appPackage.dependencies = appPackage.dependencies || {}
151+
appPackage.devDependencies = appPackage.devDependencies || {}
152+
appPackage.scripts = {
153+
'start': 'cycle-scripts start',
154+
'test': 'cycle-scripts test',
155+
'build': 'cycle-scripts build',
156+
'eject': 'cycle-scripts eject'
127157
}
128-
successMsg(appName, appPath)
158+
159+
fs.writeFileSync(
160+
appPackageJson,
161+
JSON.stringify(appPackage, null, 2)
162+
)
163+
164+
// Copy flavor files
165+
// fs.copySync(path.join(ownPath, 'template'), appPath)
166+
167+
fs.ensureDirSync(path.join(appPath, 'public'))
168+
fs.copySync(path.join(ownPath, 'template/public'), path.join(appPath, 'public'))
169+
170+
// copy src and transform each of the file
171+
fs.ensureDirSync(path.join(appPath, 'src'))
172+
const templatePath = path.join(ownPath, 'template/src', language)
173+
fs.readdir(templatePath, (err, files) => {
174+
if (err) {
175+
throw err
176+
}
177+
files.forEach(file => {
178+
const targetPath = path.join(appPath, 'src', file)
179+
const fileSrc = require(path.join(templatePath, file))
180+
const targetSrc = fileSrc(replacements[streamLib])
181+
fs.outputFile(targetPath, targetSrc)
182+
})
183+
})
184+
185+
fs.copySync(path.join(ownPath, 'template/src', language), path.join(appPath, 'src'))
186+
187+
// for each file in template/src load them, replace and write them
188+
189+
// for each library
190+
191+
// patchGitignore(appPath)
192+
193+
const dependecyList = depsToInstall
194+
.slice(0, (depsToInstall.length - 1))
195+
.join(', ')
196+
.concat(` and ${depsToInstall.slice(-1)}`)
197+
198+
console.log(`Installing ${dependecyList} using npm...`)
199+
console.log()
200+
201+
const args = [
202+
'install'
203+
].concat(
204+
depsToInstall
205+
).concat([
206+
'--save',
207+
verbose && '--verbose'
208+
]).filter(Boolean)
209+
210+
var proc = spawn('npm', args, {stdio: 'inherit'})
211+
proc.on('close', function (code) {
212+
if (code !== 0) {
213+
console.error(chalk.red('`npm ' + args.join(' ') + '` failed'))
214+
return
215+
}
216+
successMsg(appName, appPath)
217+
})
129218
})
130219
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import xs from 'xstream'
1+
module.exports = replacements => `${replacements.import}
22
33
export function App (sources) {
4-
const vtree$ = xs.of(
4+
const vtree$ = ${replacements.stream}.of(
55
<div>My Awesome Cycle.js app</div>
66
)
77
const sinks = {
88
DOM: vtree$
99
}
1010
return sinks
1111
}
12+
`
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// import assert from 'assert'
1+
module.exports = replacements => `// import assert from 'assert'
22
33
// describe('App', function () {
44
// it('should test something', function () {
55
// // TODO: Add your tests here
66
// })
77
// })
8+
`

packages/cycle-scripts/template/src/index.js renamed to packages/cycle-scripts/template/src/JavaScript/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {run} from '@cycle/run'
1+
module.exports = replacements => `import {run} from '${replacements.run}'
22
import {makeDOMDriver} from '@cycle/dom'
33
import {App} from './app'
44
@@ -9,3 +9,4 @@ const drivers = {
99
}
1010
1111
run(main, drivers)
12+
`

0 commit comments

Comments
 (0)