@simplysm/sd-cli 7.0.23 → 7.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/sd-cli.d.ts +1 -1
- package/dist/bin/sd-cli.mjs +15 -3
- package/dist/builder/SdCliClientBuilder.d.ts +20 -0
- package/dist/builder/SdCliClientBuilder.mjs +392 -0
- package/dist/builder/SdCliServerBuilder.d.ts +24 -0
- package/dist/builder/SdCliServerBuilder.mjs +399 -0
- package/dist/builder/SdCliTsLibBuilder.d.ts +5 -3
- package/dist/builder/SdCliTsLibBuilder.mjs +17 -18
- package/dist/commons.d.ts +10 -4
- package/dist/entry-points/SdCliNpm.d.ts +6 -0
- package/dist/entry-points/SdCliNpm.mjs +22 -0
- package/dist/entry-points/SdCliPrepare.d.ts +5 -0
- package/dist/entry-points/SdCliPrepare.mjs +54 -0
- package/dist/entry-points/SdCliWorkspace.d.ts +1 -0
- package/dist/entry-points/SdCliWorkspace.mjs +43 -36
- package/dist/packages/SdCliPackage.d.ts +1 -0
- package/dist/packages/SdCliPackage.mjs +20 -19
- package/dist/utils/SdCliBuildResultUtil.d.ts +4 -1
- package/dist/utils/SdCliBuildResultUtil.mjs +24 -2
- package/dist/utils/SdCliNpmConfigUtil.d.ts +7 -0
- package/dist/utils/SdCliNpmConfigUtil.mjs +15 -0
- package/package.json +22 -7
- package/src/bin/sd-cli.ts +22 -2
- package/src/builder/SdCliClientBuilder.ts +426 -0
- package/src/builder/SdCliServerBuilder.ts +457 -0
- package/src/builder/SdCliTsLibBuilder.ts +26 -21
- package/src/commons.ts +6 -5
- package/src/entry-points/SdCliNpm.ts +26 -0
- package/src/entry-points/SdCliPrepare.ts +54 -0
- package/src/entry-points/SdCliWorkspace.ts +51 -42
- package/src/packages/SdCliPackage.ts +21 -23
- package/src/utils/SdCliBuildResultUtil.ts +30 -1
- package/src/utils/SdCliNpmConfigUtil.ts +16 -0
|
@@ -2,13 +2,14 @@ import { FsUtil, Logger, SdProcess } from "@simplysm/sd-core-node";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { INpmConfig, ISdCliConfig, ISdCliPackageBuildResult } from "../commons";
|
|
4
4
|
import { SdCliPackage } from "../packages/SdCliPackage";
|
|
5
|
-
import { Wait } from "@simplysm/sd-core-common";
|
|
5
|
+
import { Uuid, Wait } from "@simplysm/sd-core-common";
|
|
6
6
|
import os from "os";
|
|
7
7
|
import { SdCliBuildResultUtil } from "../utils/SdCliBuildResultUtil";
|
|
8
8
|
import semver from "semver/preload";
|
|
9
9
|
import { SdCliConfigUtil } from "../utils/SdCliConfigUtil";
|
|
10
10
|
import { SdServiceServer } from "@simplysm/sd-service/server";
|
|
11
|
-
import
|
|
11
|
+
import { SdCliNpm } from "./SdCliNpm";
|
|
12
|
+
import { SdCliLocalUpdate } from "./SdCliLocalUpdate";
|
|
12
13
|
|
|
13
14
|
export class SdCliWorkspace {
|
|
14
15
|
private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
|
|
@@ -25,6 +26,11 @@ export class SdCliWorkspace {
|
|
|
25
26
|
this._logger.debug("프로젝트 설정 가져오기...");
|
|
26
27
|
const config = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), true, opt.optNames);
|
|
27
28
|
|
|
29
|
+
if (config.localUpdates) {
|
|
30
|
+
this._logger.debug("로컬 라이브러리 업데이트 변경감지 시작...");
|
|
31
|
+
await new SdCliLocalUpdate(this._rootPath).watchAsync({ confFileRelPath: opt.confFileRelPath });
|
|
32
|
+
}
|
|
33
|
+
|
|
28
34
|
this._logger.debug("패키지 목록 구성...");
|
|
29
35
|
const pkgs = await this._getPackagesAsync(config);
|
|
30
36
|
|
|
@@ -40,7 +46,15 @@ export class SdCliWorkspace {
|
|
|
40
46
|
changeCount++;
|
|
41
47
|
this._logger.debug(`[${pkg.name}] 빌드를 시작합니다...`);
|
|
42
48
|
})
|
|
43
|
-
.on("complete", (results) => {
|
|
49
|
+
.on("complete", async (results) => {
|
|
50
|
+
if (pkg.type === "server") {
|
|
51
|
+
if (results.some((item) => item.severity === "error")) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
await this._restartServerAsync(pkg);
|
|
56
|
+
}
|
|
57
|
+
|
|
44
58
|
this._logger.debug(`[${pkg.name}] 빌드가 완료되었습니다.`);
|
|
45
59
|
totalResultMap.set(pkg.name, results);
|
|
46
60
|
|
|
@@ -52,40 +66,6 @@ export class SdCliWorkspace {
|
|
|
52
66
|
}
|
|
53
67
|
}, 500);
|
|
54
68
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (pkg.type === "server") {
|
|
58
|
-
pkg.on("complete", async (results) => {
|
|
59
|
-
if (results.some((item) => item.severity === "error")) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const entryFileRelPath = pkg.main;
|
|
64
|
-
if (entryFileRelPath === undefined) {
|
|
65
|
-
this._logger.error(`서버패키지(${pkg.name})의 'package.json'에서 'main'필드를 찾을 수 없습니다.`);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const entryFilePath = path.resolve(pkg.rootPath, entryFileRelPath);
|
|
69
|
-
|
|
70
|
-
this._logger.log(`서버(${pkg.name}) 재시작...`);
|
|
71
|
-
const serverInfo = this._serverInfoMap.getOrCreate(pkg.name, {});
|
|
72
|
-
if (serverInfo.server) {
|
|
73
|
-
await serverInfo.server.closeAsync();
|
|
74
|
-
delete serverInfo.server;
|
|
75
|
-
decache(entryFilePath);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
serverInfo.server = (await import(entryFilePath)) as SdServiceServer | undefined;
|
|
79
|
-
if (serverInfo.server === undefined) {
|
|
80
|
-
this._logger.error(`${entryFilePath}(0, 0): 'SdServiceServer'를 'export'해야 합니다.`);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
await Wait.until(() => serverInfo.server!.isOpen);
|
|
85
|
-
|
|
86
|
-
this._logger.log(`서버(${pkg.name}) 재시작 완료`);
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
69
|
}
|
|
90
70
|
|
|
91
71
|
this._logger.debug("빌드를 시작합니다...");
|
|
@@ -98,6 +78,32 @@ export class SdCliWorkspace {
|
|
|
98
78
|
});
|
|
99
79
|
}
|
|
100
80
|
|
|
81
|
+
private async _restartServerAsync(pkg: SdCliPackage): Promise<void> {
|
|
82
|
+
const entryFileRelPath = pkg.main;
|
|
83
|
+
if (entryFileRelPath === undefined) {
|
|
84
|
+
this._logger.error(`서버패키지(${pkg.name})의 'package.json'에서 'main'필드를 찾을 수 없습니다.`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const entryFilePath = path.resolve(pkg.rootPath, entryFileRelPath);
|
|
88
|
+
|
|
89
|
+
this._logger.log(`서버(${pkg.name}) 재시작...`);
|
|
90
|
+
const serverInfo = this._serverInfoMap.getOrCreate(pkg.name, {});
|
|
91
|
+
if (serverInfo.server) {
|
|
92
|
+
await serverInfo.server.closeAsync();
|
|
93
|
+
delete serverInfo.server;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
serverInfo.server = (await import("file:///" + entryFilePath + "?update=" + Uuid.new().toString())).default as SdServiceServer | undefined;
|
|
97
|
+
if (!serverInfo.server) {
|
|
98
|
+
this._logger.error(`${entryFilePath}(0, 0): 'SdServiceServer'를 'export'해야 합니다.`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
await Wait.until(() => serverInfo.server!.isOpen);
|
|
103
|
+
|
|
104
|
+
this._logger.log(`서버(${pkg.name}) 재시작 완료`);
|
|
105
|
+
}
|
|
106
|
+
|
|
101
107
|
public async buildAsync(opt: { confFileRelPath: string; optNames: string[] }): Promise<void> {
|
|
102
108
|
this._logger.debug("프로젝트 설정 가져오기...");
|
|
103
109
|
const config = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), false, opt.optNames);
|
|
@@ -148,9 +154,9 @@ export class SdCliWorkspace {
|
|
|
148
154
|
// GIT 사용중일 경우, 커밋되지 않은 수정사항이 있는지 확인
|
|
149
155
|
if (FsUtil.exists(path.resolve(process.cwd(), ".git"))) {
|
|
150
156
|
this._logger.debug("GIT 커밋여부 확인...");
|
|
151
|
-
const gitStatusResult = await SdProcess.
|
|
157
|
+
const gitStatusResult = await SdProcess.spawnAsync("git status");
|
|
152
158
|
if (gitStatusResult.includes("Changes") || gitStatusResult.includes("Untracked")) {
|
|
153
|
-
throw new Error("커밋되지 않은 정보가
|
|
159
|
+
throw new Error("커밋되지 않은 정보가 있습니다.\n" + gitStatusResult);
|
|
154
160
|
}
|
|
155
161
|
}
|
|
156
162
|
|
|
@@ -160,6 +166,9 @@ export class SdCliWorkspace {
|
|
|
160
166
|
this._logger.debug("프로젝트 및 패키지 버전 설정...");
|
|
161
167
|
await this._upgradeVersionAsync(pkgs);
|
|
162
168
|
|
|
169
|
+
this._logger.debug("노드패키지 업데이트...");
|
|
170
|
+
await new SdCliNpm(this._rootPath).updateAsync();
|
|
171
|
+
|
|
163
172
|
// 빌드
|
|
164
173
|
if (!opt.noBuild) {
|
|
165
174
|
this._logger.debug("빌드를 시작합니다...");
|
|
@@ -169,9 +178,9 @@ export class SdCliWorkspace {
|
|
|
169
178
|
// GIT 사용중일경우, 새 버전 커밋 및 TAG 생성
|
|
170
179
|
if (FsUtil.exists(path.resolve(process.cwd(), ".git"))) {
|
|
171
180
|
this._logger.debug("새 버전 커밋 및 TAG 생성...");
|
|
172
|
-
await SdProcess.
|
|
173
|
-
await SdProcess.
|
|
174
|
-
await SdProcess.
|
|
181
|
+
await SdProcess.spawnAsync("git add .");
|
|
182
|
+
await SdProcess.spawnAsync(`git commit -m "v${this._npmConfig.version}"`);
|
|
183
|
+
await SdProcess.spawnAsync(`git tag -a "v${this._npmConfig.version}" -m "v${this._npmConfig.version}"`);
|
|
175
184
|
}
|
|
176
185
|
|
|
177
186
|
this._logger.debug("배포 시작...");
|
|
@@ -5,6 +5,8 @@ import { EventEmitter } from "events";
|
|
|
5
5
|
import { ObjectUtil } from "@simplysm/sd-core-common";
|
|
6
6
|
import { SdCliTsLibBuilder } from "../builder/SdCliTsLibBuilder";
|
|
7
7
|
import { SdCliJsLibBuilder } from "../builder/SdCliJsLibBuilder";
|
|
8
|
+
import { SdCliServerBuilder } from "../builder/SdCliServerBuilder";
|
|
9
|
+
import { SdCliNpmConfigUtil } from "../utils/SdCliNpmConfigUtil";
|
|
8
10
|
|
|
9
11
|
export class SdCliPackage extends EventEmitter {
|
|
10
12
|
private readonly _npmConfig: INpmConfig;
|
|
@@ -27,10 +29,8 @@ export class SdCliPackage extends EventEmitter {
|
|
|
27
29
|
|
|
28
30
|
public get allDependencies(): string[] {
|
|
29
31
|
return [
|
|
30
|
-
...
|
|
31
|
-
...
|
|
32
|
-
...Object.keys(this._npmConfig.devDependencies ?? {}),
|
|
33
|
-
...Object.keys(this._npmConfig.peerDependencies ?? {})
|
|
32
|
+
...SdCliNpmConfigUtil.getDependencies(this._npmConfig).defaults,
|
|
33
|
+
...SdCliNpmConfigUtil.getDependencies(this._npmConfig).optionals
|
|
34
34
|
].distinct();
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -70,16 +70,7 @@ export class SdCliPackage extends EventEmitter {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
public async watchAsync(): Promise<void> {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (isTs) {
|
|
76
|
-
await this._genBuildTsconfigAsync();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const isAngular = isTs && this.allDependencies.includes("@angular/core");
|
|
80
|
-
const builder = !isTs ? new SdCliJsLibBuilder(this.rootPath) : new SdCliTsLibBuilder(this.rootPath, isAngular);
|
|
81
|
-
|
|
82
|
-
await builder
|
|
73
|
+
await (await this._createBuilderAsync())
|
|
83
74
|
.on("change", () => {
|
|
84
75
|
this.emit("change");
|
|
85
76
|
})
|
|
@@ -90,21 +81,28 @@ export class SdCliPackage extends EventEmitter {
|
|
|
90
81
|
}
|
|
91
82
|
|
|
92
83
|
public async buildAsync(): Promise<ISdCliPackageBuildResult[]> {
|
|
84
|
+
return await (await this._createBuilderAsync()).buildAsync();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public async publishAsync(): Promise<void> {
|
|
88
|
+
if (this._config.type === "library" && this._config.publish === "npm") {
|
|
89
|
+
await SdProcess.spawnAsync("npm publish --quiet --access public", { cwd: this.rootPath });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private async _createBuilderAsync(): Promise<SdCliJsLibBuilder | SdCliTsLibBuilder | SdCliServerBuilder> {
|
|
93
94
|
const isTs = FsUtil.exists(path.resolve(this.rootPath, "tsconfig.json"));
|
|
94
95
|
|
|
95
96
|
if (isTs) {
|
|
96
97
|
await this._genBuildTsconfigAsync();
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
public async publishAsync(): Promise<void> {
|
|
106
|
-
if (this._config.type === "library" && this._config.publish === "npm") {
|
|
107
|
-
await SdProcess.execAsync("npm publish --quiet --access public", { cwd: this.rootPath });
|
|
100
|
+
if (this._config.type === "library") {
|
|
101
|
+
// const isAngular = isTs && this.allDependencies.includes("@angular/core");
|
|
102
|
+
return isTs ? new SdCliTsLibBuilder(this.rootPath) : new SdCliJsLibBuilder(this.rootPath);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
return new SdCliServerBuilder(this.rootPath, this._config, this._workspaceRootPath);
|
|
108
106
|
}
|
|
109
107
|
}
|
|
110
108
|
|
|
@@ -2,9 +2,10 @@ import ts from "typescript";
|
|
|
2
2
|
import * as os from "os";
|
|
3
3
|
import * as path from "path";
|
|
4
4
|
import { ISdCliPackageBuildResult } from "../commons";
|
|
5
|
+
import webpack from "webpack";
|
|
5
6
|
|
|
6
7
|
export class SdCliBuildResultUtil {
|
|
7
|
-
public static
|
|
8
|
+
public static convertFromTsDiag(diag: ts.Diagnostic): ISdCliPackageBuildResult | undefined {
|
|
8
9
|
const severity = diag.category === ts.DiagnosticCategory.Error ? "error"
|
|
9
10
|
: diag.category === ts.DiagnosticCategory.Warning ? "warning"
|
|
10
11
|
: undefined;
|
|
@@ -29,6 +30,34 @@ export class SdCliBuildResultUtil {
|
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
public static convertFromWebpackStats(stats: webpack.Stats): ISdCliPackageBuildResult[] {
|
|
34
|
+
const results: ISdCliPackageBuildResult[] = [];
|
|
35
|
+
|
|
36
|
+
for (const statWarn of stats.compilation.warnings) {
|
|
37
|
+
if (stats.compilation.options.ignoreWarnings?.some((ignoreWarning) => ignoreWarning(statWarn, stats.compilation))) continue;
|
|
38
|
+
|
|
39
|
+
results.push(this._convertFromWebpackError("warning", statWarn));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const statErr of stats.compilation.errors) {
|
|
43
|
+
results.push(this._convertFromWebpackError("error", statErr));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return results;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private static _convertFromWebpackError(severity: "warning" | "error", err: webpack.WebpackError): ISdCliPackageBuildResult {
|
|
50
|
+
return {
|
|
51
|
+
filePath: err.file,
|
|
52
|
+
line: err.loc["start"].line,
|
|
53
|
+
char: err.loc["start"].column,
|
|
54
|
+
code: err.name,
|
|
55
|
+
severity,
|
|
56
|
+
message: err.message
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
32
61
|
public static getMessage(result: ISdCliPackageBuildResult): string {
|
|
33
62
|
let str = "";
|
|
34
63
|
if (result.filePath !== undefined) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { INpmConfig } from "../commons";
|
|
2
|
+
|
|
3
|
+
export class SdCliNpmConfigUtil {
|
|
4
|
+
public static getDependencies(npmConfig: INpmConfig): { defaults: string[]; optionals: string[] } {
|
|
5
|
+
return {
|
|
6
|
+
defaults: [
|
|
7
|
+
...Object.keys(npmConfig.dependencies ?? {}),
|
|
8
|
+
...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => !npmConfig.peerDependenciesMeta?.[item].optional)
|
|
9
|
+
].distinct(),
|
|
10
|
+
optionals: [
|
|
11
|
+
...Object.keys(npmConfig.optionalDependencies ?? {}),
|
|
12
|
+
...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => npmConfig.peerDependenciesMeta?.[item].optional)
|
|
13
|
+
].distinct()
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|