Extract from devtools project
This commit is contained in:
commit
d8bcf85531
13 changed files with 320 additions and 0 deletions
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