Doric command line tool refact to typescript
This commit is contained in:
102
doric-cli/src/create.ts
Normal file
102
doric-cli/src/create.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import { exec } from "child_process"
|
||||
import { getAssetsDir } from "./util"
|
||||
import { Shell } from "./shell";
|
||||
|
||||
const targetJSPath = getAssetsDir();
|
||||
const targetAndroidPath = path.resolve(targetJSPath, "android")
|
||||
const targetiOSPath = path.resolve(targetJSPath, "iOS")
|
||||
const currentVersion = fs.readFileSync(path.resolve(targetJSPath, "version")).toString().trim()
|
||||
|
||||
async function shellCopy(dist: string, src: string) {
|
||||
await Shell.exec("cp", [
|
||||
"-rf",
|
||||
src,
|
||||
dist
|
||||
])
|
||||
}
|
||||
|
||||
async function initJS(dir: string, name: string) {
|
||||
console.log(`Project location ${dir}`);
|
||||
await fs.promises.writeFile(
|
||||
path.resolve(dir, "package.json"),
|
||||
(await fs.promises.readFile(path.resolve(targetJSPath, "_package.json"), "utf-8"))
|
||||
.replace(/__\$__/g, name).replace(/__\$Version__/g, currentVersion));
|
||||
await shellCopy(path.resolve(dir, "tsconfig.json"), path.resolve(targetJSPath, "_tsconfig.json"));
|
||||
await shellCopy(path.resolve(dir, "rollup.config.js"), path.resolve(targetJSPath, "_rollup.config.js"));
|
||||
await shellCopy(path.resolve(dir, ".gitignore"), path.resolve(targetJSPath, "_gitignore"));
|
||||
await fs.promises.mkdir(path.resolve(dir, ".vscode"));
|
||||
await shellCopy(path.resolve(dir, ".vscode", "launch.json"), path.resolve(targetJSPath, "_launch.json"))
|
||||
await shellCopy(path.resolve(dir, ".vscode", "tasks.json"), path.resolve(targetJSPath, "_tasks.json"))
|
||||
await fs.promises.mkdir(path.resolve(dir, "src"))
|
||||
await fs.promises.writeFile(
|
||||
path.resolve(dir, "src", `${name}.ts`),
|
||||
(await fs.promises.readFile(path.resolve(targetJSPath, "$.ts"), "utf-8")).replace(/__\$__/g, name));
|
||||
await fs.promises.writeFile(
|
||||
path.resolve(dir, `index.ts`),
|
||||
`export default ['src/${name}']`);
|
||||
console.log(`Create Doric JS Project Success`.green)
|
||||
}
|
||||
|
||||
async function initAndroid(dir: string, name: string) {
|
||||
const androidDir = `${dir}/android`
|
||||
await shellCopy(dir, targetAndroidPath);
|
||||
for (let file of [
|
||||
'app/src/main/java/pub/doric/example/MainActivity.java',
|
||||
'app/build.gradle',
|
||||
'app/src/main/res/values/strings.xml',
|
||||
'settings.gradle',
|
||||
]) {
|
||||
const sourceFile = path.resolve(androidDir, file);
|
||||
await fs.promises.writeFile(
|
||||
sourceFile,
|
||||
(await fs.promises.readFile(sourceFile, "utf-8"))
|
||||
.replace(/__\$__/g, name).replace(/__\$Version__/g, currentVersion));
|
||||
}
|
||||
console.log(`Create Doric Android Project Success`.green);
|
||||
}
|
||||
async function initiOS(dir: string, name: string) {
|
||||
const iOSDir = `${dir}/iOS`
|
||||
await shellCopy(dir, targetiOSPath);
|
||||
for (let file of [
|
||||
'App/SceneDelegate.m',
|
||||
'App/AppDelegate.m',
|
||||
'Example.xcodeproj/project.pbxproj',
|
||||
'Podfile',
|
||||
]) {
|
||||
const sourceFile = path.resolve(iOSDir, file);
|
||||
await fs.promises.writeFile(
|
||||
sourceFile,
|
||||
(await fs.promises.readFile(sourceFile, "utf-8"))
|
||||
.replace(/__\$__/g, name).replace(/__\$Version__/g, currentVersion));
|
||||
}
|
||||
await fs.promises.rename(path.resolve(iOSDir, "Example.xcodeproj"), path.resolve(iOSDir, `${name}.xcodeproj`));
|
||||
console.log(`Create Doric iOS Project Success`.green);
|
||||
}
|
||||
|
||||
export default async function create(name: string) {
|
||||
const cwd = path.resolve(process.cwd(), name)
|
||||
if (fs.existsSync(name)) {
|
||||
console.warn(`Dir:${cwd}/${name} already exists`)
|
||||
return;
|
||||
}
|
||||
await fs.promises.mkdir(name)
|
||||
await initJS(cwd, name)
|
||||
const androidDir = `${cwd}/android`
|
||||
if (fs.existsSync(androidDir)) {
|
||||
console.warn(`Dir:${androidDir} already exists`)
|
||||
} else {
|
||||
await initAndroid(cwd, name)
|
||||
}
|
||||
const iOSDir = `${cwd}/iOS`
|
||||
if (fs.existsSync(iOSDir)) {
|
||||
console.warn(`Dir:${iOSDir} already exists`)
|
||||
} else {
|
||||
await initiOS(cwd, name)
|
||||
}
|
||||
console.log("Install node modules ...".green)
|
||||
await Shell.exec('npm', ['install'], { cwd });
|
||||
await Shell.exec('npm', ['run', 'build'], { cwd });
|
||||
console.log("Installed, welcome!".green)
|
||||
}
|
28
doric-cli/src/index.ts
Normal file
28
doric-cli/src/index.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import commander from "commander"
|
||||
import create from "./create"
|
||||
|
||||
commander
|
||||
.command('create <name>')
|
||||
.action(async function (name, cmd) {
|
||||
await create(name);
|
||||
})
|
||||
commander
|
||||
.command('new <name>')
|
||||
.action(async function (name, cmd) {
|
||||
await create(name);
|
||||
})
|
||||
commander
|
||||
.command('dev')
|
||||
.action(function () {
|
||||
})
|
||||
commander
|
||||
.command('build')
|
||||
.action(function () {
|
||||
})
|
||||
commander
|
||||
.command('clean')
|
||||
.action(function () {
|
||||
})
|
||||
commander.parse(process.argv)
|
158
doric-cli/src/shell.ts
Normal file
158
doric-cli/src/shell.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
import { spawn, SpawnOptionsWithoutStdio } from "child_process";
|
||||
import "colors";
|
||||
const debug = false
|
||||
export namespace Shell {
|
||||
export async function execWithPipe(
|
||||
cmd: {
|
||||
command: string;
|
||||
args?: ReadonlyArray<string>;
|
||||
options?: SpawnOptionsWithoutStdio & {
|
||||
silence?: boolean; //不打印耗时,默认为false
|
||||
verbose?: boolean; //打印输出内容,默认为true
|
||||
};
|
||||
},
|
||||
pipedCmd: {
|
||||
command: string;
|
||||
args?: ReadonlyArray<string>;
|
||||
options?: SpawnOptionsWithoutStdio;
|
||||
}
|
||||
) {
|
||||
const { command, args, options } = cmd;
|
||||
if (!options?.silence) {
|
||||
debug && console.log(`>>>>>>>>${command} ${args ? args.join(" ") : ""}`);
|
||||
}
|
||||
const now = new Date().getTime();
|
||||
return new Promise((resolve, reject) => {
|
||||
const cmd = spawn(command, args, options);
|
||||
const piped = spawn(pipedCmd.command, pipedCmd.args, pipedCmd.options);
|
||||
cmd.stdout.pipe(piped.stdin);
|
||||
cmd.stderr.pipe(piped.stdin);
|
||||
piped.stdout.on("data", (data) => {
|
||||
if (options?.verbose !== false) {
|
||||
debug && console.log(data.toString());
|
||||
}
|
||||
});
|
||||
|
||||
piped.stderr.on("data", (data) => {
|
||||
if (options?.verbose !== false) {
|
||||
debug && console.error(data.toString());
|
||||
}
|
||||
});
|
||||
|
||||
cmd.on("close", (code) => {
|
||||
if (!options?.silence) {
|
||||
const cost = new Date().getTime() - now;
|
||||
if (code !== 0) {
|
||||
debug && console.log(`exitCode:${code} 耗时 ${cost}ms <<<<<<<<`.red);
|
||||
} else {
|
||||
debug && console.log(`exitCode:${code} 耗时 ${cost}ms <<<<<<<<`);
|
||||
}
|
||||
}
|
||||
resolve(code);
|
||||
});
|
||||
cmd.on("error", (err) => {
|
||||
if (!options?.silence) {
|
||||
const cost = new Date().getTime() - now;
|
||||
debug && console.log(`error:${err} 耗时 ${cost}ms <<<<<<<<`);
|
||||
}
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
export async function exec(
|
||||
command: string,
|
||||
args?: ReadonlyArray<string>,
|
||||
options?: SpawnOptionsWithoutStdio & {
|
||||
silence?: boolean; //不打印耗时,默认为false
|
||||
verbose?: boolean; //打印输出内容,默认为true
|
||||
consoleHandler?: (info: string) => void; //命令行输出内容处理
|
||||
}
|
||||
) {
|
||||
if (!options?.silence) {
|
||||
debug && console.log(`>>>>>>>>${command} ${args ? args.join(" ") : ""}`);
|
||||
}
|
||||
const now = new Date().getTime();
|
||||
return new Promise((resolve, reject) => {
|
||||
const cmd = spawn(command, args, options);
|
||||
cmd.stdout.on("data", (data) => {
|
||||
if (options?.verbose !== false) {
|
||||
debug && console.log(data.toString());
|
||||
}
|
||||
if (options?.consoleHandler) {
|
||||
options.consoleHandler(data.toString());
|
||||
}
|
||||
});
|
||||
|
||||
cmd.stderr.on("data", (data) => {
|
||||
if (options?.verbose !== false) {
|
||||
debug && console.error(data.toString());
|
||||
}
|
||||
if (options?.consoleHandler) {
|
||||
options.consoleHandler(data.toString());
|
||||
}
|
||||
});
|
||||
|
||||
cmd.on("close", (code) => {
|
||||
if (!options?.silence) {
|
||||
const cost = new Date().getTime() - now;
|
||||
if (code !== 0) {
|
||||
debug && console.log(`exitCode:${code} 耗时 ${cost}ms <<<<<<<<`.red);
|
||||
} else {
|
||||
debug && console.log(`exitCode:${code} 耗时 ${cost}ms <<<<<<<<`);
|
||||
}
|
||||
}
|
||||
resolve(code);
|
||||
});
|
||||
cmd.on("error", (err) => {
|
||||
if (!options?.silence) {
|
||||
const cost = new Date().getTime() - now;
|
||||
debug && console.log(`error:${err} 耗时 ${cost}ms <<<<<<<<`);
|
||||
}
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
export async function execOut(
|
||||
command: string,
|
||||
args?: ReadonlyArray<string>,
|
||||
options?: SpawnOptionsWithoutStdio & {
|
||||
silence?: boolean; //不打印耗时,默认为false
|
||||
verbose?: boolean; //打印输出内容,默认为true
|
||||
}
|
||||
): Promise<string> {
|
||||
debug && console.log(`>>>>>>>>${command} ${args ? args.join(" ") : ""}`);
|
||||
const now = new Date().getTime();
|
||||
return new Promise((resolve, reject) => {
|
||||
const cmd = spawn(command, args, options);
|
||||
const result: string[] = [];
|
||||
cmd.stdout.on("data", (data) => {
|
||||
if (options?.verbose !== false) {
|
||||
debug && console.log(data.toString());
|
||||
}
|
||||
result.push(data.toString());
|
||||
});
|
||||
|
||||
cmd.stderr.on("data", (data) => {
|
||||
if (options?.verbose !== false) {
|
||||
debug && console.error(data.toString());
|
||||
}
|
||||
result.push(data.toString());
|
||||
});
|
||||
|
||||
cmd.on("close", (code) => {
|
||||
const cost = new Date().getTime() - now;
|
||||
if (code !== 0) {
|
||||
debug && console.log(`exitCode:${code} 耗时 ${cost}ms <<<<<<<<`.red);
|
||||
} else {
|
||||
debug && console.log(`exitCode:${code} 耗时 ${cost}ms <<<<<<<<`);
|
||||
}
|
||||
resolve(result.join("\n"));
|
||||
});
|
||||
cmd.on("error", (err) => {
|
||||
const cost = new Date().getTime() - now;
|
||||
debug && console.log(`error:${err} 耗时 ${cost}ms <<<<<<<<`.red);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
3
doric-cli/src/util.ts
Normal file
3
doric-cli/src/util.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function getAssetsDir() {
|
||||
return `${__dirname}/../assets`;
|
||||
}
|
Reference in New Issue
Block a user