chore(cta): add linting and formatting, closes #1520 (#1596)

This commit is contained in:
Lucas Fernandes Nogueira
2021-04-23 01:34:54 -03:00
committed by GitHub
parent fbf73f3ab5
commit 07f5cd21be
19 changed files with 504 additions and 389 deletions

View File

@@ -9,6 +9,8 @@ on:
paths:
- '.github/workflows/js-lint.yml'
- 'tooling/cli.js/**'
- 'tooling/api/**'
- 'tooling/create-tauri-app/**'
jobs:
eslint-check:
@@ -18,12 +20,32 @@ jobs:
- uses: actions/setup-node@v1
with:
node-version: '12'
- name: install deps via yarn
- name: install cli.js deps via yarn
working-directory: ./tooling/cli.js/
run: yarn
- name: run eslint
- name: run cli.js lint
working-directory: ./tooling/cli.js/
run: yarn lint
- name: run prettier
- name: run cli.js format
working-directory: ./tooling/cli.js/
run: yarn format:check
- name: install api deps via yarn
working-directory: ./tooling/api/
run: yarn
- name: run api lint
working-directory: ./tooling/api/
run: yarn lint
- name: run api format
working-directory: ./tooling/api/
run: yarn format:check
- name: install create-tauri-app deps via yarn
working-directory: ./tooling/create-tauri-app/
run: yarn
- name: run create-tauri-app lint
working-directory: ./tooling/create-tauri-app/
run: yarn lint
- name: run create-tauri-app format
working-directory: ./tooling/create-tauri-app/
run: yarn format:check

View File

@@ -9,6 +9,11 @@
cd tooling/api
yarn format
yarn lint-fix
cd ../cli.js
yarn format
yarn lint-fix
cd ../create-tauri-app
yarn format
yarn lint-fix

View File

@@ -0,0 +1,55 @@
module.exports = {
root: true,
env: {
node: true,
jest: true
},
parser: '@typescript-eslint/parser',
extends: [
'standard-with-typescript',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:lodash-template/recommended',
// TODO: make this work with typescript
// 'plugin:node/recommended'
'prettier'
],
plugins: ['@typescript-eslint', 'node', 'security'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
},
globals: {
__statics: true,
process: true
},
// add your custom rules here
rules: {
// allow console.log during development only
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
// allow debugger during development only
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-process-exit': 'off',
'security/detect-non-literal-fs-filename': 'warn',
'security/detect-unsafe-regex': 'error',
'security/detect-buffer-noassert': 'error',
'security/detect-child-process': 'warn',
'security/detect-disable-mustache-escape': 'error',
'security/detect-eval-with-expression': 'error',
'security/detect-no-csrf-before-method-override': 'error',
'security/detect-non-literal-regexp': 'error',
'security/detect-non-literal-require': 'warn',
'security/detect-object-injection': 'warn',
'security/detect-possible-timing-attacks': 'error',
'security/detect-pseudoRandomBytes': 'error',
'space-before-function-paren': 'off',
'@typescript-eslint/default-param-last': 'off',
'@typescript-eslint/strict-boolean-expressions': 0
}
}

View File

@@ -0,0 +1,5 @@
module.exports = {
singleQuote: true,
semi: false,
trailingComma: 'none'
}

View File

@@ -3,9 +3,9 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
const parseArgs = require("minimist");
const inquirer = require("inquirer");
const { resolve, join } = require("path");
const parseArgs = require('minimist')
const inquirer = require('inquirer')
const { resolve, join } = require('path')
const {
recipeShortNames,
recipeDescriptiveNames,
@@ -14,8 +14,8 @@ const {
install,
checkPackageManager,
shell,
addTauriScript,
} = require("../dist/");
addTauriScript
} = require('../dist/')
/**
* @type {object}
@@ -35,41 +35,41 @@ const {
const createTauriApp = async (cliArgs) => {
const argv = parseArgs(cliArgs, {
alias: {
h: "help",
v: "version",
f: "force",
l: "log",
m: "manager",
d: "directory",
b: "binary",
t: "tauri-path",
A: "app-name",
W: "window-title",
D: "dist-dir",
P: "dev-path",
r: "recipe",
h: 'help',
v: 'version',
f: 'force',
l: 'log',
m: 'manager',
d: 'directory',
b: 'binary',
t: 'tauri-path',
A: 'app-name',
W: 'window-title',
D: 'dist-dir',
P: 'dev-path',
r: 'recipe'
},
boolean: ["h", "l", "ci"],
});
boolean: ['h', 'l', 'ci']
})
if (argv.help) {
printUsage();
return 0;
printUsage()
return 0
}
if (argv.v) {
console.log(require("../package.json").version);
return false; // do this for node consumers and tests
console.log(require('../package.json').version)
return false // do this for node consumers and tests
}
if (argv.ci) {
return runInit(argv);
return runInit(argv)
} else {
return getOptionsInteractive(argv).then((responses) =>
runInit(argv, responses)
);
)
}
};
}
function printUsage() {
console.log(`
@@ -91,146 +91,146 @@ function printUsage() {
--dist-dir, -D Web assets location, relative to <project-dir>/src-tauri
--dev-path, -P Url of your dev server
--recipe, -r Add UI framework recipe. None by default.
Supported recipes: [${recipeShortNames.join("|")}]
`);
Supported recipes: [${recipeShortNames.join('|')}]
`)
}
const getOptionsInteractive = (argv) => {
let defaultAppName = argv.A || "tauri-app";
let defaultAppName = argv.A || 'tauri-app'
return inquirer
.prompt([
{
type: "input",
name: "appName",
message: "What is your app name?",
type: 'input',
name: 'appName',
message: 'What is your app name?',
default: defaultAppName,
when: !argv.A,
when: !argv.A
},
{
type: "input",
name: "tauri.window.title",
message: "What should the window title be?",
default: "Tauri App",
when: () => !argv.W,
type: 'input',
name: 'tauri.window.title',
message: 'What should the window title be?',
default: 'Tauri App',
when: () => !argv.W
},
{
type: "list",
name: "recipeName",
message: "Would you like to add a UI recipe?",
type: 'list',
name: 'recipeName',
message: 'Would you like to add a UI recipe?',
choices: recipeDescriptiveNames,
default: "No recipe",
when: () => !argv.r,
},
default: 'No recipe',
when: () => !argv.r
}
])
.catch((error) => {
if (error.isTtyError) {
// Prompt couldn't be rendered in the current environment
console.log(
"It appears your terminal does not support interactive prompts. Using default values."
);
runInit();
'It appears your terminal does not support interactive prompts. Using default values.'
)
runInit()
} else {
// Something else went wrong
console.error("An unknown error occurred:", error);
console.error('An unknown error occurred:', error)
}
});
};
})
}
async function runInit(argv, config = {}) {
const {
appName,
recipeName,
tauri: {
window: { title },
},
} = config;
window: { title }
}
} = config
// this little fun snippet pulled from vite determines the package manager the script was run from
const packageManager = /yarn/.test(process.env.npm_execpath) ? "yarn" : "npm";
const packageManager = /yarn/.test(process.env.npm_execpath) ? 'yarn' : 'npm'
let recipe;
let recipe
if (recipeName !== undefined) {
recipe = recipeByDescriptiveName(recipeName);
recipe = recipeByDescriptiveName(recipeName)
} else if (argv.r) {
recipe = recipeByShortName(argv.r);
recipe = recipeByShortName(argv.r)
}
let buildConfig = {
distDir: argv.D,
devPath: argv.P,
};
if (recipe !== undefined) {
buildConfig = recipe.configUpdate({ buildConfig, packageManager });
devPath: argv.P
}
const directory = argv.d || process.cwd();
if (recipe !== undefined) {
buildConfig = recipe.configUpdate({ buildConfig, packageManager })
}
const directory = argv.d || process.cwd()
const cfg = {
...buildConfig,
appName: appName || argv.A,
windowTitle: title || argv.w,
};
windowTitle: title || argv.w
}
// note that our app directory is reliant on the appName and
// generally there are issues if the path has spaces (see Windows)
// future TODO prevent app names with spaces or escape here?
const appDirectory = join(directory, cfg.appName);
const appDirectory = join(directory, cfg.appName)
// this throws an error if we can't run the package manager they requested
await checkPackageManager({ cwd: directory, packageManager });
await checkPackageManager({ cwd: directory, packageManager })
if (recipe.preInit) {
console.log("===== running initial command(s) =====");
await recipe.preInit({ cwd: directory, cfg, packageManager });
console.log('===== running initial command(s) =====')
await recipe.preInit({ cwd: directory, cfg, packageManager })
}
const initArgs = [
["--app-name", cfg.appName],
["--window-title", cfg.windowTitle],
["--dist-dir", cfg.distDir],
["--dev-path", cfg.devPath],
['--app-name', cfg.appName],
['--window-title', cfg.windowTitle],
['--dist-dir', cfg.distDir],
['--dev-path', cfg.devPath]
].reduce((final, argSet) => {
if (argSet[1]) {
return final.concat(argSet);
return final.concat(argSet)
} else {
return final;
return final
}
}, []);
}, [])
// Vue CLI plugin automatically runs these
if (recipe.shortName !== "vuecli") {
console.log("===== installing any additional needed deps =====");
if (recipe.shortName !== 'vuecli') {
console.log('===== installing any additional needed deps =====')
await install({
appDir: appDirectory,
dependencies: recipe.extraNpmDependencies,
devDependencies: ["@tauri-apps/cli", ...recipe.extraNpmDevDependencies],
packageManager,
});
devDependencies: ['@tauri-apps/cli', ...recipe.extraNpmDevDependencies],
packageManager
})
console.log("===== running tauri init =====");
addTauriScript(appDirectory);
console.log('===== running tauri init =====')
addTauriScript(appDirectory)
const binary = !argv.b ? packageManager : resolve(appDirectory, argv.b);
const binary = !argv.b ? packageManager : resolve(appDirectory, argv.b)
const runTauriArgs =
packageManager === "npm" && !argv.b
? ["run", "tauri", "--", "init"]
: ["tauri", "init"];
packageManager === 'npm' && !argv.b
? ['run', 'tauri', '--', 'init']
: ['tauri', 'init']
await shell(binary, [...runTauriArgs, ...initArgs], {
cwd: appDirectory,
});
cwd: appDirectory
})
}
if (recipe.postInit) {
console.log("===== running final command(s) =====");
console.log('===== running final command(s) =====')
await recipe.postInit({
cwd: appDirectory,
cfg,
packageManager,
});
packageManager
})
}
}
createTauriApp(process.argv.slice(2)).catch((err) => {
console.error(err);
});
console.error(err)
})

View File

@@ -24,7 +24,12 @@
"scripts": {
"create-tauri-app": "create-tauri-app",
"build": "rollup --config",
"prepublishOnly": "yarn build"
"prepublishOnly": "yarn build",
"lint": "eslint --ext ts \"./src/**/*.ts\"",
"lint-fix": "eslint --fix --ext ts \"./src/**/*.ts\"",
"lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts npm yarn",
"format": "prettier --write --end-of-line=auto \"./**/*.{js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore",
"format:check": "prettier --check --end-of-line=auto \"./**/*.{js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore"
},
"dependencies": {
"execa": "^5.0.0",
@@ -33,15 +38,25 @@
"scaffe": "1.0.0"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^18.0.0",
"@rollup/plugin-node-resolve": "^11.2.1",
"@rollup/plugin-typescript": "^8.2.1",
"@rollup/plugin-commonjs": "18.0.0",
"@rollup/plugin-node-resolve": "11.2.1",
"@rollup/plugin-typescript": "8.2.1",
"@typescript-eslint/eslint-plugin": "4.22.0",
"@typescript-eslint/parser": "4.22.0",
"@types/cross-spawn": "6.0.2",
"@types/inquirer": "7.3.1",
"@types/semver": "7.3.4",
"prettier": "^2.2.1",
"rollup": "^2.45.1",
"tslib": "^2.2.0",
"eslint": "7.24.0",
"eslint-config-prettier": "8.2.0",
"eslint-config-standard-with-typescript": "20.0.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-lodash-template": "0.19.0",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "5.1.0",
"eslint-plugin-security": "1.4.0",
"prettier": "2.2.1",
"rollup": "2.45.1",
"tslib": "2.2.0",
"typescript": "4.2.4"
}
}

View File

@@ -1,27 +1,27 @@
import typescript from "@rollup/plugin-typescript";
import commonjs from "@rollup/plugin-commonjs";
import pkg from "./package.json";
import typescript from '@rollup/plugin-typescript'
import commonjs from '@rollup/plugin-commonjs'
import pkg from './package.json'
export default {
treeshake: true,
perf: true,
input: "src/index.ts",
input: 'src/index.ts',
output: {
dir: "dist",
format: "cjs",
entryFileNames: "[name].js",
exports: "named",
dir: 'dist',
format: 'cjs',
entryFileNames: '[name].js',
exports: 'named'
},
plugins: [typescript(), commonjs({ extensions: [".js"] })],
plugins: [typescript(), commonjs({ extensions: ['.js'] })],
external: [
"fs",
"path",
'fs',
'path',
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.peerDependencies || {}),
...Object.keys(pkg.peerDependencies || {})
],
watch: {
chokidar: true,
include: "src/**",
exclude: "node_modules/**",
},
};
include: 'src/**',
exclude: 'node_modules/**'
}
}

View File

@@ -2,46 +2,46 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { ManagementType, Result } from "./types/deps";
import { shell } from "./shell";
import { ManagementType, Result } from './types/deps'
import { shell } from './shell'
export type PackageManager = "npm" | "yarn";
export type PackageManager = 'npm' | 'yarn'
export async function install({
appDir,
dependencies,
devDependencies,
packageManager,
packageManager
}: {
appDir: string;
dependencies: string[];
devDependencies: string[];
packageManager: PackageManager;
appDir: string
dependencies: string[]
devDependencies: string[]
packageManager: PackageManager
}): Promise<Result> {
const result: Result = new Map<ManagementType, string[]>();
await installNpmDevPackage(devDependencies, packageManager, appDir);
result.set(ManagementType.Install, devDependencies);
const result: Result = new Map<ManagementType, string[]>()
await installNpmDevPackage(devDependencies, packageManager, appDir)
result.set(ManagementType.Install, devDependencies)
await installNpmPackage(dependencies, packageManager, appDir);
result.set(ManagementType.Install, dependencies);
await installNpmPackage(dependencies, packageManager, appDir)
result.set(ManagementType.Install, dependencies)
return result;
return result
}
export async function checkPackageManager({
cwd,
packageManager,
packageManager
}: {
cwd: string;
packageManager: PackageManager;
cwd: string
packageManager: PackageManager
}): Promise<boolean> {
try {
await shell(packageManager, ["--version"], { stdio: "pipe", cwd });
return true;
await shell(packageManager, ['--version'], { stdio: 'pipe', cwd })
return true
} catch (error) {
throw new Error(
`Must have ${packageManager} installed to manage dependencies. Is either in your PATH? We tried running in ${cwd}`
);
)
}
}
@@ -50,16 +50,16 @@ async function installNpmPackage(
packageManager: PackageManager,
appDir: string
): Promise<void> {
if (packageNames.length === 0) return;
console.log(`Installing ${packageNames.join(", ")}...`);
if (packageManager === "yarn") {
await shell("yarn", ["add", packageNames.join(" ")], {
cwd: appDir,
});
if (packageNames.length === 0) return
console.log(`Installing ${packageNames.join(', ')}...`)
if (packageManager === 'yarn') {
await shell('yarn', ['add', packageNames.join(' ')], {
cwd: appDir
})
} else {
await shell("npm", ["install", packageNames.join(" ")], {
cwd: appDir,
});
await shell('npm', ['install', packageNames.join(' ')], {
cwd: appDir
})
}
}
@@ -68,23 +68,23 @@ async function installNpmDevPackage(
packageManager: PackageManager,
appDir: string
): Promise<void> {
if (packageNames.length === 0) return;
console.log(`Installing ${packageNames.join(", ")}...`);
if (packageManager === "yarn") {
if (packageNames.length === 0) return
console.log(`Installing ${packageNames.join(', ')}...`)
if (packageManager === 'yarn') {
await shell(
"yarn",
["add", "--dev", "--ignore-scripts", packageNames.join(" ")],
'yarn',
['add', '--dev', '--ignore-scripts', packageNames.join(' ')],
{
cwd: appDir,
cwd: appDir
}
);
)
} else {
await shell(
"npm",
["install", "--save-dev", "--ignore-scripts", packageNames.join(" ")],
'npm',
['install', '--save-dev', '--ignore-scripts', packageNames.join(' ')],
{
cwd: appDir,
cwd: appDir
}
);
)
}
}

View File

@@ -2,25 +2,25 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { readFileSync, writeFileSync } from "fs";
import { join } from "path";
import { readFileSync, writeFileSync } from 'fs'
import { join } from 'path'
export async function addTauriScript(appDirectory: string) {
const pkgPath = join(appDirectory, "package.json");
const pkgString = readFileSync(pkgPath, "utf8");
export function addTauriScript(appDirectory: string): void {
const pkgPath = join(appDirectory, 'package.json')
const pkgString = readFileSync(pkgPath, 'utf8')
const pkg = JSON.parse(pkgString) as {
scripts: {
tauri: string;
};
};
tauri: string
}
}
const outputPkg = {
...pkg,
scripts: {
...pkg.scripts,
tauri: "tauri",
},
};
tauri: 'tauri'
}
}
writeFileSync(pkgPath, JSON.stringify(outputPkg, undefined, 2));
writeFileSync(pkgPath, JSON.stringify(outputPkg, undefined, 2))
}

View File

@@ -2,62 +2,62 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { TauriBuildConfig } from "./types/config";
import { reactjs, reactts } from "./recipes/react";
import { vuecli } from "./recipes/vue-cli";
import { vanillajs } from "./recipes/vanilla";
import { vite } from "./recipes/vite";
import { TauriBuildConfig } from './types/config'
import { reactjs, reactts } from './recipes/react'
import { vuecli } from './recipes/vue-cli'
import { vanillajs } from './recipes/vanilla'
import { vite } from './recipes/vite'
import { PackageManager } from './dependency-manager'
export { shell } from "./shell";
export { install, checkPackageManager } from "./dependency-manager";
export { addTauriScript } from "./helpers/add-tauri-script";
import { PackageManager } from "./dependency-manager";
export { shell } from './shell'
export { install, checkPackageManager } from './dependency-manager'
export { addTauriScript } from './helpers/add-tauri-script'
export interface Recipe {
descriptiveName: string;
shortName: string;
descriptiveName: string
shortName: string
configUpdate?: ({
cfg,
packageManager,
packageManager
}: {
cfg: TauriBuildConfig;
packageManager: PackageManager;
}) => TauriBuildConfig;
extraNpmDependencies: string[];
extraNpmDevDependencies: string[];
cfg: TauriBuildConfig
packageManager: PackageManager
}) => TauriBuildConfig
extraNpmDependencies: string[]
extraNpmDevDependencies: string[]
preInit?: ({
cwd,
cfg,
packageManager,
packageManager
}: {
cwd: string;
cfg: TauriBuildConfig;
packageManager: PackageManager;
}) => Promise<void>;
cwd: string
cfg: TauriBuildConfig
packageManager: PackageManager
}) => Promise<void>
postInit?: ({
cwd,
cfg,
packageManager,
packageManager
}: {
cwd: string;
cfg: TauriBuildConfig;
packageManager: PackageManager;
}) => Promise<void>;
cwd: string
cfg: TauriBuildConfig
packageManager: PackageManager
}) => Promise<void>
}
export const allRecipes: Recipe[] = [vanillajs, reactjs, reactts, vite, vuecli];
export const allRecipes: Recipe[] = [vanillajs, reactjs, reactts, vite, vuecli]
export const recipeNames: Array<[string, string]> = allRecipes.map((r) => [
r.shortName,
r.descriptiveName,
]);
r.descriptiveName
])
export const recipeByShortName = (name: string) =>
allRecipes.find((r) => r.shortName === name);
export const recipeByShortName = (name: string): Recipe | undefined =>
allRecipes.find((r) => r.shortName === name)
export const recipeByDescriptiveName = (name: string) =>
allRecipes.find((r) => r.descriptiveName === name);
export const recipeByDescriptiveName = (name: string): Recipe | undefined =>
allRecipes.find((r) => r.descriptiveName === name)
export const recipeShortNames = allRecipes.map((r) => r.shortName);
export const recipeShortNames = allRecipes.map((r) => r.shortName)
export const recipeDescriptiveNames = allRecipes.map((r) => r.descriptiveName);
export const recipeDescriptiveNames = allRecipes.map((r) => r.descriptiveName)

View File

@@ -2,104 +2,107 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { Recipe } from "..";
import { join } from "path";
//@ts-ignore
import scaffe from "scaffe";
import { shell } from "../shell";
import { Recipe } from '..'
import { join } from 'path'
// @ts-expect-error
import scaffe from 'scaffe'
import { shell } from '../shell'
const afterCra = async (
cwd: string,
appName: string,
typescript: boolean = false
) => {
): Promise<void> => {
const templateDir = join(
__dirname,
`../src/templates/react/${typescript ? "react-ts" : "react"}`
);
`../src/templates/react/${typescript ? 'react-ts' : 'react'}`
)
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await scaffe.generate(templateDir, join(cwd, appName), {
overwrite: true,
});
overwrite: true
})
} catch (err) {
console.log(err);
console.log(err)
}
};
}
const reactjs: Recipe = {
descriptiveName: "React.js",
shortName: "reactjs",
descriptiveName: 'React.js',
shortName: 'reactjs',
configUpdate: ({ cfg, packageManager }) => ({
...cfg,
distDir: `../build`,
devPath: "http://localhost:3000",
beforeDevCommand: `${packageManager === "yarn" ? "yarn" : "npm run"} start`,
devPath: 'http://localhost:3000',
beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`,
beforeBuildCommand: `${
packageManager === "yarn" ? "yarn" : "npm run"
} build`,
packageManager === 'yarn' ? 'yarn' : 'npm run'
} build`
}),
extraNpmDevDependencies: [],
extraNpmDependencies: [],
preInit: async ({ cwd, cfg, packageManager }) => {
// CRA creates the folder for you
if (packageManager === "yarn") {
await shell("yarn", ["create", "react-app", `${cfg.appName}`], {
cwd,
});
if (packageManager === 'yarn') {
await shell('yarn', ['create', 'react-app', `${cfg.appName}`], {
cwd
})
} else {
await shell("npx", ["create-react-app", `${cfg.appName}`, "--use-npm"], {
cwd,
});
await shell('npx', ['create-react-app', `${cfg.appName}`, '--use-npm'], {
cwd
})
}
await afterCra(cwd, cfg.appName);
await afterCra(cwd, cfg.appName)
},
postInit: async ({ packageManager }) => {
console.log(`
Your installation completed.
To start, run ${packageManager === "yarn" ? "yarn" : "npm run"} tauri dev
`);
},
};
To start, run ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri dev
`)
return await Promise.resolve()
}
}
const reactts: Recipe = {
...reactjs,
descriptiveName: "React with Typescript",
shortName: "reactts",
descriptiveName: 'React with Typescript',
shortName: 'reactts',
extraNpmDependencies: [],
preInit: async ({ cwd, cfg, packageManager }) => {
// CRA creates the folder for you
if (packageManager === "yarn") {
if (packageManager === 'yarn') {
await shell(
"yarn",
["create", "react-app", "--template", "typescript", `${cfg.appName}`],
'yarn',
['create', 'react-app', '--template', 'typescript', `${cfg.appName}`],
{
cwd,
cwd
}
);
)
} else {
await shell(
"npx",
'npx',
[
"create-react-app",
'create-react-app',
`${cfg.appName}`,
"--use-npm",
"--template",
"typescript",
'--use-npm',
'--template',
'typescript'
],
{
cwd,
cwd
}
);
)
}
await afterCra(cwd, cfg.appName, true);
await afterCra(cwd, cfg.appName, true)
},
postInit: async ({ packageManager }) => {
console.log(`
Your installation completed.
To start, run ${packageManager === "yarn" ? "yarn" : "npm run"} tauri dev
`);
},
};
To start, run ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri dev
`)
return await Promise.resolve()
}
}
export { reactjs, reactts };
export { reactjs, reactts }

View File

@@ -2,49 +2,50 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { Recipe } from "..";
import { join } from "path";
//@ts-ignore
import scaffe from "scaffe";
import { Recipe } from '..'
import { join } from 'path'
// @ts-expect-error
import scaffe from 'scaffe'
export const vanillajs: Recipe = {
descriptiveName: "Vanilla.js",
shortName: "vanillajs",
descriptiveName: 'Vanilla.js',
shortName: 'vanillajs',
configUpdate: ({ cfg, packageManager }) => ({
...cfg,
distDir: `../dist`,
devPath: `../dist`,
beforeDevCommand: `${packageManager === "yarn" ? "yarn" : "npm run"} start`,
beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`,
beforeBuildCommand: `${
packageManager === "yarn" ? "yarn" : "npm run"
} build`,
packageManager === 'yarn' ? 'yarn' : 'npm run'
} build`
}),
extraNpmDevDependencies: [],
extraNpmDependencies: [],
preInit: async ({ cwd, cfg }) => {
const { appName } = cfg;
const templateDir = join(__dirname, "../src/templates/vanilla");
const { appName } = cfg
const templateDir = join(__dirname, '../src/templates/vanilla')
const variables = {
name: appName,
};
name: appName
}
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await scaffe.generate(templateDir, join(cwd, appName), {
overwrite: true,
variables,
});
variables
})
} catch (err) {
console.log(err);
console.log(err)
}
},
postInit: async ({ cfg, packageManager }) => {
const setApp =
packageManager === "npm"
packageManager === 'npm'
? `
set tauri script once
$ npm set-script tauri tauri
`
: "";
: ''
console.log(`
change directory:
@@ -54,9 +55,10 @@ install dependencies:
$ ${packageManager} install
run the app:
$ ${packageManager === "yarn" ? "yarn" : "npm run"} tauri ${
packageManager === "npm" ? "-- " : ""
$ ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri ${
packageManager === 'npm' ? '-- ' : ''
}dev
`);
},
};
`)
return await Promise.resolve()
}
}

View File

@@ -2,98 +2,105 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { Recipe } from "..";
import { join } from "path";
import { readdirSync } from "fs";
//@ts-ignore
import scaffe from "scaffe";
import { shell } from "../shell";
import inquirer from "inquirer";
import { Recipe } from '..'
import { join } from 'path'
import { readdirSync } from 'fs'
// @ts-expect-error
import scaffe from 'scaffe'
import { shell } from '../shell'
import inquirer from 'inquirer'
const afterViteCA = async (cwd: string, appName: string, template: string) => {
const templateDir = join(__dirname, `../src/templates/vite/${template}`);
const afterViteCA = async (
cwd: string,
appName: string,
template: string
): Promise<void> => {
const templateDir = join(__dirname, `../src/templates/vite/${template}`)
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await scaffe.generate(templateDir, join(cwd, appName), {
overwrite: true,
});
overwrite: true
})
} catch (err) {
console.log(err);
console.log(err)
}
};
}
const vite: Recipe = {
descriptiveName: "Vite backed recipe",
shortName: "vite",
descriptiveName: 'Vite backed recipe',
shortName: 'vite',
configUpdate: ({ cfg, packageManager }) => ({
...cfg,
distDir: `../dist`,
devPath: "http://localhost:3000",
beforeDevCommand: `${packageManager === "yarn" ? "yarn" : "npm run"} start`,
devPath: 'http://localhost:3000',
beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`,
beforeBuildCommand: `${
packageManager === "yarn" ? "yarn" : "npm run"
} build`,
packageManager === 'yarn' ? 'yarn' : 'npm run'
} build`
}),
extraNpmDevDependencies: [],
extraNpmDependencies: [],
preInit: async ({ cwd, cfg, packageManager }) => {
try {
const { template } = await inquirer.prompt([
const { template } = (await inquirer.prompt([
{
type: "list",
name: "template",
message: "Which vite template would you like to use?",
choices: readdirSync(join(__dirname, "../src/templates/vite")),
default: "vue",
},
]);
type: 'list',
name: 'template',
message: 'Which vite template would you like to use?',
choices: readdirSync(join(__dirname, '../src/templates/vite')),
default: 'vue'
}
])) as { template: string }
// Vite creates the folder for you
if (packageManager === "yarn") {
if (packageManager === 'yarn') {
await shell(
"yarn",
'yarn',
[
"create",
"@vitejs/app",
'create',
'@vitejs/app',
`${cfg.appName}`,
"--template",
`${template}`,
'--template',
`${template}`
],
{
cwd,
cwd
}
);
)
} else {
await shell(
"npx",
["@vitejs/create-app", `${cfg.appName}`, "--template", `${template}`],
'npx',
['@vitejs/create-app', `${cfg.appName}`, '--template', `${template}`],
{
cwd,
cwd
}
);
)
}
await afterViteCA(cwd, cfg.appName, template);
await afterViteCA(cwd, cfg.appName, template)
} catch (error) {
if (error.isTtyError) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (error?.isTtyError) {
// Prompt couldn't be rendered in the current environment
console.log(
"It appears your terminal does not support interactive prompts. Using default values."
);
'It appears your terminal does not support interactive prompts. Using default values.'
)
} else {
// Something else went wrong
console.error("An unknown error occurred:", error);
console.error('An unknown error occurred:', error)
}
}
},
postInit: async ({ packageManager }) => {
console.log(`
Your installation completed.
To start, run ${packageManager === "yarn" ? "yarn" : "npm run"} tauri ${
packageManager === "npm" ? "--" : ""
To start, run ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri ${
packageManager === 'npm' ? '--' : ''
} dev
`);
},
};
`)
return await Promise.resolve()
}
}
export { vite };
export { vite }

View File

@@ -2,43 +2,44 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { Recipe } from "..";
import { join } from "path";
import { shell } from "../shell";
import { Recipe } from '..'
import { join } from 'path'
import { shell } from '../shell'
const completeLogMsg = `
Your installation completed.
To start, run yarn tauri:serve
`;
`
const vuecli: Recipe = {
descriptiveName: "Vue CLI",
shortName: "vuecli",
descriptiveName: 'Vue CLI',
shortName: 'vuecli',
extraNpmDevDependencies: [],
extraNpmDependencies: [],
configUpdate: ({ cfg }) => cfg,
preInit: async ({ cwd, cfg }) => {
// Vue CLI creates the folder for you
await shell("npx", ["@vue/cli", "create", `${cfg.appName}`], { cwd });
await shell('npx', ['@vue/cli', 'create', `${cfg.appName}`], { cwd })
await shell(
"npx",
'npx',
[
"@vue/cli",
"add",
"tauri",
"--appName",
'@vue/cli',
'add',
'tauri',
'--appName',
`${cfg.appName}`,
"--windowTitle",
`${cfg.windowTitle}`,
'--windowTitle',
`${cfg.windowTitle}`
],
{
cwd: join(cwd, cfg.appName),
cwd: join(cwd, cfg.appName)
}
);
)
},
postInit: async () => {
console.log(completeLogMsg);
},
};
console.log(completeLogMsg)
return await Promise.resolve()
}
}
export { vuecli };
export { vuecli }

View File

@@ -2,35 +2,35 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import execa from "execa";
import execa from 'execa'
export const shell = async (
command: string,
args?: string[],
options?: execa.Options,
log: boolean = false
) => {
): Promise<execa.ExecaReturnValue> => {
try {
if (options && options.shell === true) {
const stringCommand = [command, ...(!args ? [] : args)].join(" ");
if (log) console.log(`[running]: ${stringCommand}`);
const stringCommand = [command, ...(!args ? [] : args)].join(' ')
if (log) console.log(`[running]: ${stringCommand}`)
return await execa(stringCommand, {
stdio: "inherit",
stdio: 'inherit',
cwd: process.cwd(),
env: process.env,
...options,
});
...options
})
} else {
if (log) console.log(`[running]: ${command}`);
if (log) console.log(`[running]: ${command}`)
return await execa(command, args, {
stdio: "inherit",
stdio: 'inherit',
cwd: process.cwd(),
env: process.env,
...options,
});
...options
})
}
} catch (error) {
console.error("Error with command: %s", command);
throw new Error(error);
console.error('Error with command: %s', command)
throw new Error(error)
}
};
}

View File

@@ -1,8 +1,8 @@
import React from "react";
import logo from "./logo.svg";
import tauriCircles from "./tauri.svg";
import tauriWord from "./wordmark.svg";
import "./App.css";
import React from 'react'
import logo from './logo.svg'
import tauriCircles from './tauri.svg'
import tauriWord from './wordmark.svg'
import './App.css'
function App() {
return (
@@ -34,7 +34,7 @@ function App() {
</p>
</header>
</div>
);
)
}
export default App;
export default App

View File

@@ -1,8 +1,8 @@
import React from "react";
import logo from "./logo.svg";
import tauriCircles from "./tauri.svg";
import tauriWord from "./wordmark.svg";
import "./App.css";
import React from 'react'
import logo from './logo.svg'
import tauriCircles from './tauri.svg'
import tauriWord from './wordmark.svg'
import './App.css'
function App() {
return (
@@ -34,7 +34,7 @@ function App() {
</p>
</header>
</div>
);
)
}
export default App;
export default App

View File

@@ -3,24 +3,24 @@
// SPDX-License-Identifier: MIT
export interface TauriBuildConfig {
appName: string;
windowTitle: string;
appName: string
windowTitle: string
/**
* the path to the app's dist dir
* this path must contain your index.html file
*/
distDir: string;
distDir: string
/**
* the app's dev server URL, or the path to the directory containing an index.html to open
*/
devPath: string;
devPath: string
/**
* a shell command to run before `tauri dev` kicks in
*/
beforeDevCommand?: string;
beforeDevCommand?: string
/**
* a shell command to run before `tauri build` kicks in
*/
beforeBuildCommand?: string;
withGlobalTauri?: boolean;
beforeBuildCommand?: string
withGlobalTauri?: boolean
}

View File

@@ -5,7 +5,7 @@
export enum ManagementType {
Install,
InstallDev,
Update,
Update
}
export type Result = Map<ManagementType, string[]>;
export type Result = Map<ManagementType, string[]>