Extract from devtools project
This commit is contained in:
commit
d8bcf85531
10
.editorconfig
Normal file
10
.editorconfig
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*.{ts,json}]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
deno.d.ts
|
||||||
|
.vscode
|
||||||
|
.local
|
||||||
|
|
22
.vscode/launch.json
vendored
Normal file
22
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Deno",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"program": "cli.ts",
|
||||||
|
"console": "externalTerminal",
|
||||||
|
"attachSimplePort": 9229,
|
||||||
|
"runtimeExecutable": "deno",
|
||||||
|
"runtimeArgs": [
|
||||||
|
"run",
|
||||||
|
"--inspect",
|
||||||
|
"--allow-run=./run",
|
||||||
|
"--allow-read=.",
|
||||||
|
"--allow-write=."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
1
.vscode/settings.json
vendored
Normal file
1
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ "deno.enable": true }
|
11
.vscode/tasks.json
vendored
Normal file
11
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "test",
|
||||||
|
"type": "shell",
|
||||||
|
"group": { "kind": "test", "isDefault": true },
|
||||||
|
"command": "./run test"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# typescript/scaffold
|
||||||
|
|
||||||
|
[![Build Status](https://thunderk.visualstudio.com/typescript/_apis/build/status/scaffold?branchName=master)](https://dev.azure.com/thunderk/typescript/_build?pipelineNameFilter=scaffold)
|
6
cli.ts
Executable file
6
cli.ts
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!./run
|
||||||
|
import { normalize } from "./src/normalize.ts";
|
||||||
|
|
||||||
|
if (import.meta.main) {
|
||||||
|
await normalize();
|
||||||
|
}
|
1
config/run.flags
Normal file
1
config/run.flags
Normal file
|
@ -0,0 +1 @@
|
||||||
|
--allow-run=./run --allow-read=. --allow-write=.
|
1
deps.ts
Normal file
1
deps.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { Sys } from "https://js.thunderk.net/system@1.0.0/mod.ts";
|
20
run
Executable file
20
run
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Simplified run tool for deno commands
|
||||||
|
|
||||||
|
if test $# -eq 0
|
||||||
|
then
|
||||||
|
echo "Usage: $0 [file or command]"
|
||||||
|
exit 1
|
||||||
|
elif echo $1 | grep -q '.*.ts'
|
||||||
|
then
|
||||||
|
denocmd=run
|
||||||
|
denoargs=$1
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
denocmd=$1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
denoargs="$(cat config/$denocmd.flags 2> /dev/null) $denoargs $@"
|
||||||
|
exec deno $denocmd $denoargs
|
||||||
|
|
0
src/normalize.test.ts
Normal file
0
src/normalize.test.ts
Normal file
231
src/normalize.ts
Executable file
231
src/normalize.ts
Executable file
|
@ -0,0 +1,231 @@
|
||||||
|
import { Sys } from "../deps.ts";
|
||||||
|
|
||||||
|
export class ProjectNormalizer {
|
||||||
|
constructor(readonly sys = Sys) {
|
||||||
|
}
|
||||||
|
|
||||||
|
async isDirectory(path: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
return (await this.sys.stat(path)).isDirectory;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async isFile(path: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
return (await this.sys.stat(path)).isFile;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async readContent(path: string): Promise<string> {
|
||||||
|
try {
|
||||||
|
return await this.sys.readTextFile(path);
|
||||||
|
} catch {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async ensureDirectory(path: string) {
|
||||||
|
if (!await this.isDirectory(path)) {
|
||||||
|
await this.sys.mkdir(path, { recursive: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async writeJsonFile(path: string, content: any) {
|
||||||
|
await this.sys.writeTextFile(
|
||||||
|
path,
|
||||||
|
JSON.stringify(content),
|
||||||
|
);
|
||||||
|
await this.formatPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
async formatPath(path: string) {
|
||||||
|
await this.sys.run({
|
||||||
|
cmd: ["./run", "fmt", "-q", path],
|
||||||
|
}).status();
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateRunScript() {
|
||||||
|
await this.sys.writeTextFile(
|
||||||
|
"run",
|
||||||
|
`#!/bin/sh
|
||||||
|
# Simplified run tool for deno commands
|
||||||
|
|
||||||
|
if test $# -eq 0
|
||||||
|
then
|
||||||
|
echo "Usage: $0 [file or command]"
|
||||||
|
exit 1
|
||||||
|
elif echo $1 | grep -q '.*\.ts'
|
||||||
|
then
|
||||||
|
denocmd=run
|
||||||
|
denoargs=$1
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
denocmd=$1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
denoargs="$(cat config/$denocmd.flags 2> /dev/null) $denoargs $@"
|
||||||
|
exec deno $denocmd $denoargs
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
await this.sys.chmod("run", 0o755);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateDenoDefs() {
|
||||||
|
const process = this.sys.run({
|
||||||
|
cmd: ["./run", "types"],
|
||||||
|
stdout: "piped",
|
||||||
|
});
|
||||||
|
const defs = new TextDecoder("utf-8").decode(await process.output());
|
||||||
|
await this.sys.writeTextFile("deno.d.ts", defs);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateEditorConfig() {
|
||||||
|
await this.sys.writeTextFile(
|
||||||
|
".editorconfig",
|
||||||
|
`root = true
|
||||||
|
|
||||||
|
[*.{ts,json}]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateTsConfig() {
|
||||||
|
await this.writeJsonFile("tsconfig.json", {
|
||||||
|
compilerOptions: {
|
||||||
|
module: "esnext",
|
||||||
|
target: "ESNext",
|
||||||
|
strict: true,
|
||||||
|
noImplicitReturns: true,
|
||||||
|
noFallthroughCasesInSwitch: true,
|
||||||
|
preserveConstEnums: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateVscodeConf() {
|
||||||
|
await this.ensureDirectory(".vscode");
|
||||||
|
const path = ".vscode/settings.json";
|
||||||
|
const json_config = await this.readContent(path);
|
||||||
|
const config = JSON.parse(json_config || "{}");
|
||||||
|
if (!config["deno.enable"]) {
|
||||||
|
config["deno.enable"] = true;
|
||||||
|
await this.writeJsonFile(path, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.writeJsonFile(".vscode/tasks.json", {
|
||||||
|
version: "2.0.0",
|
||||||
|
tasks: [
|
||||||
|
{
|
||||||
|
label: "test",
|
||||||
|
type: "shell",
|
||||||
|
group: {
|
||||||
|
kind: "test",
|
||||||
|
isDefault: true,
|
||||||
|
},
|
||||||
|
command: "./run test",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (await this.isFile("cli.ts")) {
|
||||||
|
await this.writeJsonFile(".vscode/launch.json", {
|
||||||
|
version: "0.2.0",
|
||||||
|
configurations: [
|
||||||
|
{
|
||||||
|
name: "Deno",
|
||||||
|
type: "node",
|
||||||
|
request: "launch",
|
||||||
|
cwd: "\${workspaceFolder}",
|
||||||
|
program: "cli.ts",
|
||||||
|
console: "externalTerminal",
|
||||||
|
attachSimplePort: 9229,
|
||||||
|
runtimeExecutable: "deno",
|
||||||
|
runtimeArgs: [
|
||||||
|
"run",
|
||||||
|
"--inspect",
|
||||||
|
].concat(
|
||||||
|
(await this.readContent("config/run.flags"))
|
||||||
|
.split(" ")
|
||||||
|
.filter((part) => !!part),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateGitIgnore() {
|
||||||
|
await this.sys.writeTextFile(
|
||||||
|
".gitignore",
|
||||||
|
`deno.d.ts
|
||||||
|
.vscode
|
||||||
|
.local
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateGitHooks() {
|
||||||
|
await this.sys.writeTextFile(
|
||||||
|
".git/hooks/pre-commit",
|
||||||
|
`#!/bin/sh
|
||||||
|
set -e
|
||||||
|
./run fmt --check
|
||||||
|
./run test
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
await this.sys.chmod(".git/hooks/pre-commit", 0o755);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateReadme() {
|
||||||
|
const project = this.sys.cwd().split("/").pop();
|
||||||
|
let sections = "";
|
||||||
|
if (await this.isDirectory("doc")) {
|
||||||
|
const index = await this.readContent("doc/index");
|
||||||
|
for (let section of index.split("\n")) {
|
||||||
|
if (section?.trim()) {
|
||||||
|
sections += "\n" +
|
||||||
|
(await this.readContent(`doc/${section.trim()}.md`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await this.sys.writeTextFile(
|
||||||
|
"README.md",
|
||||||
|
`# typescript/${project}
|
||||||
|
|
||||||
|
[![Build Status](https://thunderk.visualstudio.com/typescript/_apis/build/status/${project}?branchName=master)](https://dev.azure.com/thunderk/typescript/_build?pipelineNameFilter=${project})
|
||||||
|
${sections}`,
|
||||||
|
);
|
||||||
|
await this.formatPath("README.md");
|
||||||
|
}
|
||||||
|
|
||||||
|
async normalize() {
|
||||||
|
if (!await this.isDirectory(".git")) {
|
||||||
|
throw new Error("Not in a git repository");
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.updateRunScript();
|
||||||
|
await this.updateDenoDefs();
|
||||||
|
await this.updateVscodeConf();
|
||||||
|
await this.updateTsConfig();
|
||||||
|
await this.updateEditorConfig();
|
||||||
|
await this.updateGitIgnore();
|
||||||
|
await this.updateGitHooks();
|
||||||
|
await this.updateReadme();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function normalize(sys = Sys) {
|
||||||
|
const normalizer = new ProjectNormalizer(sys);
|
||||||
|
await normalizer.normalize();
|
||||||
|
}
|
10
tsconfig.json
Normal file
10
tsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "esnext",
|
||||||
|
"target": "ESNext",
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"preserveConstEnums": true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue