feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
{
"dependencies": {
"@eslint/compat": "^1.2.2"
}
}

View File

@@ -0,0 +1,23 @@
{
"name": "plugins",
"version": "1.0.0",
"private": true,
"author": "liyubei@bytedance.com",
"maintainers": [
"fanwenjie.fe@bytedance.com"
],
"dependencies": {
"@coze-arch/rush-clear-build-cache-plugin": "0.0.1-alpha.a8d5b5",
"@coze-arch/rush-dep-level-check-plugin": "0.0.1-alpha.f89072",
"@coze-arch/rush-fix-ts-refers-plugin": "alpha",
"@coze-arch/rush-increment-run-plugin": "0.0.2-alpha.88b122",
"@coze-arch/rush-publish-plugin": "alpha",
"@coze-arch/rush-run-tsc-plugin": "0.0.1-alpha.5f6259",
"json5": "^2.2.1",
"rush-init-project-plugin": "^0.11.0",
"typescript": "~5.8.2"
},
"devDependencies": {
"@types/node": "^18.6.3"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
"commands": [
{
"name": "clear-build-cache",
"description": "清理构建缓存",
"commandKind": "global",
"summary": "🚀 清理构建缓存",
"shellCommand": "rush-clear-build-cache",
"safeForSimultaneousRushProcesses": true
}
],
"parameters": []
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugin-manifest.schema.json",
"plugins": [
{
"pluginName": "@coze-arch/rush-clear-build-cache-plugin",
"description": "@coze-arch/rush-clear-build-cache-plugin",
"commandLineJsonFilePath": "./command-line.json"
}
]
}

View File

@@ -0,0 +1,11 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugin-manifest.schema.json",
"plugins": [
{
"pluginName": "@coze-arch/rush-dep-level-check-plugin",
"description": "@coze-arch/rush-dep-level-check-plugin",
"entryPoint": "./lib/index.js",
"associatedCommands": ["install", "update"]
}
]
}

View File

@@ -0,0 +1,47 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
"commands": [
{
"name": "fix-ts-refers",
"description": "Fix common project issues",
"commandKind": "global",
"summary": "⭐️️ Fix tsconfig.json and tsconfig.build.json",
"shellCommand": "rush-fix-ts-refers fix",
"safeForSimultaneousRushProcesses": true
}
],
"parameters": [
{
"parameterKind": "string",
"description": "Specify the package to fix",
"shortName": "-p",
"longName": "--package",
"argumentName": "PACKAGE",
"associatedCommands": ["fix-ts-refers"],
"required": false
},
{
"parameterKind": "flag",
"description": "Use cached files",
"shortName": "-c",
"longName": "--use-cached-files",
"associatedCommands": ["fix-ts-refers"],
"required": false
},
{
"parameterKind": "flag",
"description": "Submit changes",
"shortName": "-s",
"longName": "--submit-changes",
"associatedCommands": ["fix-ts-refers"],
"required": false
},
{
"parameterKind": "flag",
"description": "Shallow fix",
"longName": "--shallow",
"associatedCommands": ["fix-ts-refers"],
"required": false
}
]
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugin-manifest.schema.json",
"plugins": [
{
"pluginName": "@coze-arch/rush-fix-ts-refers-plugin",
"description": "rush plugin for auto fix ts references in ts projects",
"commandLineJsonFilePath": "./command-line.json"
}
]
}

View File

@@ -0,0 +1,68 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
"commands": [
{
"name": "increment",
"description": "增量运行指定的操作命令,基于变更文件分析影响的项目",
"commandKind": "global",
"summary": "🚀 增量运行操作命令",
"shellCommand": "rush-increment-run increment",
"safeForSimultaneousRushProcesses": true
}
],
"parameters": [
{
"parameterKind": "string",
"description": "变更文件列表,使用逗号分隔",
"shortName": "-f",
"longName": "--changed-files",
"argumentName": "FILES",
"associatedCommands": ["increment"],
"required": false
},
{
"parameterKind": "string",
"description": "变更文件列表所在文件路径",
"shortName": "-p",
"longName": "--changed-path",
"argumentName": "PATH",
"associatedCommands": ["increment"],
"required": false
},
{
"parameterKind": "string",
"description": "需要作对比的目标分支,使用该参数前建议先执行 `git fetch`,确保对比结果的正确性",
"shortName": "-b",
"longName": "--branch",
"argumentName": "BRANCH",
"associatedCommands": ["increment"],
"required": false
},
{
"parameterKind": "flag",
"description": "是否打印详细日志",
"shortName": "-v",
"longName": "--verbose",
"associatedCommands": ["increment"],
"required": false
},
{
"parameterKind": "string",
"description": "支持的增量操作命令",
"shortName": "-a",
"longName": "--action",
"argumentName": "ACTION",
"associatedCommands": ["increment"],
"required": true
},
{
"parameterKind": "string",
"description": "变更文件列表的分隔符",
"shortName": "-s",
"longName": "--separator",
"argumentName": "SEPARATOR",
"associatedCommands": ["increment"],
"required": false
}
]
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugin-manifest.schema.json",
"plugins": [
{
"pluginName": "@coze-arch/rush-increment-run-plugin",
"description": "incremently run commands for ci",
"commandLineJsonFilePath": "./command-line.json"
}
]
}

View File

@@ -0,0 +1,140 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
"commands": [
{
"name": "pub",
"commandKind": "global",
"summary": "⭐️️ Publish packages to npm",
"shellCommand": "rush-publish pub",
"safeForSimultaneousRushProcesses": true
},
{
"name": "change-x",
"commandKind": "global",
"summary": "⭐️️ generate change log",
"shellCommand": "rush-publish change",
"safeForSimultaneousRushProcesses": true
},
{
"name": "release",
"commandKind": "global",
"summary": "⭐️️ release packages",
"shellCommand": "rush-publish release",
"safeForSimultaneousRushProcesses": true
}
],
"parameters": [
{
"parameterKind": "string",
"description": "Enable dry run mode",
"shortName": "-d",
"longName": "--dry-run",
"argumentName": "DRY_RUN",
"associatedCommands": ["pub"],
"required": false
},
{
"parameterKind": "string",
"shortName": "-t",
"longName": "--to",
"description": "Publish specified packages and their downstream dependencies",
"argumentName": "TO",
"associatedCommands": ["pub"],
"required": false
},
{
"parameterKind": "string",
"shortName": "-f",
"longName": "--from",
"description": "Publish specified packages and their upstream/downstream dependencies",
"argumentName": "FROM",
"associatedCommands": ["pub"],
"required": false
},
{
"parameterKind": "string",
"shortName": "-o",
"longName": "--only",
"description": "Only publish specified packages",
"argumentName": "ONLY",
"associatedCommands": ["pub"],
"required": false
},
{
"parameterKind": "flag",
"shortName": "-s",
"longName": "--skip-commit",
"description": "Skip git commit",
"associatedCommands": ["pub"],
"required": false
},
{
"parameterKind": "flag",
"shortName": "-p",
"longName": "--skip-push",
"description": "Skip git push",
"associatedCommands": ["pub"],
"required": false
},
{
"parameterKind": "choice",
"alternatives": [
{
"name": "alpha",
"description": "Alpha version"
},
{
"name": "beta",
"description": "Beta version"
},
{
"name": "patch",
"description": "Patch version"
},
{
"name": "minor",
"description": "Minor version"
},
{
"name": "major",
"description": "Major version"
}
],
"shortName": "-b",
"longName": "--bump-type",
"description": "Version bump type (alpha/beta/patch/minor/major)",
"associatedCommands": ["pub"],
"required": false
},
{
"parameterKind": "flag",
"longName": "--amend-commit",
"shortName": "-a",
"description": "是否 amend commit 阶段",
"associatedCommands": ["change-x"]
},
{
"parameterKind": "flag",
"longName": "--ci",
"shortName": "-i",
"description": "是否在 CI 环境",
"associatedCommands": ["change-x"]
},
{
"parameterKind": "string",
"argumentName": "COMMIT_MSG",
"longName": "--commit-msg",
"shortName": "-c",
"description": "本次提交信息,默认读取 .git/COMMIT_EDITMSG",
"associatedCommands": ["change-x"]
},
{
"parameterKind": "string",
"argumentName": "COMMIT",
"longName": "--commit",
"shortName": "-c",
"description": "Git commit hash",
"associatedCommands": ["release"]
}
]
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugin-manifest.schema.json",
"plugins": [
{
"pluginName": "@coze-arch/rush-publish-plugin",
"description": "rush plugin to generate change log and publish packages",
"commandLineJsonFilePath": "./command-line.json"
}
]
}

View File

@@ -0,0 +1,17 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
"commands": [
{
"commandKind": "bulk",
"name": "ts-check",
"ignoreMissingScript": false,
"enableParallelism": true,
"shellCommand": "npm run prets-check --if-present && NODE_OPTIONS='--max-old-space-size=16384' tsc -b tsconfig.build.json",
"allowWarningsInSuccessfulBuild": true,
"summary": "⭐️️ Run tsc command for each package",
"safeForSimultaneousRushProcesses": true
// "incremental": true
}
],
"parameters": []
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugin-manifest.schema.json",
"plugins": [
{
"pluginName": "@coze-arch/rush-run-tsc-plugin",
"description": "Rush plugin for run tsc",
"commandLineJsonFilePath": "./command-line.json"
}
]
}

View File

@@ -0,0 +1,45 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
"commands": [
{
"name": "init-project",
"commandKind": "global",
"summary": "Initialize project in this monorepo",
"shellCommand": "rush-init-project",
"safeForSimultaneousRushProcesses": true
}
],
"parameters": [
{
"parameterKind": "string",
"description": "Provide predefined answers with JSON string",
"shortName": "-a",
"longName": "--answer",
"argumentName": "ANSWER",
"associatedCommands": ["init-project"],
"required": false
},
{
"parameterKind": "flag",
"description": "Provide the option isDryRun in plugin context",
"longName": "--dry-run",
"associatedCommands": ["init-project"],
"required": false
},
{
"parameterKind": "flag",
"description": "Provide verbose log output",
"shortName": "-v",
"longName": "--verbose",
"associatedCommands": ["init-project"],
"required": false
},
{
"parameterKind": "flag",
"description": "Provide terminal ui operation",
"longName": "--ui",
"associatedCommands": ["init-project"],
"required": false
}
]
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugin-manifest.schema.json",
"plugins": [
{
"pluginName": "rush-init-project-plugin",
"description": "Rush plugin for initialize project in monorepo",
"commandLineJsonFilePath": "command-line.json"
}
]
}

View File

@@ -0,0 +1,85 @@
const chalk = require('chalk')
const spawn = require('cross-spawn')
const defaultConfig = require('cz-customizable');
const { getChangedPackages } = require('./utils')
const typesConfig = [
{ value: 'feat', name: 'A new feature' },
{ value: 'fix', name: 'A bug fix' },
{ value: 'docs', name: 'Documentation only changes' },
{
value: 'style',
name: 'Changes that do not affect the meaning of the code\n (white-space, formatting, missing semi-colons, etc)',
},
{
value: 'refactor',
name: 'A code change that neither fixes a bug nor adds a feature',
},
{
value: 'perf',
name: 'A code change that improves performance',
},
{ value: 'test', name: 'Adding missing tests' },
{
value: 'chore',
name: 'Changes to the build process or auxiliary tools',
},
{
value: 'build',
name: 'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
},
{
value: 'ci',
name: 'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
},
{
value: 'revert',
name: 'Reverts a previous commit',
},
]
const { stdout = '' } = spawn.sync(`git diff --staged --name-only`, {
shell: true,
encoding: 'utf8',
stdio: 'pipe',
})
const changedFiles = stdout.split('\n').filter(Boolean)
const changeSet = getChangedPackages(changedFiles)
if (changeSet.size > 1) {
process.stderr.write(
`${[
chalk.yellow(`检测到当前提交可能涉及到多个包的改动,请注意拆分提交粒度`),
].join('\n')}\n`,
)
changeSet.clear()
changeSet.add('multiple')
}
const changedScopes = [...changeSet]
module.exports = {
...defaultConfig,
types: typesConfig.map(({ value, name }) => {
return {
name: `${value}:${new Array(10 - value.length)
.fill(' ')
.join('')}${name}`,
value,
}
}),
messages: {
...defaultConfig.messages,
type: "Select the type of change that you're committing",
scope: 'Ensure the scope of this change',
subject: 'Write a short, imperative tense description of the change',
body: 'Provide a longer description of the change. Use "|" to break new line:\n',
breaking: 'List any BREAKING CHANGES (optional):\n',
confirmCommit: 'Are you sure you want to proceed with the commit above?',
},
scopes: changedScopes.join(','),
allowCustomScopes: false,
skipQuestions: ['customScope', 'footer', 'body'],
allowBreakingChanges: ['feat', 'fix'],
}

View File

@@ -0,0 +1,14 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'header-max-length': [2, 'always', 150],
'subject-full-stop': [0, 'never'],
'subject-case': [
2,
'never',
[
'upper-case', // UPPERCASE
],
],
},
};

View File

@@ -0,0 +1,21 @@
{
"name": "rush-commitlint",
"version": "1.0.0",
"private": true,
"author": "fanwenjie.fe@bytedance.com",
"config": {
"commitizen": {
"path": "common/autoinstallers/rush-commitlint/node_modules/cz-customizable"
}
},
"dependencies": {
"@commitlint/cli": "^17.2.0",
"@commitlint/config-conventional": "^17.2.0",
"@rushstack/rush-sdk": "5.100.2",
"commitizen": "^4.2.6",
"cz-customizable": "^7.2.1"
},
"devDependencies": {
"@types/node": "^18.11.9"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
const { RushConfiguration } = require('@rushstack/rush-sdk')
const getRushConfiguration = (function () {
let rushConfiguration = null
return function () {
// eslint-disable-next-line
return (rushConfiguration ||= RushConfiguration.loadFromDefaultLocation({
startingFolder: process.cwd(),
}))
}
})()
function getChangedPackages(changedFiles) {
const changedPackages = new Set()
try {
const rushConfiguration = getRushConfiguration()
const { rushJsonFolder } = rushConfiguration
const lookup = rushConfiguration.getProjectLookupForRoot(rushJsonFolder)
for (const file of changedFiles) {
const project = lookup.findChildPath(file)
// 如果没找到注册的包信息,则认为是通用文件更改
const packageName = project?.packageName || 'misc'
if (!changedPackages.has(packageName)) {
changedPackages.add(packageName)
}
}
} catch (e) {
console.error(e)
throw e
}
return changedPackages
}
exports.getChangedPackages = getChangedPackages
exports.getRushConfiguration = getRushConfiguration

View File

@@ -0,0 +1,77 @@
const {
excludeIgnoredFiles,
groupChangedFilesByProject,
getRushConfiguration,
} = require('./utils');
const micromatch = require('micromatch');
const path = require('path');
const fs = require('fs');
module.exports = {
'**/*.{ts,tsx,js,jsx,mjs}': async files => {
const match = micromatch.not(files, [
'**/common/_templates/!(_*)/**/(.)?*',
]);
const changedFileGroup = await groupChangedFilesByProject(match);
const eslintCmds = Object.entries(changedFileGroup)
.filter(([packageName]) =>
packageName !== '@coze-arch/arco-icon' && packageName !== '@coze-arch/arco-illustration')
.map(
([packageName, changedFiles]) => {
const rushConfiguration = getRushConfiguration();
const { projectFolder, packageName: name } =
rushConfiguration.getProjectByName(packageName);
const filesToCheck = changedFiles
.map(f => path.relative(projectFolder, f))
.join(' ');
// TSESTREE_SINGLE_RUN doc https://typescript-eslint.io/packages/parser/#allowautomaticsingleruninference
// 切换到项目文件夹,并运行 ESLint 命令
const cmd = [
`cd ${projectFolder}`,
`TSESTREE_SINGLE_RUN=true eslint --fix --cache ${filesToCheck} --no-error-on-unmatched-pattern`,
].join(' && ');
return {
name,
cmd,
};
},
);
if (!eslintCmds.length) return [];
if (eslintCmds.length > 16) {
console.log(
`For performance reason, skip ESlint detection due to ${eslintCmds.length} eslint commands.`,
);
return [];
}
return [
// 这里不能直接返回 eslintCmds 数组,因为 lint-staged 会依次串行执行每个命令
// 而 concurrently 会并行执行多个命令
`concurrently --max-process 8 --names ${eslintCmds
.map(r => `${r.name}`)
.join(',')} --kill-others-on-fail ${eslintCmds
.map(r => `"${r.cmd}"`)
.join(' ')}`,
];
},
'**/*.{less,scss,css}': files => {
// 暂时只修复,不报错卡点
return [`stylelint ${files.join(' ')} --fix || exit 0`];
},
'**/package.json': async files => {
const match = micromatch.not(files, [
'**/common/_templates/!(_*)/**/(.)?*',
]);
const filesToLint = await excludeIgnoredFiles(match);
if (!filesToLint) return [];
return [
// https://eslint.org/docs/latest/flags/#enable-feature-flags-with-the-cli
// eslint v9默认从cwd找配置这里需要使用 unstable_config_lookup_from_file 配置,否则会报错
`eslint --cache ${filesToLint} --flag unstable_config_lookup_from_file`,
`prettier ${filesToLint} --write`,
];
},
'**/!(package).json': 'prettier --write',
};

View File

@@ -0,0 +1,18 @@
{
"name": "rush-lint-staged",
"version": "1.0.0",
"private": true,
"author": "fanwenjie.fe@bytedance.com",
"resolutions": {},
"dependencies": {
"@microsoft/rush-lib": "5.147.1",
"concurrently": "^7.6.0",
"eslint": "~9.12.0",
"lint-staged": "^13.0.3",
"micromatch": "^4.0.5",
"prettier": "^2.7.1",
"pretty-quick": "^3.1.3",
"stylelint": "^16.7.0",
"typescript": "~5.8.2"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,106 @@
const path = require('path');
const { ESLint } = require('eslint');
const { RushConfiguration } = require('@microsoft/rush-lib');
const getRushConfiguration = (function () {
let rushConfiguration = null;
return function () {
// eslint-disable-next-line
return (rushConfiguration ||= RushConfiguration.loadFromDefaultLocation({
startingFolder: process.cwd(),
}));
};
})();
// 获取变更文件所在的项目路径
function withProjectFolder(changedFiles) {
const projectFolders = [];
try {
const rushConfiguration = getRushConfiguration();
const { rushJsonFolder } = rushConfiguration;
const lookup = rushConfiguration.getProjectLookupForRoot(rushJsonFolder);
for (const file of changedFiles) {
const project = lookup.findChildPath(path.relative(rushJsonFolder, file));
// 忽略不在 rush.json 内定义的项目
if (project) {
const projectFolder = project?.projectFolder ?? rushJsonFolder;
const packageName = project?.packageName;
projectFolders.push({
file,
projectFolder,
packageName,
});
}
}
} catch (e) {
console.error(e);
throw e;
}
return projectFolders;
}
async function excludeIgnoredFiles(changedFiles) {
try {
const eslintInstances = new Map();
const changedFilesWithIgnored = await Promise.all(
withProjectFolder(changedFiles).map(async ({ file, projectFolder }) => {
let eslint = eslintInstances.get(projectFolder);
if (!eslint) {
eslint = new ESLint({ cwd: projectFolder });
eslintInstances.set(projectFolder, eslint);
}
return {
file,
isIgnored: await eslint.isPathIgnored(file),
};
}),
);
return changedFilesWithIgnored
.filter(change => !change.isIgnored)
.map(change => change.file)
.join(' ');
} catch (e) {
console.error(e);
throw e;
}
}
// 获取发生变更的项目路径
function getChangedProjects(changedFiles) {
const changedProjectFolders = new Set();
const changedProjects = new Set();
withProjectFolder(changedFiles).forEach(({ projectFolder, packageName }) => {
if (!changedProjectFolders.has(projectFolder)) {
changedProjectFolders.add(projectFolder);
changedProjects.add({
packageName,
projectFolder,
});
}
});
return [...changedProjects];
}
const groupChangedFilesByProject = changedFiles => {
const changedFilesMap = withProjectFolder(changedFiles);
const result = changedFilesMap.reduce((pre, cur) => {
pre[cur.packageName] ||= [];
pre[cur.packageName].push(cur.file);
return pre;
}, {});
return result;
};
exports.excludeIgnoredFiles = excludeIgnoredFiles;
exports.getRushConfiguration = getRushConfiguration;
exports.getChangedProjects = getChangedProjects;
exports.groupChangedFilesByProject = groupChangedFilesByProject;