2017-09-01 08:23:17 +03:00
|
|
|
const chalk = require("chalk")
|
2017-09-01 21:57:00 +03:00
|
|
|
const fse = require("fs-extra")
|
2017-09-01 08:23:17 +03:00
|
|
|
const path = require("path")
|
|
|
|
const Generator = require("yeoman-generator")
|
|
|
|
|
2017-09-07 20:49:11 +03:00
|
|
|
const stripPrimerPrefix = require("./lib/strip-prefix")
|
|
|
|
|
|
|
|
const OPTIONS = require("./options")
|
2017-09-01 08:23:17 +03:00
|
|
|
|
|
|
|
module.exports = class PrimerModule extends Generator {
|
|
|
|
|
2017-09-06 22:42:22 +03:00
|
|
|
constructor(args, opts) {
|
|
|
|
super(args, opts)
|
2017-09-01 08:23:17 +03:00
|
|
|
|
2017-09-07 21:00:10 +03:00
|
|
|
// initialize positional arguments and option flags
|
2017-09-07 20:49:11 +03:00
|
|
|
Object.entries(OPTIONS).forEach(([name, val]) => {
|
|
|
|
if (val.argument) {
|
|
|
|
this.argument(name, Object.assign(val.argument, {name}))
|
|
|
|
} else if (val.option) {
|
2017-09-07 21:00:10 +03:00
|
|
|
const option = Object.assign(val.option, {name})
|
|
|
|
if (name.includes("_")) {
|
|
|
|
const alias = name.replace(/_/g, "-")
|
|
|
|
option.alias = option.alias
|
|
|
|
? [alias].concat(option.alias)
|
|
|
|
: alias
|
|
|
|
}
|
|
|
|
this.option(name, option)
|
2017-09-07 20:49:11 +03:00
|
|
|
}
|
2017-09-01 08:23:17 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-09-06 22:42:22 +03:00
|
|
|
initializing() {
|
2017-09-07 21:38:49 +03:00
|
|
|
// this.log("It looks like you are adding a new Primer module!")
|
2017-09-06 22:42:22 +03:00
|
|
|
}
|
|
|
|
|
2017-09-01 08:23:17 +03:00
|
|
|
prompting() {
|
|
|
|
if (this.options.module) {
|
2017-09-07 21:19:54 +03:00
|
|
|
this.log(
|
|
|
|
"Okay, let's get you started with %s...",
|
|
|
|
chalk.green(this.options.module)
|
|
|
|
)
|
2017-09-01 08:23:17 +03:00
|
|
|
}
|
|
|
|
|
2017-09-07 20:49:11 +03:00
|
|
|
// filter out options without prompts, and which already
|
|
|
|
// have options set, then add back the "name" key to each
|
|
|
|
const prompts = Object.entries(OPTIONS)
|
|
|
|
.filter(([name, {prompt}]) => {
|
2017-09-12 01:23:49 +03:00
|
|
|
return prompt && (
|
|
|
|
prompt.when === true || typeof this.options[name] === "undefined"
|
|
|
|
)
|
2017-09-07 20:49:11 +03:00
|
|
|
})
|
|
|
|
.map(([name, {prompt}]) => {
|
2017-09-07 21:19:54 +03:00
|
|
|
// bind functions to the generator as `this`
|
|
|
|
Object.keys(prompt).forEach(key => {
|
|
|
|
if (typeof prompt[key] === "function") {
|
|
|
|
prompt[key] = prompt[key].bind(this)
|
|
|
|
}
|
|
|
|
})
|
2017-09-07 20:49:11 +03:00
|
|
|
return Object.assign(prompt, {name})
|
|
|
|
})
|
2017-09-01 08:23:17 +03:00
|
|
|
|
|
|
|
// remove prompts for which arguments were already provided
|
2017-09-07 20:49:11 +03:00
|
|
|
return this.prompt(prompts)
|
2017-09-01 08:23:17 +03:00
|
|
|
.then(answers => {
|
|
|
|
Object.assign(this.options, answers)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
configuring() {
|
2017-09-07 20:49:11 +03:00
|
|
|
this.dependencies = this._getDependencies()
|
2017-09-01 21:57:00 +03:00
|
|
|
if (this.options.docs) {
|
|
|
|
return fse.readFile(this.options.docs, "utf8")
|
|
|
|
.then(docs => this.options.docs = docs)
|
|
|
|
}
|
2017-09-01 08:23:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
paths() {
|
|
|
|
this.basePath = this.destinationPath(this.options.module)
|
|
|
|
}
|
|
|
|
|
|
|
|
writing() {
|
|
|
|
this.log("creating: %s", chalk.green(this.basePath))
|
|
|
|
|
2017-09-07 20:49:11 +03:00
|
|
|
const data = {
|
|
|
|
"dependencies": this.dependencies,
|
|
|
|
}
|
|
|
|
|
|
|
|
Object.assign(
|
|
|
|
data,
|
|
|
|
Object.entries(OPTIONS)
|
|
|
|
.map(([name, value]) => [name, this.options[name]])
|
|
|
|
.reduce((acc, [name, value]) => {
|
|
|
|
acc[name] = value
|
|
|
|
return acc
|
|
|
|
}, {})
|
|
|
|
)
|
|
|
|
|
|
|
|
if (this.options.verbose) {
|
|
|
|
const debugData = Object.assign({}, data, {
|
|
|
|
"dependencies": Object.keys(data.dependencies),
|
|
|
|
})
|
|
|
|
console.warn(chalk.green("data:"), JSON.stringify(debugData, null, " "))
|
|
|
|
}
|
2017-09-01 08:23:17 +03:00
|
|
|
|
2017-09-07 02:53:29 +03:00
|
|
|
// for the index.scss import
|
|
|
|
data.lib = stripPrimerPrefix(data.module)
|
2017-09-01 08:23:17 +03:00
|
|
|
|
|
|
|
// copy the whole directory with each file treated as
|
|
|
|
// an EJS template
|
|
|
|
this.fs.copyTpl(
|
|
|
|
this.templatePath(),
|
|
|
|
this.basePath,
|
|
|
|
data
|
|
|
|
)
|
2017-09-01 21:57:00 +03:00
|
|
|
|
|
|
|
const src = path.join(this.basePath, "lib/module.scss")
|
2017-09-07 02:53:29 +03:00
|
|
|
const dest = src.replace("module.scss", `${data.lib}.scss`)
|
2017-09-01 21:57:00 +03:00
|
|
|
this.fs.move(src, dest)
|
2017-09-01 08:23:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
install() {
|
|
|
|
const pkg = this.fs.readJSON(
|
|
|
|
path.join(this.basePath, "package.json")
|
|
|
|
)
|
|
|
|
// this.log("package:", pkg.name, "@", pkg.version)
|
|
|
|
|
2017-09-12 01:23:49 +03:00
|
|
|
const dependents = this.options.dependents
|
|
|
|
if (Array.isArray(dependents)) {
|
|
|
|
dependents.forEach(dependent => {
|
2017-09-01 21:58:19 +03:00
|
|
|
this._addAsDependencyTo(pkg, dependent)
|
|
|
|
})
|
2017-09-12 01:23:49 +03:00
|
|
|
} else {
|
|
|
|
this.log(chalk.red("No dependents!"), dependents)
|
2017-09-01 21:58:19 +03:00
|
|
|
}
|
2017-09-01 08:23:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
end() {
|
2017-09-07 20:49:11 +03:00
|
|
|
if (this.options.todo === true) {
|
|
|
|
this.log(
|
2017-09-07 21:24:58 +03:00
|
|
|
"\n📝 ",
|
|
|
|
chalk.bold("Remember to fill in any remaining TODOs below:"),
|
|
|
|
"\n"
|
2017-09-07 20:49:11 +03:00
|
|
|
)
|
2017-09-01 21:58:19 +03:00
|
|
|
this.spawnCommandSync("ack", ["TODO", this.basePath], {
|
|
|
|
stdio: "inherit",
|
|
|
|
})
|
|
|
|
}
|
2017-09-01 08:23:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
_getDependencies() {
|
|
|
|
return [
|
|
|
|
"primer-support",
|
|
|
|
].reduce((deps, module) => {
|
|
|
|
deps[module] = require(`${module}/package.json`)
|
|
|
|
return deps
|
|
|
|
}, {})
|
|
|
|
}
|
|
|
|
|
|
|
|
_addAsDependencyTo(pkg, dest) {
|
|
|
|
this.log(
|
|
|
|
"adding %s@%s as a dependency to %s...",
|
2017-09-07 02:36:14 +03:00
|
|
|
pkg.name, pkg.version, dest
|
2017-09-01 08:23:17 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
const destPath = require.resolve(
|
2017-09-07 02:58:30 +03:00
|
|
|
path.join("../../", dest, "package.json")
|
2017-09-01 08:23:17 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
this.fs.extendJSON(destPath, {
|
|
|
|
dependencies: {
|
|
|
|
[pkg.name]: pkg.version,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|