Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17,618 changes: 6,595 additions & 11,023 deletions package-lock.json

Large diffs are not rendered by default.

49 changes: 25 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
"test:template": "./script/test-template.sh",
"lint": "prettier --ignore-path .gitignore --check '**/*.{js,ts,json,yml,md}'",
"lint:fix": "prettier --ignore-path .gitignore --write '**/*.{js,ts,json,yml,md}'",
"dev": "tsc-watch --onFirstSuccess \"npm run dev:make-cpa\"",
"dev:make-cpa": "ts-node -e 'import { chBinMod } from \"./script/make-executable\"; chBinMod(\"create-probot-app\")'",
"dev:make-tests": "ts-node -e 'import { chBinMod } from \"./script/make-executable\"; chBinMod(\"run-tests\")'",
"dev:make-cpa": "node --input-type=module -e 'import { chBinMod } from \"./script/make-executable.js\"; chBinMod(\"create-probot-app\")'",
"dev:make-tests": "node --input-type=module -e 'import { chBinMod } from \"./script/make-executable.js\"; chBinMod(\"run-tests\")'",
"build": "npm run build:clean && tsc && npm run dev:make-cpa && npm run dev:make-tests",
"build:clean": "rimraf bin",
"build:source": "tsc && npm run dev:make-cpa",
Expand All @@ -30,39 +29,41 @@
"author": "Brandon Keepers",
"license": "ISC",
"dependencies": {
"chalk": "^4.1.2",
"commander": "^9.0.0",
"chalk": "^5.2.0",
"commander": "^10.0.0",
"conjecture": "^0.1.2",
"cross-spawn": "^7.0.3",
"egad": "^0.2.0",
"fs-extra": "^11.0.0",
"inquirer": "^8.2.4",
"jsesc": "^3.0.1",
"execa": "^6.1.0",
"fs-extra": "^11.1.0",
"inquirer": "^9.1.4",
"jsesc": "^3.0.2",
"lodash.camelcase": "^4.3.0",
"lodash.kebabcase": "^4.1.1",
"npm": "^9.0.0",
"simple-git": "^3.0.3",
"simple-git": "^3.15.1",
"stringify-author": "^0.1.3",
"validate-npm-package-name": "^5.0.0"
},
"devDependencies": {
"@types/cross-spawn": "^6.0.2",
"@types/fs-extra": "^9.0.1",
"@types/inquirer": "^8.1.1",
"@types/jsesc": "^3.0.0",
"@types/lodash.camelcase": "^4.3.6",
"@types/lodash.kebabcase": "^4.1.6",
"@types/node": "^18.0.0",
"@types/fs-extra": "^11.0.1",
"@types/inquirer": "^9.0.3",
"@types/jsesc": "^3.0.1",
"@types/lodash.camelcase": "^4.3.7",
"@types/lodash.kebabcase": "^4.1.7",
"@types/node": "^18.11.18",
"@types/npm": "^7.19.0",
"@types/rimraf": "^3.0.0",
"@types/shelljs": "^0.8.8",
"@types/rimraf": "^3.0.2",
"@types/shelljs": "^0.8.11",
"@types/validate-npm-package-name": "^4.0.0",
"prettier": "^2.2.1",
"rimraf": "^3.0.2",
"prettier": "^2.8.3",
"rimraf": "^4.0.5",
"semantic-release": "^19.0.2",
"shelljs": "^0.8.4",
"ts-node": "^10.0.0",
"tsc-watch": "^6.0.0",
"typescript": "^4.0.2"
"shelljs": "^0.8.5",
"typescript": "^4.9.4"
},
"type": "module",
"engines": {
"node": ">= 16.7.0"
}
}
12 changes: 7 additions & 5 deletions script/make-executable.ts → script/make-executable.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import fs from "fs";
import path from "path";
import { fileURLToPath } from 'url';
import shell from "shelljs";
import pkg from "../package.json";
import pkg from "../package.json" assert { type: "json" };

const __dirname = path.dirname(fileURLToPath(import.meta.url));
/**
* Converts TS file under ./bin/ into an executable file.
*
Expand All @@ -14,10 +16,10 @@ import pkg from "../package.json";
*
* @param {string} name the name of the built JS file, e.g. 'create-probot-app'
*/
export function chBinMod(name: string): void {
const binList: Record<string, string> = pkg.bin;
const jsFilePath: string = binList[name];
const distributableBinary: string = path.join(__dirname, "..", jsFilePath);
export function chBinMod(name) {
const binList = pkg.bin;
const jsFilePath = binList[name];
const distributableBinary = path.join(__dirname, "..", jsFilePath);

try {
if (fs.existsSync(distributableBinary)) {
Expand Down
40 changes: 18 additions & 22 deletions src/create-probot-app.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
#!/usr/bin/env node
import { askUser, runCliManager } from "./helpers/user-interaction";
import { initGit } from "./helpers/init-git";
import { installAndBuild } from "./helpers/run-npm";
import { makeScaffolding } from "./helpers/filesystem";
import { printSuccess, red } from "./helpers/write-help";
import { askUser, runCliManager } from "./helpers/user-interaction.js";
import { initGit } from "./helpers/init-git.js";
import { installAndBuild } from "./helpers/run-npm.js";
import { makeScaffolding } from "./helpers/filesystem.js";
import { printSuccess, red } from "./helpers/write-help.js";

async function main(): Promise<void> {
runCliManager()
.then((cliConfig) => askUser(cliConfig))
.then((config) => makeScaffolding(config))
.then(async (config) => {
if (config.gitInit) await initGit(config.destination);
return config;
})
.then(async (config) => await installAndBuild(config))
.then((config) => printSuccess(config.appName, config.destination))
.catch((err) => {
console.log(red(err));
process.exit(1);
});
}

main();
runCliManager()
.then((cliConfig) => askUser(cliConfig))
.then((config) => makeScaffolding(config))
.then(async (config) => {
if (config.gitInit) await initGit(config.destination);
return config;
})
.then(async (config) => await installAndBuild(config))
.then((config) => printSuccess(config.appName, config.destination))
.catch((err) => {
console.log(red(err));
process.exit(1);
});
21 changes: 14 additions & 7 deletions src/helpers/filesystem.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import path from "path";
import fs from "fs-extra";
import * as path from "path";
import { fileURLToPath } from 'url';
import * as fs from "fs";
import { generate } from "egad";
import { Config } from "./user-interaction";
import { yellow, green } from "./write-help";
import { Config } from "./user-interaction.js";
import { yellow, green } from "./write-help.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

export const templatesSourcePath = path.join(__dirname, "../../templates/");

Expand Down Expand Up @@ -62,9 +65,11 @@ export async function makeScaffolding(config: Config): Promise<Config> {
[
path.join(templatesSourcePath, "__common__"),
path.join(templatesSourcePath, config.template),
].forEach((source) => fs.copySync(source, tempDestPath));
].forEach((source) => fs.cpSync(source, tempDestPath, {
recursive: true
}));

fs.removeSync(path.join(tempDestPath, "__description__.txt"));
fs.rmSync(path.join(tempDestPath, "__description__.txt"));

if (fs.existsSync(path.join(tempDestPath, "gitignore")))
fs.renameSync(
Expand All @@ -76,7 +81,9 @@ export async function makeScaffolding(config: Config): Promise<Config> {
overwrite: config.overwrite,
});

fs.removeSync(tempDestPath);
fs.rmSync(tempDestPath, {
recursive: true
});

result.forEach((fileInfo) => {
console.log(
Expand Down
8 changes: 4 additions & 4 deletions src/helpers/init-git.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import fs from "fs-extra";
import path from "path";
import spawn from "cross-spawn";
import * as fs from "fs-extra";
import * as path from "path";
import * as spawn from "cross-spawn";
import simplegit from "simple-git";

import { green, yellow, red } from "./write-help";
import { green, yellow, red } from "./write-help.js";

function isInGitRepo(path: string): boolean {
const gitRevParse = spawn.sync(
Expand Down
91 changes: 42 additions & 49 deletions src/helpers/run-npm.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import npm from "npm";
import { bold, yellow } from "./write-help";
import { Config } from "./user-interaction";
import { bold, yellow } from "./write-help.js";
import { Config } from "./user-interaction.js";
import { execa } from "execa";

export function detectPackageManager(): string {
const { npm_config_user_agent: userAgent } = process.env;
if (userAgent) {
if (userAgent.includes("yarn")) return "yarn";
if (userAgent.includes("npm")) return "npm";
}
return "npm";
}

/**
* Run `npm install` in `destination` folder, then run `npm run build`
Expand All @@ -10,52 +19,36 @@ import { Config } from "./user-interaction";
*
* @returns Promise which returns the input Config object
*/
export function installAndBuild(config: Config): Promise<Config> {
class NpmError extends Error {
constructor(msg: string, command: string) {
const message = `

Could not ${msg}.
Try running ${bold("npm " + command)} yourself.

`;
super(message);
}
export async function installAndBuild(config: Config): Promise<Config> {
const originalDir = process.cwd();
process.chdir(config.destination);
const packageManager = detectPackageManager();
console.log(
yellow("\nInstalling dependencies. This may take a few minutes...\n")
);
try {
await execa(packageManager, ["install"]);
} catch (error: any) {
process.chdir(originalDir);
throw new Error(
`\nCould not install npm dependencies.\nTry running ${bold(
"npm install"
)} yourself.\n`
);
}

return new Promise((resolve, reject) => {
npm.load(function (err) {
if (err) reject(err);

const defaultPrefix = npm.prefix;

const rejectWithError = (error: NpmError) => {
npm.prefix = defaultPrefix;
reject(error);
};

const resolveWithConfig = () => {
npm.prefix = defaultPrefix;
resolve(config);
};

console.log(
yellow("\nInstalling dependencies. This may take a few minutes...\n")
if (config.toBuild) {
console.log(yellow("\n\nCompile application...\n"));
try {
await execa(packageManager, ["run", "build"]);
} catch (error: any) {
process.chdir(originalDir);
throw new Error(
`\nCould not build application.\nTry running ${bold(
"npm run build"
)} yourself.\n`
);

npm.prefix = config.destination;
npm.commands.install([], function (err) {
if (err)
rejectWithError(new NpmError("install npm dependencies", "install"));
else if (config.toBuild) {
console.log(yellow("\n\nCompile application...\n"));
npm.commands["run-script"](["build"], function (err) {
if (err)
rejectWithError(new NpmError("build application", "run build"));
else resolveWithConfig();
});
} else resolveWithConfig();
});
});
});
}
}
process.chdir(originalDir);
return config;
}
14 changes: 9 additions & 5 deletions src/helpers/user-interaction.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import path from "path";
import * as fs from "fs";
import * as path from "path";
import { fileURLToPath } from "url";

import { guessEmail, guessAuthor, guessGitHubUsername } from "conjecture";
import camelCase from "lodash.camelcase";
import commander from "commander";
import * as commander from "commander";
import inquirer, { Answers, Question, QuestionCollection } from "inquirer";
import jsesc from "jsesc";
import kebabCase from "lodash.kebabcase";
import stringifyAuthor from "stringify-author";
import validatePackageName from "validate-npm-package-name";

import { blue, red, printHelpAndFail } from "./write-help";
import { getTemplates, ensureValidDestination } from "./filesystem";
import { blue, red, printHelpAndFail } from "./write-help.js";
import { getTemplates, ensureValidDestination } from "./filesystem.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const templateDelimiter = " => ";

Expand Down Expand Up @@ -197,7 +201,7 @@ export async function runCliManager(): Promise<CliConfig> {
// TSC mangles output directory when using normal import methods for
// package.json. See
// https://github.com/Microsoft/TypeScript/issues/24715#issuecomment-542490675
const pkg = require(require.resolve("../../package.json"));
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "..", "package.json"), "utf-8"));

const program = new commander.Command("create-probot-app")
.arguments("[destination]")
Expand Down
2 changes: 1 addition & 1 deletion src/run-tests.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node
import fs from "fs";
import path from "path";
import { red } from "./helpers/write-help";
import { red } from "./helpers/write-help.js";

/**
* Ensure `package.json` from templated app meets all requirements
Expand Down
7 changes: 3 additions & 4 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
{
"compilerOptions": {
"allowJs": false,
"module": "commonjs",
"target": "es2015",
"module": "ESNext",
"target": "es2022",
"moduleResolution": "node",
"strict": true,
"noImplicitAny": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": false,
"outDir": "bin",
"baseUrl": ".",
Expand Down