Skip to content

Commit d55ff92

Browse files
authored
Merge pull request #61 from akd-io/release/0.0.9
Release 0.0.9
2 parents f64b54f + 13681af commit d55ff92

26 files changed

+284
-61
lines changed

.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"no-process-exit": "off",
1313
"unicorn/no-process-exit": "off",
1414
"no-warning-comments": "off",
15-
"@typescript-eslint/no-use-before-define": "off"
15+
"@typescript-eslint/no-use-before-define": "off",
16+
"@typescript-eslint/no-unused-vars": "warn"
1617
}
1718
}

bin/run-prod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env node
2+
3+
require(`../lib`).run().catch(require("@oclif/errors/handle"))

package.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "create-next-stack",
3-
"version": "0.0.8",
3+
"version": "0.0.9",
44
"author": "Anders Kjær Damgaard @akd-io",
55
"bin": {
66
"create-next-stack": "./bin/run"
@@ -13,13 +13,16 @@
1313
"@oclif/plugin-help": "^3.2.2",
1414
"execa": "^5.1.1",
1515
"inquirer": "^8.1.1",
16+
"rimraf": "^3.0.2",
1617
"tslib": "^2.3.0",
1718
"validate-npm-package-name": "^3.0.0"
1819
},
1920
"devDependencies": {
2021
"@oclif/dev-cli": "^1.26.0",
2122
"@types/inquirer": "^7.3.2",
2223
"@types/node": "^15.12.4",
24+
"@types/rimraf": "^3.0.1",
25+
"@types/uuid": "^8.3.1",
2326
"@types/validate-npm-package-name": "^3.0.2",
2427
"eslint": "^5.16.0",
2528
"eslint-config-oclif": "^3.1.0",
@@ -28,9 +31,9 @@
2831
"husky": "^6.0.0",
2932
"lint-staged": "^11.0.0",
3033
"prettier": "^2.3.2",
31-
"rimraf": "^3.0.2",
3234
"ts-node": "^10.0.0",
33-
"typescript": "^4.3.4"
35+
"typescript": "^4.3.4",
36+
"uuid": "^8.3.2"
3437
},
3538
"engines": {
3639
"node": ">=12.0.0"
@@ -53,7 +56,7 @@
5356
"prepare": "husky install",
5457
"prepack": "yarn build && oclif-dev readme",
5558
"build": "rimraf lib && tsc -b",
56-
"test": "echo NO TESTS",
59+
"test": "ts-node src/e2e/test.ts",
5760
"version": "oclif-dev readme && git add README.md",
5861
"format": "prettier --write --ignore-path=.gitignore .",
5962
"format:check": "prettier --check --ignore-path=.gitignore .",

src/e2e/helpers/exit-with-error.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import console from "console"
2+
3+
export const exitWithError = async (error: unknown) => {
4+
if (error instanceof Error) {
5+
console.error(error.message)
6+
} else if (typeof error === "string") {
7+
console.error(error)
8+
} else {
9+
console.error("Error: An error object of unknown type was thrown.")
10+
}
11+
process.exit(1)
12+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import console from "console"
2+
import execa from "execa"
3+
import { exitWithError } from "./exit-with-error"
4+
5+
export const setGitNameAndEmail = async () => {
6+
try {
7+
await execa("git", ["config", "--global", "user.name"])
8+
.then((result) => {
9+
console.log(`user.name found: ${result.stdout}`)
10+
})
11+
.catch(async () => {
12+
console.log(`user.name didn't exist. Setting user.name="Test user"`)
13+
await execa("git", ["config", "--global", "user.name", "Test user"])
14+
})
15+
await execa("git", ["config", "--global", "user.email"])
16+
.then((result) => {
17+
console.log(`user.email found: ${result.stdout}`)
18+
})
19+
.catch(async () => {
20+
console.log(
21+
`user.email didn't exist. Setting user.email="test-user@create-next-stack.com"`
22+
)
23+
await execa("git", [
24+
"config",
25+
"--global",
26+
"user.email",
27+
"test-user@create-next-stack.com",
28+
])
29+
})
30+
} catch (error) {
31+
exitWithError(error)
32+
}
33+
}

src/e2e/test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { exitWithError } from "./helpers/exit-with-error"
2+
import { setGitNameAndEmail } from "./helpers/set-git-name-and-email"
3+
import { testDefaultOptions } from "./tests/default-options"
4+
;(async () => {
5+
try {
6+
// If not done already, Set Git name and email so `git commit` doesn't fail during create-next-app
7+
await setGitNameAndEmail()
8+
9+
await testDefaultOptions()
10+
} catch (error) {
11+
exitWithError(error)
12+
}
13+
})()

src/e2e/tests/default-options.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import console from "console"
2+
import execa from "execa"
3+
import { promises as fs } from "fs"
4+
import path from "path"
5+
import { v4 as uuidv4 } from "uuid"
6+
7+
export const testDefaultOptions = async () => {
8+
const createNextStackDir = process.cwd()
9+
10+
// Create unique id for this run
11+
const testRunId = uuidv4()
12+
13+
// Switch to unique test directory
14+
const runDirectory = path.resolve(
15+
`../create-next-stack-tests/run-${testRunId}`
16+
)
17+
await fs.mkdir(runDirectory, { recursive: true })
18+
process.chdir(runDirectory)
19+
console.log(`Created test run directory at ${runDirectory}`)
20+
21+
// Run /bin/run-prod to test against compiled js files in /lib instead of ts-files in /src using ts-node.
22+
const pathToProdCLI = path.resolve(`${createNextStackDir}/bin/run-prod`)
23+
24+
console.log(`Making /bin/run readable and executable by all.`)
25+
await fs.chmod(pathToProdCLI, 0o555)
26+
27+
console.log(`Running command: ${pathToProdCLI} --debug .`)
28+
const execaProcess = execa(pathToProdCLI, ["--debug", "."], {
29+
timeout: 10 * 60 * 1000,
30+
}) // 10 minutes
31+
execaProcess.stdout?.pipe(process.stdout)
32+
execaProcess.stderr?.pipe(process.stderr)
33+
34+
console.log("Sending \\n to accept default options.")
35+
execaProcess.stdin?.write("\n") // Press
36+
37+
await execaProcess
38+
39+
console.log("Checking formatting")
40+
await execa("npx", ["prettier", "--check", "--ignore-path=.gitignore", "."])
41+
42+
console.log("Checking linting")
43+
await execa("yarn", ["lint"])
44+
45+
console.log("Running yarn build")
46+
await execa("yarn", ["build"])
47+
}

src/helpers/is-git-initialized.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import fs from "fs/promises"
1+
import { promises as fs } from "fs"
22

33
/**
44
* `isGitInitialized` checks if Git has been initialized or not.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import execa from "execa"
2+
3+
/**
4+
* This function finds out if a package is installed globally.
5+
*
6+
* IMPORTANT: This function is not perfect. It uses `npm list -g --depth=0 <package-name>` which checks both top-level packages and their dependencies.
7+
* In other words, the --depth param only limits the depth of the rendered tree, not the actual search algorithm itself.
8+
* This means that a search for the package `which`, for example, will not throw an error even though the package isn't installed globally.
9+
* As such, false positives can arise.
10+
*
11+
* In order to combat this, `isPackageGloballyInstalled` checks whether the output tree of depth 0 includes the specified package name.
12+
*
13+
* This limits the false positives to cases where some top-level package has:
14+
* 1. the specified package somewhere in its dependency tree, AND
15+
* 2. the specified package name included in its own name
16+
*
17+
* @param packageName The name of the npm package
18+
* @returns Whether the specified npm package is globally installed or not.
19+
*/
20+
export const isPackageGloballyInstalled = async (
21+
packageName: string
22+
): Promise<boolean> => {
23+
try {
24+
const execaResult = await execa("npm", [
25+
"list",
26+
"-g",
27+
"--depth=0",
28+
packageName,
29+
])
30+
31+
if (!execaResult.stdout.includes(packageName)) {
32+
return false
33+
}
34+
} catch {
35+
return false
36+
}
37+
38+
return true
39+
}

src/helpers/remove.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import fs from "fs/promises"
1+
import rimraf from "rimraf"
2+
import { promisify } from "util"
3+
4+
const rm = promisify(rimraf)
25

36
export const remove = (path: string): Promise<void> => {
4-
return fs.rm(path, {
5-
recursive: true,
6-
force: true,
7-
})
7+
return rm(path)
88
}

0 commit comments

Comments
 (0)