1
0
Fork 0

Extract from devtools project

This commit is contained in:
Michaël Lemaire 2021-09-05 22:27:05 +02:00
commit d8bcf85531
13 changed files with 320 additions and 0 deletions

10
.editorconfig Normal file
View 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
View File

@ -0,0 +1,4 @@
deno.d.ts
.vscode
.local

22
.vscode/launch.json vendored Normal file
View 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
View File

@ -0,0 +1 @@
{ "deno.enable": true }

11
.vscode/tasks.json vendored Normal file
View 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
View 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
View File

@ -0,0 +1,6 @@
#!./run
import { normalize } from "./src/normalize.ts";
if (import.meta.main) {
await normalize();
}

1
config/run.flags Normal file
View File

@ -0,0 +1 @@
--allow-run=./run --allow-read=. --allow-write=.

1
deps.ts Normal file
View File

@ -0,0 +1 @@
export { Sys } from "https://js.thunderk.net/system@1.0.0/mod.ts";

20
run Executable file
View 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
View File

231
src/normalize.ts Executable file
View 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
View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"module": "esnext",
"target": "ESNext",
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"preserveConstEnums": true
}
}