mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-24 07:49:47 +08:00
feat(projects): 1.0 beta
This commit is contained in:
5
packages/scripts/src/commands/cleanup.ts
Normal file
5
packages/scripts/src/commands/cleanup.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { rimraf } from 'rimraf';
|
||||
|
||||
export async function cleanup(paths: string[]) {
|
||||
await rimraf(paths, { glob: true });
|
||||
}
|
75
packages/scripts/src/commands/git-commit.ts
Normal file
75
packages/scripts/src/commands/git-commit.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import path from 'node:path';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import enquirer from 'enquirer';
|
||||
import { bgRed, red, green } from 'kolorist';
|
||||
import { execCommand } from '../shared';
|
||||
import type { CliOption } from '../types';
|
||||
|
||||
interface PromptObject {
|
||||
types: string;
|
||||
scopes: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export async function gitCommit(
|
||||
gitCommitTypes: CliOption['gitCommitTypes'],
|
||||
gitCommitScopes: CliOption['gitCommitScopes']
|
||||
) {
|
||||
const typesChoices = gitCommitTypes.map(([name, title]) => {
|
||||
const nameWithSuffix = `${name}:`;
|
||||
|
||||
const message = `${nameWithSuffix.padEnd(12)}${title}`;
|
||||
|
||||
return {
|
||||
name,
|
||||
message
|
||||
};
|
||||
});
|
||||
|
||||
const scopesChoices = gitCommitScopes.map(([name, title]) => ({
|
||||
name,
|
||||
message: `${name.padEnd(30)} (${title})`
|
||||
}));
|
||||
|
||||
const result = await enquirer.prompt<PromptObject>([
|
||||
{
|
||||
name: 'types',
|
||||
type: 'select',
|
||||
message: 'Please select a type',
|
||||
choices: typesChoices
|
||||
},
|
||||
{
|
||||
name: 'scopes',
|
||||
type: 'select',
|
||||
message: 'Please select a scope',
|
||||
choices: scopesChoices
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'text',
|
||||
message: 'Please enter a description'
|
||||
}
|
||||
]);
|
||||
|
||||
const commitMsg = `${result.types}(${result.scopes}): ${result.description}`;
|
||||
|
||||
await execCommand('git', ['commit', '-m', commitMsg], { stdio: 'inherit' });
|
||||
}
|
||||
|
||||
export async function gitCommitVerify() {
|
||||
const gitPath = await execCommand('git', ['rev-parse', '--show-toplevel']);
|
||||
|
||||
const gitMsgPath = path.join(gitPath, '.git', 'COMMIT_EDITMSG');
|
||||
|
||||
const commitMsg = readFileSync(gitMsgPath, 'utf8').trim();
|
||||
|
||||
const REG_EXP = /(?<type>[a-z]+)(\((?<scope>.+)\))?(?<breaking>!)?: (?<description>.+)/i;
|
||||
|
||||
if (!REG_EXP.test(commitMsg)) {
|
||||
throw new Error(
|
||||
`${bgRed(' ERROR ')} ${red('git commit message must match the Conventional Commits standard!')}\n\n${green(
|
||||
'Recommended to use the command `pnpm commit` to generate Conventional Commits compliant commit information.\nGet more info about Conventional Commits, follow this link: https://conventionalcommits.org'
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
5
packages/scripts/src/commands/index.ts
Normal file
5
packages/scripts/src/commands/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export * from './git-commit';
|
||||
export * from './cleanup';
|
||||
export * from './update-pkg';
|
||||
export * from './prettier';
|
||||
export * from './lint-staged';
|
5
packages/scripts/src/commands/lint-staged.ts
Normal file
5
packages/scripts/src/commands/lint-staged.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export async function execLintStaged(config: Record<string, string | string[]>) {
|
||||
const lintStaged = (await import('lint-staged')).default;
|
||||
|
||||
return lintStaged({ config, allowEmpty: true });
|
||||
}
|
7
packages/scripts/src/commands/prettier.ts
Normal file
7
packages/scripts/src/commands/prettier.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { execCommand } from '../shared';
|
||||
|
||||
export async function prettierWrite(writeGlob: string[]) {
|
||||
await execCommand('npx', ['prettier', '--write', '.', ...writeGlob], {
|
||||
stdio: 'inherit'
|
||||
});
|
||||
}
|
5
packages/scripts/src/commands/update-pkg.ts
Normal file
5
packages/scripts/src/commands/update-pkg.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { execCommand } from '../shared';
|
||||
|
||||
export async function updatePkg(args: string[] = ['--deep', '-u']) {
|
||||
execCommand('npx', ['ncu', ...args], { stdio: 'inherit' });
|
||||
}
|
74
packages/scripts/src/config/index.ts
Normal file
74
packages/scripts/src/config/index.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { loadConfig } from 'c12';
|
||||
import type { CliOption } from '../types';
|
||||
|
||||
const eslintExt = '*.{js,jsx,mjs,cjs,ts,tsx,vue}';
|
||||
|
||||
const defaultOptions: CliOption = {
|
||||
cwd: process.cwd(),
|
||||
cleanupDirs: [
|
||||
'**/dist',
|
||||
'**/package-lock.json',
|
||||
'**/yarn.lock',
|
||||
'**/pnpm-lock.yaml',
|
||||
'**/node_modules',
|
||||
'!node_modules/**'
|
||||
],
|
||||
gitCommitTypes: [
|
||||
['feat', 'A new feature'],
|
||||
['fix', 'A bug fix'],
|
||||
['docs', 'Documentation only changes'],
|
||||
['style', 'Changes that do not affect the meaning of the code'],
|
||||
['refactor', 'A code change that neither fixes a bug nor adds a feature'],
|
||||
['perf', 'A code change that improves performance'],
|
||||
['test', 'Adding missing tests or correcting existing tests'],
|
||||
['build', 'Changes that affect the build system or external dependencies'],
|
||||
['ci', 'Changes to our CI configuration files and scripts'],
|
||||
['chore', "Other changes that don't modify src or test files"],
|
||||
['revert', 'Reverts a previous commit']
|
||||
],
|
||||
gitCommitScopes: [
|
||||
['projects', 'project'],
|
||||
['components', 'components'],
|
||||
['hooks', 'hook functions'],
|
||||
['utils', 'utils functions'],
|
||||
['types', 'TS declaration'],
|
||||
['styles', 'style'],
|
||||
['deps', 'project dependencies'],
|
||||
['release', 'release project'],
|
||||
['other', 'other changes']
|
||||
],
|
||||
ncuCommandArgs: ['--deep', '-u'],
|
||||
prettierWriteGlob: [
|
||||
`!**/${eslintExt}`,
|
||||
'!*.min.*',
|
||||
'!CHANGELOG.md',
|
||||
'!dist',
|
||||
'!LICENSE*',
|
||||
'!output',
|
||||
'!coverage',
|
||||
'!public',
|
||||
'!temp',
|
||||
'!package-lock.json',
|
||||
'!pnpm-lock.yaml',
|
||||
'!yarn.lock',
|
||||
'!.github',
|
||||
'!__snapshots__',
|
||||
'!node_modules'
|
||||
],
|
||||
lintStagedConfig: {
|
||||
[eslintExt]: 'eslint --fix',
|
||||
'*': 'sa prettier-write'
|
||||
}
|
||||
};
|
||||
|
||||
export async function loadCliOptions(overrides?: Partial<CliOption>, cwd = process.cwd()) {
|
||||
const { config } = await loadConfig<Partial<CliOption>>({
|
||||
name: 'soybean',
|
||||
defaults: defaultOptions,
|
||||
overrides,
|
||||
cwd,
|
||||
packageJson: true
|
||||
});
|
||||
|
||||
return config as CliOption;
|
||||
}
|
70
packages/scripts/src/index.ts
Executable file
70
packages/scripts/src/index.ts
Executable file
@ -0,0 +1,70 @@
|
||||
import cac from 'cac';
|
||||
import { blue, lightGreen } from 'kolorist';
|
||||
import { version } from '../package.json';
|
||||
import { cleanup, updatePkg, gitCommit, gitCommitVerify, prettierWrite, execLintStaged } from './commands';
|
||||
import { loadCliOptions } from './config';
|
||||
|
||||
type Command = 'cleanup' | 'update-pkg' | 'git-commit' | 'git-commit-verify' | 'prettier-write' | 'lint-staged';
|
||||
|
||||
type CommandAction<A extends object> = (args?: A) => Promise<void> | void;
|
||||
|
||||
type CommandWithAction<A extends object = object> = Record<Command, { desc: string; action: CommandAction<A> }>;
|
||||
|
||||
interface CommandArg {
|
||||
total?: boolean;
|
||||
}
|
||||
|
||||
export async function setupCli() {
|
||||
const cliOptions = await loadCliOptions();
|
||||
|
||||
const cli = cac(blue('soybean'));
|
||||
|
||||
cli.version(lightGreen(version)).help();
|
||||
|
||||
const commands: CommandWithAction<CommandArg> = {
|
||||
cleanup: {
|
||||
desc: 'delete dirs: node_modules, dist, etc.',
|
||||
action: async () => {
|
||||
await cleanup(cliOptions.cleanupDirs);
|
||||
}
|
||||
},
|
||||
'update-pkg': {
|
||||
desc: 'update package.json dependencies versions',
|
||||
action: async () => {
|
||||
await updatePkg(cliOptions.ncuCommandArgs);
|
||||
}
|
||||
},
|
||||
'git-commit': {
|
||||
desc: 'git commit, generate commit message which match Conventional Commits standard',
|
||||
action: async () => {
|
||||
await gitCommit(cliOptions.gitCommitTypes, cliOptions.gitCommitScopes);
|
||||
}
|
||||
},
|
||||
'git-commit-verify': {
|
||||
desc: 'verify git commit message, make sure it match Conventional Commits standard',
|
||||
action: async () => {
|
||||
await gitCommitVerify();
|
||||
}
|
||||
},
|
||||
'prettier-write': {
|
||||
desc: 'run prettier --write',
|
||||
action: async () => {
|
||||
await prettierWrite(cliOptions.prettierWriteGlob);
|
||||
}
|
||||
},
|
||||
'lint-staged': {
|
||||
desc: 'run lint-staged',
|
||||
action: async () => {
|
||||
await execLintStaged(cliOptions.lintStagedConfig);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const [command, { desc, action }] of Object.entries(commands)) {
|
||||
cli.command(command, lightGreen(desc)).action(action);
|
||||
}
|
||||
|
||||
cli.parse();
|
||||
}
|
||||
|
||||
setupCli();
|
7
packages/scripts/src/shared/index.ts
Normal file
7
packages/scripts/src/shared/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import type { Options } from 'execa';
|
||||
|
||||
export async function execCommand(cmd: string, args: string[], options?: Options) {
|
||||
const { execa } = await import('execa');
|
||||
const res = await execa(cmd, args, options);
|
||||
return res?.stdout?.trim() || '';
|
||||
}
|
37
packages/scripts/src/types/index.ts
Normal file
37
packages/scripts/src/types/index.ts
Normal file
@ -0,0 +1,37 @@
|
||||
export interface CliOption {
|
||||
/**
|
||||
* the project root directory
|
||||
*/
|
||||
cwd: string;
|
||||
/**
|
||||
* cleanup dirs
|
||||
* @default
|
||||
* ```json
|
||||
* ["** /dist", "** /pnpm-lock.yaml", "** /node_modules", "!node_modules/**"]
|
||||
* ```
|
||||
* @description glob pattern syntax {@link https://github.com/isaacs/minimatch}
|
||||
*/
|
||||
cleanupDirs: string[];
|
||||
/**
|
||||
* git commit types
|
||||
*/
|
||||
gitCommitTypes: [string, string][];
|
||||
/**
|
||||
* git commit scopes
|
||||
*/
|
||||
gitCommitScopes: [string, string][];
|
||||
/**
|
||||
* npm-check-updates command args
|
||||
* @default ["--deep","-u"]
|
||||
*/
|
||||
ncuCommandArgs: string[];
|
||||
/**
|
||||
* prettier write glob
|
||||
* @description glob pattern syntax {@link https://github.com/micromatch/micromatch}
|
||||
*/
|
||||
prettierWriteGlob: string[];
|
||||
/**
|
||||
* lint-staged config
|
||||
*/
|
||||
lintStagedConfig: Record<string, string | string[]>;
|
||||
}
|
Reference in New Issue
Block a user