Skip to content

Commit

Permalink
feat: add template support
Browse files Browse the repository at this point in the history
This commit also includes a host of other changes. A few notable ones:

- Renamed "bootstrap" command to "install".
- Added the "rm" command.
- Added support for templates using "@starters/core"

BREAKING CHANGE: renamed "bootstrap" command to "install"
  • Loading branch information
jakehamilton committed Dec 28, 2020
1 parent 901324d commit 2dbede1
Show file tree
Hide file tree
Showing 19 changed files with 2,347 additions and 287 deletions.
2,140 changes: 1,968 additions & 172 deletions packages/titan/package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion packages/titan/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
"@types/node": "^14.11.1"
},
"dependencies": {
"@littlethings/log": "^1.3.1",
"@littlethings/log": "^2.3.0",
"@littlethings/test": "^1.2.1",
"@starters/core": "^1.1.0",
"arg": "^4.1.3",
"chalk": "^4.1.0",
"inquirer": "^7.3.3",
Expand Down
35 changes: 31 additions & 4 deletions packages/titan/src/commands/add/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const semver = require("semver");
const log = require("../../util/log");
const npm = require("../../util/npm");
const git = require("../../util/git");
const cmd = require("../../util/cmd");
const help = require("./help");
const getArgs = require("./args");

Expand Down Expand Up @@ -165,36 +166,62 @@ const command = () => {
}
}
} else {
let resolvedVersion = version;

if (version === "latest") {
try {
const versions = JSON.parse(
cmd.exec(`npm view ${name} versions --json`, {
encoding: "utf8",
})
);

if (versions.length === 0) {
log.error(
`No versions found for package "${name}". Defaulting to "latest".`
);
} else {
resolvedVersion = `^${
versions[versions.length - 1]
}`;
}
} catch (error) {
log.error(
`Could not fetch versions from npm for package "${name}". Defaulting to "latest".`
);
}
}

if (!args["--dev"] && !args["--peer"] && !args["--optional"]) {
if (!pkg.config.hasOwnProperty("dependencies")) {
pkg.config.dependencies = {};
}

pkg.config.dependencies[name] = version;
pkg.config.dependencies[name] = resolvedVersion;
}

if (args["--dev"]) {
if (!pkg.config.hasOwnProperty("devDependencies")) {
pkg.config.devDependencies = {};
}

pkg.config.devDependencies[name] = version;
pkg.config.devDependencies[name] = resolvedVersion;
}

if (args["--peer"]) {
if (!pkg.config.hasOwnProperty("peerDependencies")) {
pkg.config.peerDependencies = {};
}

pkg.config.peerDependencies[name] = version;
pkg.config.peerDependencies[name] = resolvedVersion;
}

if (args["--optional"]) {
if (!pkg.config.hasOwnProperty("optionalDependencies")) {
pkg.config.optionalDependencies = {};
}

pkg.config.optionalDependencies[name] = version;
pkg.config.optionalDependencies[name] = resolvedVersion;
}
}
}
Expand Down
7 changes: 2 additions & 5 deletions packages/titan/src/commands/create/args.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ const getArgs = () => ({
"--force": Boolean,
"-f": "--force",

"--private": Boolean,
"-p": "--private",

"--name": String,
"-n": "--name",
"--template": String,
"-t": "--template",
},
{
permissive: false,
Expand Down
6 changes: 5 additions & 1 deletion packages/titan/src/commands/create/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ const help = () => {
{bold USAGE}
{dim $} {bold titan create} <name> [root]
{dim $} {bold titan create} <name> [root] [options]
{bold OPTIONS}
--help Show this help message
--force, -f Overwrite existing directory if it exists
--private, -p Set the package to private
--name, -n Set the name used in package.json
--template, -t The {white.bold starters} template to use
{bold EXAMPLE}
Expand All @@ -30,6 +31,9 @@ const help = () => {
{dim $ # Create a private package.}
{dim $} {bold titan create} --private my-private-library
{dim $ # Create a JavaScript library from a template.}
{dim $} {bold titan create} my-library --template @starters/library
`;

console.log(message);
Expand Down
88 changes: 40 additions & 48 deletions packages/titan/src/commands/create/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const chalk = require("chalk");
const starters = require("@starters/core");
const fs = require("../../util/fs");
const log = require("../../util/log");
const path = require("../../util/path");
const npm = require("../../util/npm");

const help = require("./help");
const getArgs = require("./args");
Expand All @@ -14,7 +17,7 @@ const command = () => {
}

if (args._.length === 1) {
log.error("Missing position arguments");
log.error("No name specified.");
help();
process.exit(1);
}
Expand All @@ -26,50 +29,56 @@ const command = () => {
process.exit(1);
}

const pkgName = args["--name"] || name;
const rootPkgPath = npm.getProjectRoot();
const pkg = npm.getProjectRootConfig();

const pkgPath = path.resolve(process.cwd(), "package.json");

if (!fs.exists(pkgPath)) {
log.error(`Unable to load package configuration at "${pkgPath}".`);
if (!pkg.titan.packages) {
log.error(
chalk`Root configuration has no {white titan.packages} property.`
);
process.exit(1);
}

const pkg = JSON.parse(
fs.read(pkgPath, {
encoding: "utf8",
})
);
const root = path.resolveRelative(args._[2] || pkg.titan.packages[0]);

if (!pkg.titan) {
log.error("Package has no titan config.");
process.exit(1);
}
let isPkgMapped = false;
for (const pkgPath of pkg.titan.packages) {
const resolvedPkgPath = path.resolveRelative(pkgPath, rootPkgPath);

if (!pkg.titan.packages) {
log.error("Package has no `titan.packages` property.");
process.exit(1);
if (root === resolvedPkgPath) {
isPkgMapped = true;
}
}

const where = path.resolveRelative(args._[2] || pkg.titan.packages[0]);
if (!isPkgMapped) {
log.warn(
chalk`Root configuration's {white.bold titan.packages} property does not include {white.bold ${path.relative(
rootPkgPath,
root
)}}.`
);
}

if (!where) {
if (!root) {
log.error("No destination available.");
process.exit(1);
}

if (!fs.exists(where)) {
if (!fs.exists(root)) {
log.info("Creating destination directory.");
fs.mkdir(where);
} else if (!fs.isDir(where)) {
fs.mkdir(root);
} else if (!fs.isDir(root)) {
log.info("Creating destination directory.");
fs.mkdir(where);
fs.mkdir(root);
}

const target = path.resolve(where, name);
const target = path.resolve(root, name);

if (fs.exists(target)) {
if (args["--force"] && fs.isDir(target)) {
log.debug(
chalk`Removing existing directory {white.bold ${target}}.`
);
fs.rm(target);
} else {
log.error(
Expand All @@ -82,31 +91,14 @@ const command = () => {
log.info("Creating package directory.");
fs.mkdir(target);

const src = path.resolve(target, "src");

fs.mkdir(src);

const pkgTemplate = JSON.parse(
fs.read(path.resolve(__dirname, "package.template.json"), {
encoding: "utf8",
})
);

pkgTemplate.name = pkgName;
const template = args["--template"] || "@starters/library";

if (args["--private"]) {
pkgTemplate.private = true;
try {
starters.create(target, template, name);
} catch (error) {
log.error("Could not create package.");
process.exit(1);
}

fs.write(
path.resolve(target, "package.json"),
JSON.stringify(pkgTemplate, null, 4) + "\n"
);

fs.write(
path.resolve(src, "index.js"),
fs.read(path.resolve(__dirname, "index.template.js"))
);
};

module.exports = command;
3 changes: 2 additions & 1 deletion packages/titan/src/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ module.exports = {
init: require("./init"),
create: require("./create"),
version: require("./version"),
bootstrap: require("./bootstrap"),
install: require("./install"),
exec: require("./exec"),
publish: require("./publish"),
add: require("./add"),
changed: require("./changed"),
run: require("./run"),
rm: require("./rm"),
};
3 changes: 3 additions & 0 deletions packages/titan/src/commands/init/args.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const getArgs = () => ({

"--skip-git": Boolean,
"-X": "--skip-git",

"--template": String,
"-t": "--template",
},
{
permissive: false,
Expand Down
1 change: 1 addition & 0 deletions packages/titan/src/commands/init/gitignore.template
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,4 @@ dist
.pnp.*

tmp
.DS_Store
4 changes: 4 additions & 0 deletions packages/titan/src/commands/init/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const help = () => {
--force, -f Overwrite existing directory
--skip-install, -x Skip installing dependencies
--skip-git, -X Skip running git commands
--template, -t The {white.bold starters} template to use
{bold EXAMPLE}
Expand All @@ -31,6 +32,9 @@ const help = () => {
{dim $ # Create a new project but don't run git commands.}
{dim $} {bold titan init} --skip-git my-project
{dim $ # Create a new project using a template.}
{dim $} {bold titan init} my-project --template my-starters-template
`;

console.log(message);
Expand Down
Loading

0 comments on commit 2dbede1

Please sign in to comment.