Skip to content
This repository has been archived by the owner on Jul 2, 2020. It is now read-only.

Commit

Permalink
fix: invoke copy file (#81)
Browse files Browse the repository at this point in the history
* fix: invoke copy file

* fix: add copy ignore
  • Loading branch information
echosoar committed Mar 13, 2020
1 parent 96c1850 commit 9558410
Show file tree
Hide file tree
Showing 22 changed files with 216 additions and 120 deletions.
40 changes: 11 additions & 29 deletions packages/faas-cli-plugin-package/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import {
writeFileSync,
writeJSON,
} from 'fs-extra';
import * as globby from 'globby';
import * as micromatch from 'micromatch';
import { commonPrefix, formatLayers } from './utils';
import {
tsCompile,
tsIntegrationProjectCompile,
copyFiles,
} from '@midwayjs/faas-util-ts-compile';
import { exec } from 'child_process';
import * as archiver from 'archiver';
Expand Down Expand Up @@ -197,35 +197,17 @@ export class PackagePlugin extends BasePlugin {
this.core.cli.log('Copy Files to build directory...');
// copy packages config files
const packageObj: any = this.core.service.package || {};
const include = await globby(
[
this.options.sourceDir || 'src',
'*.yml',
'*.js',
'*.json',
'app',
'config',
].concat(packageObj.include || []),
{ cwd: this.servicePath }
);
const exclude = await globby(packageObj.exclude || [], {
cwd: this.servicePath,
});
const paths = include.filter((filePath: string) => {
return exclude.indexOf(filePath) === -1;
});
if (paths.length) {
this.core.cli.log(` - Copy files`);
}
await Promise.all(
paths.map((path: string) => {
await copyFiles({
sourceDir: this.servicePath,
targetDir: this.midwayBuildPath,
include: [this.options.sourceDir || 'src'].concat(
packageObj.include || []
),
exclude: packageObj.exclude,
log: path => {
this.core.cli.log(` ◎ Copy ${path}`);
return copy(
join(this.servicePath, path),
join(this.midwayBuildPath, path)
);
})
);
},
});
if (this.codeAnalyzeResult.integrationProject) {
await writeJSON(join(this.midwayBuildPath, 'package.json'), {
name: this.codeAnalyzeResult.projectType,
Expand Down
1 change: 1 addition & 0 deletions packages/faas-util-ts-compile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"typings": "dist/index.d.ts",
"dependencies": {
"fs-extra": "^8.1.0",
"globby": "^10.0.1",
"midway-bin": "beta"
},
"scripts": {
Expand Down
72 changes: 42 additions & 30 deletions packages/faas-util-ts-compile/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { join, relative, resolve } from 'path';
import { readFileSync, existsSync } from 'fs-extra';
import { BuildCommand } from 'midway-bin';
export * from './utils';
import { combineTsConfig } from './utils';

export const tsIntegrationProjectCompile = async (baseDir, options: {
buildRoot: string;
tsCodeRoot: string;
incremental: boolean;
tsConfig?: any; // 临时的ts配置
clean: boolean;
}) => {
export const tsIntegrationProjectCompile = async (
baseDir,
options: {
buildRoot: string;
tsCodeRoot: string;
incremental: boolean;
tsConfig?: any; // 临时的ts配置
clean: boolean;
}
) => {
const tsConfig = await tsCompile(baseDir, {
tsConfig: options.tsConfig,
clean: options.clean,
Expand All @@ -30,19 +34,11 @@ export const tsIntegrationProjectCompile = async (baseDir, options: {
pretty: true,
declaration: true,
jsx: 'react',
outDir: relative(
baseDir,
join(options.buildRoot, 'dist')
),
outDir: relative(baseDir, join(options.buildRoot, 'dist')),
},
include: [
`${relative(
baseDir,
options.tsCodeRoot
)}/**/*`
],
include: [`${relative(baseDir, options.tsCodeRoot)}/**/*`],
exclude: ['dist', 'node_modules', 'test'],
}
},
});
return tsConfig;
};
Expand All @@ -55,21 +51,31 @@ export const tsIntegrationProjectCompile = async (baseDir, options: {
* @param options.tsConfigName tsconfig.json 名
* @param options.clean 是否在构建前清理
*/
export const tsCompile = async (baseDir: string, options: {
tsConfigName?: string;
clean?: boolean;
innerTsConfig?: any;
tsConfig?: any; // extra tsconfig
incremental?: boolean;
} = {}) => {
export const tsCompile = async (
baseDir: string,
options: {
tsConfigName?: string;
clean?: boolean;
innerTsConfig?: any;
tsConfig?: any; // extra tsconfig
incremental?: boolean;
} = {}
) => {
const builder = new BuildCommand();
let tsJson = null;
if (options.tsConfigName) {
try {
tsJson = JSON.parse(readFileSync(resolve(baseDir, options.tsConfigName)).toString());
tsJson = JSON.parse(
readFileSync(resolve(baseDir, options.tsConfigName)).toString()
);
} catch (e) {}
}
const tsConfig = combineTsConfig({}, options.innerTsConfig, options.tsConfig, tsJson);
const tsConfig = combineTsConfig(
{},
options.innerTsConfig,
options.tsConfig,
tsJson
);

if (tsConfig.compilerOptions) {
if (tsConfig.compilerOptions.inlineSourceMap) {
Expand All @@ -81,9 +87,15 @@ export const tsCompile = async (baseDir: string, options: {
if (tsConfig.compilerOptions.incremental) {
let tsBuildInfoFile = '';
if (tsConfig.compilerOptions.outDir) {
tsBuildInfoFile = resolve(baseDir, tsConfig.compilerOptions.outDir, '.tsbuildinfo');
tsBuildInfoFile = resolve(
baseDir,
tsConfig.compilerOptions.outDir,
'.tsbuildinfo'
);
} else {
const tmpDir = ['build', 'dist'].find(dirName => existsSync(resolve(baseDir, dirName)));
const tmpDir = ['build', 'dist'].find(dirName =>
existsSync(resolve(baseDir, dirName))
);
tsBuildInfoFile = resolve(tmpDir || baseDir, '.tsbuildinfo');
}
tsConfig.compilerOptions.tsBuildInfoFile = tsBuildInfoFile;
Expand All @@ -94,7 +106,7 @@ export const tsCompile = async (baseDir: string, options: {
cwd: baseDir,
argv: {
clean: typeof options.clean === 'undefined' ? true : options.clean,
tsConfig
tsConfig,
},
});

Expand Down
103 changes: 102 additions & 1 deletion packages/faas-util-ts-compile/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
const getType = (v: any) => (({}).toString.call(v).slice(8, -1).toLowerCase());
import * as globby from 'globby';
import { existsSync, copy, statSync } from 'fs-extra';
import { join } from 'path';
const getType = (v: any) =>
({}.toString
.call(v)
.slice(8, -1)
.toLowerCase());
export const combineTsConfig = (config, ...tsConfig: any[]) => {
const combined = config || {};
for (const config of tsConfig || []) {
Expand All @@ -21,3 +28,97 @@ export const combineTsConfig = (config, ...tsConfig: any[]) => {
}
return combined;
};

// 符合sourceGlob条件的文件中 是否存在 比所有符合toGlob条件的文件 要新的文件
// 返回 fromGlob 中更新的文件
export const compareFileChange = async (
fromGlob: string[],
toGlob: string[],
options?: any
) => {
options = options || {};
if (!options.cwd) {
options.cwd = process.cwd();
}
options.stats = true;
const fromFiles: any = await globby(fromGlob, options);
const toFiles: any = await globby(toGlob, options);

if (!fromFiles || !fromFiles.length) {
return [];
}

if (!toFiles || !toFiles.length) {
return fromFiles.map((file: any) => file.path);
}
let latestFilesChangeTime = 0;
for (const file of toFiles) {
if (file.stats.mtimeMs > latestFilesChangeTime) {
latestFilesChangeTime = file.stats.mtimeMs;
}
}
const result = [];
for (const file of fromFiles) {
if (file.stats.mtimeMs > latestFilesChangeTime) {
result.push(file.path);
}
}
return result;
};

interface ICopyOptions {
sourceDir: string;
targetDir: string;
defaultInclude?: string[];
include?: string[];
exclude?: string[];
log?: (path: string) => void;
}

export const copyFiles = async (options: ICopyOptions) => {
const {
defaultInclude,
include,
exclude,
sourceDir,
targetDir,
log,
} = options;
const paths = await globby(
(defaultInclude || ['*.yml', '*.js', '*.json', 'app', 'config']).concat(
include || []
),
{
cwd: sourceDir,
followSymbolicLinks: false,
ignore: [
'**/node_modules/**', // 模块依赖目录
'**/test/**', // 测试目录
'**/run/**', // egg 运行调试目录
'**/public/**', // 公共assets目录
'**/build/**', // 构建产物目录
'**/dist/**', // 构建产物目录
'**/.serverless/**', // faas 构建目录
'**/.faas_debug_tmp/**', // faas 调试临时目录
].concat(exclude || []),
}
);
await Promise.all(
paths.map((path: string) => {
const source = join(sourceDir, path);
const target = join(targetDir, path);
if (existsSync(target)) {
const sourceStat = statSync(source);
const targetStat = statSync(target);
// source 修改时间小于目标文件 修改时间,则不拷贝
if (sourceStat.mtimeMs <= targetStat.mtimeMs) {
return;
}
}
if (log) {
log(path);
}
return copy(source, target);
})
);
};
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1584085292279
1 change: 1 addition & 0 deletions packages/faas-util-ts-compile/test/fixtures/files/tmp/1.to
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1584085292384
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1584085292486
Empty file.
Empty file.
Empty file.
39 changes: 39 additions & 0 deletions packages/faas-util-ts-compile/test/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { compareFileChange, copyFiles } from '../src/utils';
import * as assert from 'assert';
import { writeFileSync, existsSync, remove } from 'fs-extra';
import { resolve } from 'path';
describe('/test/utils.test.ts', () => {
it('compareFileChange', async () => {
const timeout = (fileName: string) => {
return new Promise(res => {
setTimeout(() => {
writeFileSync(resolve(__dirname, fileName), `${Date.now()}`);
res(true);
}, 100);
});
};
await timeout('./fixtures/files/tmp/1.from');
await timeout('./fixtures/files/tmp/1.to');
await timeout('./fixtures/files/tmp/2.from');
const result = await compareFileChange(
['./fixtures/files/tmp/*.from'],
['./fixtures/files/tmp/*.to'],
{ cwd: __dirname }
);
assert(result && result[0] === './fixtures/files/tmp/2.from');
});

it('copyFiles', async () => {
const target = resolve(__dirname, './fixtures/files/to');
await remove(target);
await copyFiles({
sourceDir: resolve(__dirname, './fixtures/files/from'),
targetDir: resolve(__dirname, './fixtures/files/to'),
exclude: ['1.json', 'files/a.ts'],
include: ['*.txt', 'files/*'],
});
assert(existsSync(resolve(__dirname, target, '1.js')));
assert(existsSync(resolve(__dirname, target, '1.txt')));
assert(existsSync(resolve(__dirname, target, 'files/b.ts')));
});
});
18 changes: 17 additions & 1 deletion packages/serverless-invoke/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
2. tsc编译用户代码到dist目录
3. 开源版: 【创建runtime、创建trigger】封装为平台invoke包,提供getInvoke方法,会传入args与入口方法,返回invoke方法
*/
import { FaaSStarterClass, cleanTarget, compareFileChange } from './utils';
import { FaaSStarterClass, cleanTarget } from './utils';
import { join, resolve, relative } from 'path';
import { existsSync, move, writeFileSync, ensureFileSync } from 'fs-extra';
import { loadSpec, getSpecFile } from '@midwayjs/fcli-command-core';
Expand All @@ -14,6 +14,8 @@ import { AnalyzeResult, Locator } from '@midwayjs/locate';
import {
tsCompile,
tsIntegrationProjectCompile,
compareFileChange,
copyFiles,
} from '@midwayjs/faas-util-ts-compile';
import { IInvoke } from './interface';

Expand Down Expand Up @@ -158,6 +160,7 @@ export abstract class InvokeCore implements IInvoke {
}

public async invoke(...args: any) {
await this.copyFile();
await this.buildTS();
const invoke = await this.getInvokeFunction();
this.checkDebug();
Expand Down Expand Up @@ -186,6 +189,19 @@ export abstract class InvokeCore implements IInvoke {
}
}

private async copyFile() {
const packageObj: any = this.spec.package || {};
return copyFiles({
sourceDir: this.baseDir,
targetDir: this.buildDir,
include: packageObj.include,
exclude: packageObj.exclude,
log: path => {
this.debug('copy file', path);
},
});
}

// 写入口
private async makeWrapper(starter: string) {
const funcInfo = this.getFunctionInfo();
Expand Down
Loading

0 comments on commit 9558410

Please sign in to comment.