-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
600 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import { | ||
join, | ||
isAbsolute, | ||
relative, | ||
} from 'node:path'; | ||
import { | ||
existsSync, | ||
statSync, | ||
Stats, | ||
copyFileSync, | ||
} from 'node:fs'; | ||
|
||
import { green, italic } from 'chalk'; | ||
|
||
import { registerTask, Task, TaskState } from '../task'; | ||
import { forEachFiles, makeDir } from '../utils'; | ||
|
||
export type FileConfig = { | ||
source: string; | ||
dist: string; | ||
filter(file: string, stat: Stats): boolean; | ||
}[]; | ||
|
||
export class FileTask extends Task { | ||
static getMaxConcurrent() { | ||
return 1; | ||
} | ||
|
||
getTitle() { | ||
return 'Copy files'; | ||
} | ||
|
||
async execute(workspace: string, configArray: FileConfig): Promise<TaskState> { | ||
let hasError = false; | ||
|
||
for (const config of configArray) { | ||
// 将相对路径转成绝对路径 | ||
const source = isAbsolute(config.source) | ||
? config.source | ||
: join(workspace, config.source); | ||
const dist = isAbsolute(config.dist) | ||
? config.dist | ||
: join(workspace, config.dist); | ||
|
||
const dataItem = this.getCache(source); | ||
|
||
// 新的缓存数据 | ||
const newDataItem: { | ||
[key: string]: number; | ||
} = {}; | ||
|
||
// 编译的文件是否有变化 | ||
let changed = false; | ||
const fileArray: { | ||
source: string; | ||
dist: string; | ||
}[] = []; | ||
|
||
// 获取编译的文件列表 | ||
try { | ||
await forEachFiles(source, (file, stat) => { | ||
const relativePath = relative(source, file); | ||
const distFile = join(dist, relativePath); | ||
if (config.filter && !config.filter(file, stat)) { | ||
return; | ||
} | ||
if (stat.isDirectory()) { | ||
return; | ||
} | ||
fileArray.push({ | ||
source: file, | ||
dist: distFile, | ||
}); | ||
}); | ||
|
||
this.print(`${italic(`${config.source} => ${config.dist}`)} Copy files: ${green(fileArray.length)}`); | ||
|
||
fileArray.forEach((item) => { | ||
const stat = statSync(item.source); | ||
const mtime = stat.mtime.getTime(); | ||
if ( | ||
!dataItem[item.source] | ||
|| mtime !== dataItem[item.source] | ||
|| !existsSync(item.dist) | ||
) { | ||
changed = true; | ||
} | ||
newDataItem[item.source] = mtime; | ||
}); | ||
} catch (error) { | ||
const err = error as Error; | ||
this.print(err.message); | ||
hasError = true; | ||
} | ||
|
||
// 没有变化 | ||
if (changed === false) { | ||
continue; | ||
} | ||
|
||
// 实际拷贝 | ||
try { | ||
for (const item of fileArray) { | ||
const baseDir = join(item.dist, '..'); | ||
if (!existsSync(baseDir)) { | ||
await makeDir(baseDir); | ||
} | ||
if (existsSync(item.source) && !existsSync(item.dist)) { | ||
copyFileSync(item.source, item.dist); | ||
} | ||
} | ||
|
||
// 有变化的时候,更新缓存 | ||
this.setCache(source, newDataItem); | ||
} catch (error) { | ||
const err = error as Error; | ||
this.print(err.message); | ||
hasError = true; | ||
} | ||
} | ||
|
||
return hasError ? TaskState.error : TaskState.success; | ||
} | ||
} | ||
registerTask('file', FileTask); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { TscConfig, TscTask } from './tsc'; | ||
import { RepoConfig, RepoTask } from './repo'; | ||
import { LessConfig, LessTask } from './less'; | ||
import { FileConfig, FileTask } from './file'; | ||
|
||
/** | ||
* 任务配置 | ||
*/ | ||
export type ConfigType = { | ||
tsc: TscConfig, | ||
repo: RepoConfig, | ||
less: LessConfig, | ||
file: FileConfig, | ||
}; | ||
|
||
/** | ||
* 任务列表 | ||
*/ | ||
export const Task = { | ||
tsc: TscTask, | ||
repo: RepoTask, | ||
less: LessTask, | ||
file: FileTask, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { | ||
join, isAbsolute, | ||
} from 'node:path'; | ||
import { | ||
existsSync, | ||
statSync, | ||
} from 'node:fs'; | ||
import { cpus } from 'node:os'; | ||
|
||
import { green, italic } from 'chalk'; | ||
|
||
import { registerTask, Task, TaskState } from '../task'; | ||
import { bash } from '../utils'; | ||
|
||
export type LessConfig = { | ||
source: string; | ||
dist: string; | ||
compress: boolean; | ||
}[]; | ||
|
||
export class LessTask extends Task { | ||
static getMaxConcurrent() { | ||
return cpus().length; | ||
} | ||
|
||
getTitle() { | ||
return 'Compile with less'; | ||
} | ||
|
||
async execute(workspace: string, configArray: LessConfig): Promise<TaskState> { | ||
let hasError = false; | ||
|
||
for (const config of configArray) { | ||
// 将相对路径转成绝对路径 | ||
const path = isAbsolute(config.source) ? config.source : join(workspace, config.source); | ||
|
||
const dataItem = this.getCache(path); | ||
|
||
// 新的缓存数据 | ||
const newDataItem: { | ||
[key: string]: number; | ||
} = {}; | ||
|
||
// 编译的文件是否有变化 | ||
let changed = false; | ||
|
||
// 获取编译的文件列表 | ||
try { | ||
const fileArray: string[] = [ | ||
path, | ||
]; | ||
const out = './.less.cache.json'; | ||
await bash('npx', ['lessc', '--depends', config.source, out], { | ||
cwd: workspace, | ||
}, (data) => { | ||
let str = data.toString(); | ||
if (str.startsWith(out)) { | ||
str = str.substring(out.length + 2); | ||
} | ||
str.split(/\.less /).forEach((fileWithoutExt) => { | ||
const file = `${fileWithoutExt}.less`; | ||
if (existsSync(file)) { | ||
fileArray.push(file); | ||
} | ||
}); | ||
}); | ||
this.print(`${italic(config.source)} Compile files: ${green(fileArray.length)}`); | ||
|
||
fileArray.forEach((file) => { | ||
const stat = statSync(file); | ||
const mtime = stat.mtime.getTime(); | ||
if (!dataItem[file] || mtime !== dataItem[file]) { | ||
changed = true; | ||
} | ||
newDataItem[file] = mtime; | ||
}); | ||
} catch (error) { | ||
const err = error as Error; | ||
this.print(err.message); | ||
hasError = true; | ||
} | ||
|
||
// 没有变化 | ||
if (changed === false) { | ||
continue; | ||
} | ||
|
||
// 实际编译 | ||
try { | ||
await bash('npx', ['lessc', config.source, config.dist], { | ||
cwd: workspace, | ||
}); | ||
|
||
// 有变化的时候,更新缓存 | ||
this.setCache(path, newDataItem); | ||
} catch (error) { | ||
const err = error as Error; | ||
this.print(err.message); | ||
hasError = true; | ||
} | ||
} | ||
|
||
return hasError ? TaskState.error : TaskState.success; | ||
} | ||
} | ||
registerTask('less', LessTask); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { | ||
join, | ||
isAbsolute, | ||
} from 'node:path'; | ||
import { | ||
createWriteStream, | ||
WriteStream, | ||
} from 'node:fs'; | ||
|
||
import { italic } from 'chalk'; | ||
|
||
import { registerTask, Task, TaskState } from '../task'; | ||
import { bash } from '../utils'; | ||
|
||
export type NPMConfig = { | ||
// 安装的时候输出的信息 | ||
message: string; | ||
// 执行 NPM 命令的路径 | ||
path: string; | ||
// 执行的参数 | ||
params: string[], | ||
// 错误的时候输出的信息 | ||
detail: string; | ||
// 存放日志的路径,当没有设置的时候,会将日志输出到控制台 | ||
logFile?: string, | ||
}[]; | ||
|
||
export class FileTask extends Task { | ||
static getMaxConcurrent() { | ||
return 1; | ||
} | ||
|
||
getTitle() { | ||
return 'Run npm command'; | ||
} | ||
|
||
async execute(workspace: string, configArray: NPMConfig): Promise<TaskState> { | ||
let hasError = false; | ||
|
||
for (const config of configArray) { | ||
// 将相对路径转成绝对路径 | ||
const source = isAbsolute(config.path) | ||
? config.path | ||
: join(workspace, config.path); | ||
|
||
this.print(italic(`npm ${config.params.join(' ')}`)); | ||
if (config.message) { | ||
this.print(italic(config.message)); | ||
} | ||
this.print(`Execution Path: ${config.path}`); | ||
if (config.logFile) { | ||
this.print(`Log file: ${config.logFile}`); | ||
} | ||
|
||
// 执行命令 | ||
try { | ||
let writeStream: WriteStream | undefined; | ||
if (config.logFile) { | ||
writeStream = createWriteStream(config.logFile, { flags: 'a' }); | ||
} | ||
await bash('npm', config.params, { | ||
cwd: source, | ||
}, (data) => { | ||
if (writeStream) { | ||
writeStream.write(data.toString()); | ||
} else { | ||
this.print(data.toString()); | ||
} | ||
}); | ||
if (writeStream) { | ||
writeStream.close(); | ||
} | ||
} catch (error) { | ||
const err = error as Error; | ||
this.print(err.message); | ||
hasError = true; | ||
} | ||
} | ||
|
||
return hasError ? TaskState.error : TaskState.success; | ||
} | ||
} | ||
registerTask('file', FileTask); |
Oops, something went wrong.