@build-script/package-tools 0.0.27 → 0.0.29

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.
Files changed (55) hide show
  1. package/bins/load.js +0 -0
  2. package/lib/commands/monorepo-publish.d.ts.map +1 -1
  3. package/lib/commands/monorepo-publish.js +31 -15
  4. package/lib/commands/monorepo-publish.js.map +1 -1
  5. package/lib/common/cache/native.npm.d.ts +4 -1
  6. package/lib/common/cache/native.npm.d.ts.map +1 -1
  7. package/lib/common/cache/native.npm.js +13 -10
  8. package/lib/common/cache/native.npm.js.map +1 -1
  9. package/lib/common/git/git.d.ts +3 -1
  10. package/lib/common/git/git.d.ts.map +1 -1
  11. package/lib/common/git/git.js +12 -10
  12. package/lib/common/git/git.js.map +1 -1
  13. package/lib/common/package-manager/driver.abstract.d.ts +3 -1
  14. package/lib/common/package-manager/driver.abstract.d.ts.map +1 -1
  15. package/lib/common/package-manager/driver.abstract.js +16 -14
  16. package/lib/common/package-manager/driver.abstract.js.map +1 -1
  17. package/lib/common/package-manager/package-manager.d.ts +2 -1
  18. package/lib/common/package-manager/package-manager.d.ts.map +1 -1
  19. package/lib/common/package-manager/package-manager.js +4 -3
  20. package/lib/common/package-manager/package-manager.js.map +1 -1
  21. package/lib/common/package-manager/proxy.d.ts +3 -2
  22. package/lib/common/package-manager/proxy.d.ts.map +1 -1
  23. package/lib/common/package-manager/proxy.js +6 -6
  24. package/lib/common/package-manager/proxy.js.map +1 -1
  25. package/lib/common/shared-jobs/detect-change-job.d.ts.map +1 -1
  26. package/lib/common/shared-jobs/detect-change-job.js +12 -13
  27. package/lib/common/shared-jobs/detect-change-job.js.map +1 -1
  28. package/lib/common/taball/decompress.d.ts +2 -1
  29. package/lib/common/taball/decompress.d.ts.map +1 -1
  30. package/lib/common/taball/decompress.js +2 -2
  31. package/lib/common/taball/decompress.js.map +1 -1
  32. package/lib/common/taball/file-download.d.ts +8 -1
  33. package/lib/common/taball/file-download.d.ts.map +1 -1
  34. package/lib/common/taball/file-download.js +107 -97
  35. package/lib/common/taball/file-download.js.map +1 -1
  36. package/lib/common/temp-work-folder.d.ts +3 -1
  37. package/lib/common/temp-work-folder.d.ts.map +1 -1
  38. package/lib/common/temp-work-folder.js +9 -7
  39. package/lib/common/temp-work-folder.js.map +1 -1
  40. package/lib/common/version.generated.d.ts +1 -1
  41. package/lib/common/version.generated.js +1 -1
  42. package/package.json +20 -21
  43. package/src/commands/monorepo-publish.ts +33 -15
  44. package/src/common/cache/native.npm.ts +13 -10
  45. package/src/common/git/git.ts +13 -10
  46. package/src/common/package-manager/driver.abstract.ts +14 -13
  47. package/src/common/package-manager/package-manager.ts +10 -4
  48. package/src/common/package-manager/proxy.ts +6 -6
  49. package/src/common/shared-jobs/detect-change-job.ts +13 -13
  50. package/src/common/taball/decompress.ts +2 -2
  51. package/src/common/taball/file-download.ts +113 -105
  52. package/src/common/temp-work-folder.ts +7 -6
  53. package/src/common/version.generated.ts +1 -1
  54. package/src/tsconfig.json +13 -8
  55. package/bins/load.devel.js +0 -15
@@ -1,4 +1,4 @@
1
- import { logger } from '@idlebox/cli';
1
+ import { logger as defaultLogger, type IMyLogger } from '@idlebox/cli';
2
2
  import { sleep } from '@idlebox/common';
3
3
  import { exists, streamPromise } from '@idlebox/node';
4
4
  import { createWriteStream } from 'node:fs';
@@ -14,33 +14,124 @@ interface IMetaInfo {
14
14
  url: string;
15
15
  }
16
16
 
17
- export async function downloadFileCached(url: string, file: string) {
18
- const metadata = `${file}.meta.json`;
19
- logger.debug`下载文件:\n 地址: long<${url}>\n 保存到: long<${file}>`;
20
- let meta: IMetaInfo | undefined;
21
- if ((await exists(metadata)) && (await exists(file))) {
22
- try {
23
- meta = JSON.parse(await readFile(metadata, 'utf-8'));
24
- } catch {}
25
-
26
- if (meta?.url === url) {
27
- logger.debug(' -> 已经下载');
28
- return file;
17
+ export class FileDownloader {
18
+ constructor(public readonly logger: IMyLogger = defaultLogger) {}
19
+
20
+ public async download(url: string, file: string) {
21
+ const metadata = `${file}.meta.json`;
22
+ this.logger.debug`下载文件:\n 地址: long<${url}>\n 保存到: long<${file}>`;
23
+ let meta: IMetaInfo | undefined;
24
+ if ((await exists(metadata)) && (await exists(file))) {
25
+ try {
26
+ meta = JSON.parse(await readFile(metadata, 'utf-8'));
27
+ } catch {}
28
+
29
+ if (meta?.url === url) {
30
+ this.logger.debug(' -> 已经下载');
31
+ return file;
32
+ }
29
33
  }
34
+ const response = await this.http_stream(url);
35
+
36
+ await mkdir(dirname(file), { recursive: true });
37
+ const writeOut = createWriteStream(`${file}.downloading`);
38
+ await streamPromise(response.stream.pipe(writeOut));
39
+
40
+ meta = { headers: response.headers, url };
41
+ await writeFile(metadata, JSON.stringify(meta), 'utf-8');
42
+
43
+ await rename(`${file}.downloading`, file);
44
+ this.logger.debug(' -> 下载完成');
45
+
46
+ return file;
30
47
  }
31
- const response = await http_stream(url);
32
48
 
33
- await mkdir(dirname(file), { recursive: true });
34
- const writeOut = createWriteStream(`${file}.downloading`);
35
- await streamPromise(response.stream.pipe(writeOut));
49
+ private async http_stream(url: string, headers?: OutgoingHttpHeaders): Promise<INormalizedResponse> {
50
+ let try_remain = 3;
51
+ let redirect_cnt = 0;
52
+ while (try_remain-- > 0) {
53
+ try {
54
+ return await this.send_request(url, headers || {});
55
+ } catch (e: unknown) {
56
+ if (RedirectError.is(e)) {
57
+ redirect_cnt++;
58
+ if (redirect_cnt > 8) {
59
+ throw new HttpError(url, 0, '重定向次数过多');
60
+ }
61
+
62
+ this.logger.debug(`[http] 重定向到 ${e.location}`);
63
+ url = e.location;
64
+ try_remain++;
65
+ continue;
66
+ }
67
+
68
+ this.logger.error('获取 %s 失败 [剩余尝试次数 %s]', url, try_remain);
69
+ if (try_remain === 0) throw e;
36
70
 
37
- meta = { headers: response.headers, url };
38
- await writeFile(metadata, JSON.stringify(meta), 'utf-8');
71
+ await sleep(2000);
72
+ }
73
+ }
74
+ throw new Error('不可能的错误');
75
+ }
39
76
 
40
- await rename(`${file}.downloading`, file);
41
- logger.debug(' -> 下载完成');
77
+ private send_request(url: string, headers: OutgoingHttpHeaders): Promise<any> {
78
+ headers['Accept-Encoding'] = 'br,gzip,deflate';
79
+ return new Promise<any>((resolve, reject) => {
80
+ this.logger.debug(`[http] 请求 ${url}`);
81
+
82
+ const request = get(url, { headers }, (response) => {
83
+ this.logger.debug(`[http] 响应 ${response.statusCode} [encoding: ${response.headers['content-encoding']}][${response.headers['content-length']} bytes]`);
84
+ if (response.statusCode === 200) {
85
+ const bytes = Number.parseInt(response.headers['content-length'] ?? '--', 10);
86
+
87
+ if (bytes > 5 * 1024 * 1024 && process.stderr.isTTY) {
88
+ let downloaded = 0;
89
+ response.on('data', (bs) => {
90
+ downloaded += bs.length;
91
+ process.stderr.write(`\x1B[2mdownload: ${downloaded} of ${bytes} bytes (${Math.round((downloaded / bytes) * 100)}%)\x1B[0m\r`);
92
+ });
93
+ response.on('end', () => {
94
+ process.stderr.write('\x1B[K');
95
+ });
96
+ }
97
+
98
+ let stream: Readable;
99
+ switch (response.headers['content-encoding']) {
100
+ case 'br':
101
+ stream = response.pipe(createBrotliDecompress());
102
+ break;
103
+ // Or, just use zlib.createUnzip() to handle both of the following cases:
104
+ case 'gzip':
105
+ stream = response.pipe(createGunzip());
106
+ break;
107
+ case 'deflate':
108
+ stream = response.pipe(createInflate());
109
+ break;
110
+ default:
111
+ stream = response;
112
+ break;
113
+ }
114
+ resolve(Object.assign(response, { stream }));
115
+ } else if (
116
+ (response.statusCode === 302 ||
117
+ response.statusCode === 301 ||
118
+ response.statusCode === 303 ||
119
+ response.statusCode === 307 ||
120
+ response.statusCode === 308) &&
121
+ response.headers.location
122
+ ) {
123
+ reject(new RedirectError(url, response.headers.location, response.statusCode));
124
+ } else {
125
+ reject(new HttpError(url, response.statusCode as number, response.statusMessage as string));
126
+ }
127
+ });
42
128
 
43
- return file;
129
+ request.on('error', (err) => {
130
+ reject(err);
131
+ });
132
+ request.end();
133
+ });
134
+ }
44
135
  }
45
136
 
46
137
  class RedirectError extends Error {
@@ -73,86 +164,3 @@ export class HttpError extends Error {
73
164
 
74
165
  type IStream = { stream: Readable };
75
166
  export type INormalizedResponse = Omit<IncomingMessage, keyof Readable> & IStream;
76
-
77
- async function http_stream(url: string, headers?: OutgoingHttpHeaders): Promise<INormalizedResponse> {
78
- let try_remain = 3;
79
- let redirect_cnt = 0;
80
- while (try_remain-- > 0) {
81
- try {
82
- return await send_request(url, headers || {});
83
- } catch (e: unknown) {
84
- if (RedirectError.is(e)) {
85
- redirect_cnt++;
86
- if (redirect_cnt > 8) {
87
- throw new HttpError(url, 0, '重定向次数过多');
88
- }
89
-
90
- logger.debug(`[http] 重定向到 ${e.location}`);
91
- url = e.location;
92
- try_remain++;
93
- continue;
94
- }
95
-
96
- logger.error('获取 %s 失败 [剩余尝试次数 %s]', url, try_remain);
97
- if (try_remain === 0) throw e;
98
-
99
- await sleep(2000);
100
- }
101
- }
102
- throw new Error('不可能的错误');
103
- }
104
-
105
- function send_request(url: string, headers: OutgoingHttpHeaders): Promise<any> {
106
- headers['Accept-Encoding'] = 'br,gzip,deflate';
107
- return new Promise<any>((resolve, reject) => {
108
- logger.debug(`[http] 请求 ${url}`);
109
-
110
- const request = get(url, { headers }, (response) => {
111
- logger.debug(`[http] 响应 ${response.statusCode} [encoding: ${response.headers['content-encoding']}][${response.headers['content-length']} bytes]`);
112
- if (response.statusCode === 200) {
113
- const bytes = Number.parseInt(response.headers['content-length'] ?? '--', 10);
114
-
115
- if (bytes > 5 * 1024 * 1024 && process.stderr.isTTY) {
116
- let downloaded = 0;
117
- response.on('data', (bs) => {
118
- downloaded += bs.length;
119
- process.stderr.write(`\x1B[2mdownload: ${downloaded} of ${bytes} bytes (${Math.round((downloaded / bytes) * 100)}%)\x1B[0m\r`);
120
- });
121
- response.on('end', () => {
122
- process.stderr.write('\x1B[K');
123
- });
124
- }
125
-
126
- let stream: Readable;
127
- switch (response.headers['content-encoding']) {
128
- case 'br':
129
- stream = response.pipe(createBrotliDecompress());
130
- break;
131
- // Or, just use zlib.createUnzip() to handle both of the following cases:
132
- case 'gzip':
133
- stream = response.pipe(createGunzip());
134
- break;
135
- case 'deflate':
136
- stream = response.pipe(createInflate());
137
- break;
138
- default:
139
- stream = response;
140
- break;
141
- }
142
- resolve(Object.assign(response, { stream }));
143
- } else if (
144
- (response.statusCode === 302 || response.statusCode === 301 || response.statusCode === 303 || response.statusCode === 307 || response.statusCode === 308) &&
145
- response.headers.location
146
- ) {
147
- reject(new RedirectError(url, response.headers.location, response.statusCode));
148
- } else {
149
- reject(new HttpError(url, response.statusCode as number, response.statusMessage as string));
150
- }
151
- });
152
-
153
- request.on('error', (err) => {
154
- reject(err);
155
- });
156
- request.end();
157
- });
158
- }
@@ -1,7 +1,7 @@
1
1
  import type { WorkspaceBase } from '@build-script/monorepo-lib';
2
+ import { logger as defaultLogger, type IMyLogger } from '@idlebox/cli';
2
3
  import { registerGlobalLifecycle } from '@idlebox/common';
3
4
  import { writeJsonFile } from '@idlebox/json-edit';
4
- import { logger } from '@idlebox/cli';
5
5
  import { emptyDir } from '@idlebox/node';
6
6
  import { randomBytes } from 'node:crypto';
7
7
  import { rmSync } from 'node:fs';
@@ -17,6 +17,7 @@ export class TempWorkingFolder {
17
17
  constructor(
18
18
  private readonly workspace: WorkspaceBase,
19
19
  name: string,
20
+ public readonly logger: IMyLogger = defaultLogger,
20
21
  __internal_isChild = false,
21
22
  ) {
22
23
  if (!__internal_isChild) {
@@ -27,7 +28,7 @@ export class TempWorkingFolder {
27
28
  }
28
29
 
29
30
  resolve(p0: string, ...paths: string[]) {
30
- return new TempWorkingFolder(this.workspace, this.joinpath(p0, ...paths), true);
31
+ return new TempWorkingFolder(this.workspace, this.joinpath(p0, ...paths), this.logger, true);
31
32
  }
32
33
 
33
34
  joinpath(p0: string, ...paths: string[]) {
@@ -39,7 +40,7 @@ export class TempWorkingFolder {
39
40
  }
40
41
 
41
42
  async mkdir() {
42
- logger.debug('临时工作目录: %s', this.path);
43
+ this.logger.debug`临时工作目录: long<${this.path}>`;
43
44
  await mkdir(this.path, { recursive: true });
44
45
  this._exists = true;
45
46
  }
@@ -66,15 +67,15 @@ export class TempWorkingFolder {
66
67
  }
67
68
 
68
69
  unpack(tarball: string, dest = '.') {
69
- return decompressPack(tarball, resolve(this.path, dest));
70
+ return decompressPack(tarball, resolve(this.path, dest), this.logger);
70
71
  }
71
72
 
72
73
  dispose() {
73
74
  if (!isDebugMode) {
74
- logger.debug(' * 删除临时目录: %s', this.path);
75
+ this.logger.debug` * 删除临时目录: long<${this.path}>`;
75
76
  rmSync(this.path, { force: true, recursive: true });
76
77
  } else {
77
- logger.debug(' * 由于是调试模式,不删除临时文件夹: %s', this.path);
78
+ this.logger.debug` * 由于是调试模式,不删除临时文件夹: long<${this.path}>`;
78
79
  }
79
80
  }
80
81
  }
@@ -13,7 +13,7 @@
13
13
  ******************************************************************************/
14
14
 
15
15
 
16
- export const self_package_version = "0.0.27";
16
+ export const self_package_version = "0.0.29";
17
17
  export const self_package_name = "@build-script/package-tools";
18
18
  export const self_package_repository = "https://github.com/GongT/baobao";
19
19
 
package/src/tsconfig.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
- "extends": "@build-script/baseline-rig/package/tsconfig.json",
3
- "compilerOptions": {
4
- "typeRoots": ["../node_modules/@types", "../node_modules"],
5
- "outDir": "../lib",
6
- "rootDir": "./",
7
- "noEmitOnError": false
8
- },
9
- "exclude": ["**/*.generator.ts"]
2
+ "extends": "@build-script/baseline-rig/package/tsconfig.json",
3
+ "compilerOptions": {
4
+ "typeRoots": [
5
+ "../node_modules/@types",
6
+ "../node_modules"
7
+ ],
8
+ "outDir": "../lib",
9
+ "rootDir": "./",
10
+ "noEmitOnError": false
11
+ },
12
+ "exclude": [
13
+ "**/*.generator.ts"
14
+ ]
10
15
  }
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env -S node --experimental-transform-types --disable-warning=ExperimentalWarning
2
-
3
- import '@idlebox/native-executer/register';
4
- import { execaNode } from 'execa';
5
- import { resolve } from 'node:path';
6
-
7
- process.title = `PkgTool`;
8
-
9
- try {
10
- await import('../src/commands.generated.ts');
11
- } catch {
12
- await execaNode({ stdio: 'inherit' })`${resolve(import.meta.dirname, '../../codegen/loader/bin.devel.js')} ${resolve(import.meta.dirname, '../src')}`;
13
- }
14
-
15
- await import('../src/main.ts');