@git.zone/tsrust 1.5.0 → 1.6.0
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/.smartconfig.json +10 -1
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/mod_cargo/classes.cargorunner.d.ts +4 -1
- package/dist_ts/mod_cargo/classes.cargorunner.js +8 -6
- package/dist_ts/mod_cargo/classes.targetcache.d.ts +37 -0
- package/dist_ts/mod_cargo/classes.targetcache.js +260 -0
- package/dist_ts/mod_cargo/index.d.ts +1 -0
- package/dist_ts/mod_cargo/index.js +2 -1
- package/dist_ts/mod_cli/classes.tsrustcli.d.ts +2 -0
- package/dist_ts/mod_cli/classes.tsrustcli.js +52 -7
- package/package.json +2 -2
- package/readme.md +39 -8
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/mod_cargo/classes.cargorunner.ts +8 -6
- package/ts/mod_cargo/classes.targetcache.ts +304 -0
- package/ts/mod_cargo/index.ts +1 -0
- package/ts/mod_cli/classes.tsrustcli.ts +63 -6
package/.smartconfig.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"@git.zone/cli": {
|
|
3
|
+
"schemaVersion": 2,
|
|
3
4
|
"projectType": "npm",
|
|
4
5
|
"module": {
|
|
5
6
|
"githost": "code.foss.global",
|
|
@@ -20,12 +21,20 @@
|
|
|
20
21
|
},
|
|
21
22
|
"release": {
|
|
22
23
|
"targets": {
|
|
24
|
+
"git": {
|
|
25
|
+
"enabled": true,
|
|
26
|
+
"remote": "origin",
|
|
27
|
+
"pushBranch": true,
|
|
28
|
+
"pushTags": true
|
|
29
|
+
},
|
|
23
30
|
"npm": {
|
|
31
|
+
"enabled": true,
|
|
24
32
|
"registries": [
|
|
25
33
|
"https://verdaccio.lossless.digital",
|
|
26
34
|
"https://registry.npmjs.org"
|
|
27
35
|
],
|
|
28
|
-
"accessLevel": "public"
|
|
36
|
+
"accessLevel": "public",
|
|
37
|
+
"alreadyPublished": "success"
|
|
29
38
|
}
|
|
30
39
|
}
|
|
31
40
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@git.zone/tsrust',
|
|
6
|
-
version: '1.
|
|
6
|
+
version: '1.6.0',
|
|
7
7
|
description: 'A tool for compiling Rust projects, detecting Cargo workspaces, building with cargo, and placing binaries in a conventional dist_rust directory.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLGtKQUFrSjtDQUNoSyxDQUFBIn0=
|
|
@@ -16,11 +16,14 @@ export declare class CargoRunner {
|
|
|
16
16
|
target?: string;
|
|
17
17
|
crtStatic?: boolean;
|
|
18
18
|
rustflags?: string[];
|
|
19
|
+
targetDir?: string;
|
|
19
20
|
}): Promise<ICargoRunResult>;
|
|
20
21
|
private shellQuote;
|
|
21
22
|
/**
|
|
22
23
|
* Ensures a rustup target is installed. If not present, installs it via `rustup target add`.
|
|
23
24
|
*/
|
|
24
25
|
ensureTarget(triple: string): Promise<void>;
|
|
25
|
-
clean(
|
|
26
|
+
clean(options?: {
|
|
27
|
+
targetDir?: string;
|
|
28
|
+
}): Promise<ICargoRunResult>;
|
|
26
29
|
}
|
|
@@ -21,7 +21,7 @@ export class CargoRunner {
|
|
|
21
21
|
async build(options = {}) {
|
|
22
22
|
if (options.clean) {
|
|
23
23
|
console.log('Cleaning previous build...');
|
|
24
|
-
await this.clean();
|
|
24
|
+
await this.clean({ targetDir: options.targetDir });
|
|
25
25
|
}
|
|
26
26
|
// crt-static may only be injected together with an explicit --target:
|
|
27
27
|
// without one, cargo applies RUSTFLAGS to host artifacts too, and rustc
|
|
@@ -39,8 +39,9 @@ export class CargoRunner {
|
|
|
39
39
|
rustflags.unshift('-C', 'target-feature=+crt-static');
|
|
40
40
|
}
|
|
41
41
|
const rustflagsPrefix = rustflags.length ? `RUSTFLAGS=${this.shellQuote(rustflags.join(' '))} ` : '';
|
|
42
|
-
const
|
|
43
|
-
|
|
42
|
+
const targetDirPrefix = options.targetDir ? `CARGO_TARGET_DIR=${this.shellQuote(options.targetDir)} ` : '';
|
|
43
|
+
const command = `${this.envPrefix}cd ${this.rustDir} && ${targetDirPrefix}${rustflagsPrefix}cargo build${profile}${targetFlag}`;
|
|
44
|
+
console.log(`Running: ${targetDirPrefix}${rustflagsPrefix}cargo build${profile}${targetFlag}`);
|
|
44
45
|
const result = await this.shell.exec(command);
|
|
45
46
|
return {
|
|
46
47
|
success: result.exitCode === 0,
|
|
@@ -66,8 +67,9 @@ export class CargoRunner {
|
|
|
66
67
|
throw new Error(`Failed to install rustup target ${triple}`);
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
|
-
async clean() {
|
|
70
|
-
const
|
|
70
|
+
async clean(options = {}) {
|
|
71
|
+
const targetDirPrefix = options.targetDir ? `CARGO_TARGET_DIR=${this.shellQuote(options.targetDir)} ` : '';
|
|
72
|
+
const command = `${this.envPrefix}cd ${this.rustDir} && ${targetDirPrefix}cargo clean`;
|
|
71
73
|
const result = await this.shell.exec(command);
|
|
72
74
|
return {
|
|
73
75
|
success: result.exitCode === 0,
|
|
@@ -76,4 +78,4 @@ export class CargoRunner {
|
|
|
76
78
|
};
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
81
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jYXJnb3J1bm5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL21vZF9jYXJnby9jbGFzc2VzLmNhcmdvcnVubmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBUXpDLE1BQU0sT0FBTyxXQUFXO0lBQ2QsS0FBSyxDQUFnQztJQUNyQyxPQUFPLENBQVM7SUFDaEIsU0FBUyxDQUFTO0lBRTFCLFlBQVksT0FBZSxFQUFFLFlBQW9CLEVBQUU7UUFDakQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO1lBQzdDLFFBQVEsRUFBRSxNQUFNO1NBQ2pCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxLQUFLLENBQUMsbUJBQW1CO1FBQzlCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxpQkFBaUIsQ0FBQyxDQUFDO1FBQy9FLE9BQU8sTUFBTSxDQUFDLFFBQVEsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVNLEtBQUssQ0FBQyxlQUFlO1FBQzFCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxpQkFBaUIsQ0FBQyxDQUFDO1FBQy9FLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxVQUFnSSxFQUFFO1FBQ25KLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2xCLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENB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
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare const toolCacheMarkerFile = ".gitzone-tool-cache.json";
|
|
2
|
+
export declare const tsrustCacheOwner = "@git.zone/tsrust";
|
|
3
|
+
export declare const targetCacheKind = "rust-target-cache";
|
|
4
|
+
export interface IToolCacheMarker {
|
|
5
|
+
owner: string;
|
|
6
|
+
kind: string;
|
|
7
|
+
safeToPrune: boolean;
|
|
8
|
+
createdAt: string;
|
|
9
|
+
schemaVersion: 1;
|
|
10
|
+
}
|
|
11
|
+
export interface ITsrustPruneCandidate {
|
|
12
|
+
path: string;
|
|
13
|
+
workspace: string;
|
|
14
|
+
bytes: number;
|
|
15
|
+
marked: boolean;
|
|
16
|
+
shouldPrune: boolean;
|
|
17
|
+
reason: string;
|
|
18
|
+
truncated?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface ITsrustPruneOptions {
|
|
21
|
+
workspace: string;
|
|
22
|
+
targetDir?: string;
|
|
23
|
+
days?: number;
|
|
24
|
+
maxSizeBytes?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function createTargetCacheMarker(): IToolCacheMarker;
|
|
27
|
+
export declare function isValidTargetCacheMarker(markerArg: unknown): markerArg is IToolCacheMarker;
|
|
28
|
+
export declare function getDefaultManagedTargetDir(workspaceArg: string): string;
|
|
29
|
+
export declare function isSafeManagedTargetDir(workspaceArg: string, targetDirArg: string): boolean;
|
|
30
|
+
export declare function resolveManagedTargetDir(workspaceArg: string, configTargetDirArg?: string): string;
|
|
31
|
+
export declare function getCargoArtifactDir(targetDirArg: string, profileArg: string, targetTripleArg?: string): string;
|
|
32
|
+
export declare function parseSizeToBytes(valueArg: string | undefined): number | undefined;
|
|
33
|
+
export declare function writeTargetCacheMarker(targetDirArg: string): Promise<void>;
|
|
34
|
+
export declare function readTargetCacheMarker(targetDirArg: string): Promise<IToolCacheMarker | undefined>;
|
|
35
|
+
export declare function getDirectorySize(pathArg: string): Promise<number>;
|
|
36
|
+
export declare function createTsrustPrunePlan(optionsArg: ITsrustPruneOptions): Promise<ITsrustPruneCandidate[]>;
|
|
37
|
+
export declare function applyTsrustPrunePlan(planArg: ITsrustPruneCandidate[]): Promise<void>;
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
export const toolCacheMarkerFile = '.gitzone-tool-cache.json';
|
|
4
|
+
export const tsrustCacheOwner = '@git.zone/tsrust';
|
|
5
|
+
export const targetCacheKind = 'rust-target-cache';
|
|
6
|
+
export function createTargetCacheMarker() {
|
|
7
|
+
return {
|
|
8
|
+
owner: tsrustCacheOwner,
|
|
9
|
+
kind: targetCacheKind,
|
|
10
|
+
safeToPrune: true,
|
|
11
|
+
createdAt: new Date().toISOString(),
|
|
12
|
+
schemaVersion: 1,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function isValidTargetCacheMarker(markerArg) {
|
|
16
|
+
const marker = markerArg;
|
|
17
|
+
return marker.owner === tsrustCacheOwner
|
|
18
|
+
&& marker.kind === targetCacheKind
|
|
19
|
+
&& marker.safeToPrune === true
|
|
20
|
+
&& marker.schemaVersion === 1;
|
|
21
|
+
}
|
|
22
|
+
export function getDefaultManagedTargetDir(workspaceArg) {
|
|
23
|
+
return path.resolve(workspaceArg, '.nogit', 'tsrust-target');
|
|
24
|
+
}
|
|
25
|
+
export function isSafeManagedTargetDir(workspaceArg, targetDirArg) {
|
|
26
|
+
const workspace = path.resolve(workspaceArg);
|
|
27
|
+
const targetDir = path.resolve(targetDirArg);
|
|
28
|
+
const relative = path.relative(workspace, targetDir);
|
|
29
|
+
if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return relative === path.join('.nogit', 'tsrust-target')
|
|
33
|
+
|| relative.startsWith(`${path.join('.nogit', 'tsrust-')}`)
|
|
34
|
+
|| relative.startsWith(`${path.join('.nogit', 'tsrust')}${path.sep}`);
|
|
35
|
+
}
|
|
36
|
+
export function resolveManagedTargetDir(workspaceArg, configTargetDirArg) {
|
|
37
|
+
const configured = process.env.TSRUST_TARGET_DIR || configTargetDirArg;
|
|
38
|
+
const targetDir = configured
|
|
39
|
+
? path.isAbsolute(configured) ? configured : path.resolve(workspaceArg, configured)
|
|
40
|
+
: getDefaultManagedTargetDir(workspaceArg);
|
|
41
|
+
if (!isSafeManagedTargetDir(workspaceArg, targetDir)) {
|
|
42
|
+
throw new Error(`Refusing unsafe tsrust target dir outside workspace .nogit/: ${targetDir}`);
|
|
43
|
+
}
|
|
44
|
+
return targetDir;
|
|
45
|
+
}
|
|
46
|
+
export function getCargoArtifactDir(targetDirArg, profileArg, targetTripleArg) {
|
|
47
|
+
return targetTripleArg
|
|
48
|
+
? path.join(targetDirArg, targetTripleArg, profileArg)
|
|
49
|
+
: path.join(targetDirArg, profileArg);
|
|
50
|
+
}
|
|
51
|
+
export function parseSizeToBytes(valueArg) {
|
|
52
|
+
if (!valueArg) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const match = valueArg.trim().match(/^(\d+(?:\.\d+)?)(b|kb|kib|mb|mib|gb|gib)?$/i);
|
|
56
|
+
if (!match) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
const value = Number(match[1]);
|
|
60
|
+
const unit = (match[2] || 'b').toLowerCase();
|
|
61
|
+
const multiplier = unit === 'gb' || unit === 'gib'
|
|
62
|
+
? 1024 ** 3
|
|
63
|
+
: unit === 'mb' || unit === 'mib'
|
|
64
|
+
? 1024 ** 2
|
|
65
|
+
: unit === 'kb' || unit === 'kib'
|
|
66
|
+
? 1024
|
|
67
|
+
: 1;
|
|
68
|
+
return Math.round(value * multiplier);
|
|
69
|
+
}
|
|
70
|
+
export async function writeTargetCacheMarker(targetDirArg) {
|
|
71
|
+
await fs.mkdir(targetDirArg, { recursive: true });
|
|
72
|
+
const existingMarker = await readTargetCacheMarker(targetDirArg);
|
|
73
|
+
if (existingMarker) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const entries = await fs.readdir(targetDirArg);
|
|
77
|
+
if (entries.length > 0) {
|
|
78
|
+
throw new Error(`Refusing to mark pre-existing non-empty tsrust target cache: ${targetDirArg}`);
|
|
79
|
+
}
|
|
80
|
+
await fs.writeFile(path.join(targetDirArg, toolCacheMarkerFile), `${JSON.stringify(createTargetCacheMarker(), null, 2)}\n`);
|
|
81
|
+
}
|
|
82
|
+
export async function readTargetCacheMarker(targetDirArg) {
|
|
83
|
+
try {
|
|
84
|
+
const markerRaw = await fs.readFile(path.join(targetDirArg, toolCacheMarkerFile), 'utf8');
|
|
85
|
+
const marker = JSON.parse(markerRaw);
|
|
86
|
+
return isValidTargetCacheMarker(marker) ? marker : undefined;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function pathExists(pathArg) {
|
|
93
|
+
try {
|
|
94
|
+
await fs.stat(pathArg);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export async function getDirectorySize(pathArg) {
|
|
102
|
+
let total = 0;
|
|
103
|
+
let entries;
|
|
104
|
+
try {
|
|
105
|
+
entries = await fs.readdir(pathArg, { withFileTypes: true });
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
for (const entry of entries) {
|
|
111
|
+
const entryPath = path.join(pathArg, entry.name);
|
|
112
|
+
if (entry.isDirectory()) {
|
|
113
|
+
total += await getDirectorySize(entryPath);
|
|
114
|
+
}
|
|
115
|
+
else if (entry.isFile()) {
|
|
116
|
+
try {
|
|
117
|
+
total += (await fs.stat(entryPath)).size;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Ignore files that disappear while planning a prune.
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return total;
|
|
125
|
+
}
|
|
126
|
+
async function getDirectoryUsage(pathArg, maxEntriesArg = 100_000) {
|
|
127
|
+
let bytes = 0;
|
|
128
|
+
let newestMtimeMs = 0;
|
|
129
|
+
let visitedEntries = 0;
|
|
130
|
+
let truncated = false;
|
|
131
|
+
const visit = async (entryPathArg) => {
|
|
132
|
+
if (visitedEntries >= maxEntriesArg) {
|
|
133
|
+
truncated = true;
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
visitedEntries++;
|
|
137
|
+
let stat;
|
|
138
|
+
try {
|
|
139
|
+
stat = await fs.stat(entryPathArg);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
newestMtimeMs = Math.max(newestMtimeMs, stat.mtimeMs);
|
|
145
|
+
if (stat.isFile()) {
|
|
146
|
+
bytes += stat.size;
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (!stat.isDirectory()) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
let entries;
|
|
153
|
+
try {
|
|
154
|
+
entries = await fs.readdir(entryPathArg, { withFileTypes: true });
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
for (const entry of entries) {
|
|
160
|
+
if (visitedEntries >= maxEntriesArg) {
|
|
161
|
+
truncated = true;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
await visit(path.join(entryPathArg, entry.name));
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
await visit(pathArg);
|
|
168
|
+
return { bytes, newestMtimeMs, truncated };
|
|
169
|
+
}
|
|
170
|
+
async function getNewestMtimeMs(pathArg) {
|
|
171
|
+
let newest = 0;
|
|
172
|
+
try {
|
|
173
|
+
const stat = await fs.stat(pathArg);
|
|
174
|
+
newest = stat.mtimeMs;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
let entries;
|
|
180
|
+
try {
|
|
181
|
+
entries = await fs.readdir(pathArg, { withFileTypes: true });
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return newest;
|
|
185
|
+
}
|
|
186
|
+
for (const entry of entries) {
|
|
187
|
+
const entryPath = path.join(pathArg, entry.name);
|
|
188
|
+
if (entry.isDirectory()) {
|
|
189
|
+
newest = Math.max(newest, await getNewestMtimeMs(entryPath));
|
|
190
|
+
}
|
|
191
|
+
else if (entry.isFile()) {
|
|
192
|
+
try {
|
|
193
|
+
newest = Math.max(newest, (await fs.stat(entryPath)).mtimeMs);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// Ignore files that disappear while planning a prune.
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return newest;
|
|
201
|
+
}
|
|
202
|
+
export async function createTsrustPrunePlan(optionsArg) {
|
|
203
|
+
const workspace = path.resolve(optionsArg.workspace);
|
|
204
|
+
const managedTargetDir = optionsArg.targetDir
|
|
205
|
+
? resolveManagedTargetDir(workspace, optionsArg.targetDir)
|
|
206
|
+
: resolveManagedTargetDir(workspace);
|
|
207
|
+
const candidates = [
|
|
208
|
+
managedTargetDir,
|
|
209
|
+
path.join(workspace, 'rust', 'target'),
|
|
210
|
+
path.join(workspace, 'ts_rust', 'target'),
|
|
211
|
+
];
|
|
212
|
+
const uniqueCandidates = [...new Set(candidates.map((candidate) => path.resolve(candidate)))];
|
|
213
|
+
const pruneCandidates = [];
|
|
214
|
+
const maxAgeMs = typeof optionsArg.days === 'number' ? optionsArg.days * 24 * 60 * 60 * 1000 : undefined;
|
|
215
|
+
for (const candidate of uniqueCandidates) {
|
|
216
|
+
if (!(await pathExists(candidate))) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const marker = await readTargetCacheMarker(candidate);
|
|
220
|
+
const usage = await getDirectoryUsage(candidate);
|
|
221
|
+
const isManagedTarget = isSafeManagedTargetDir(workspace, candidate);
|
|
222
|
+
const ageMatches = typeof maxAgeMs === 'number' ? Date.now() - usage.newestMtimeMs >= maxAgeMs : false;
|
|
223
|
+
const bytes = usage.bytes;
|
|
224
|
+
const sizeMatches = typeof optionsArg.maxSizeBytes === 'number' ? bytes >= optionsArg.maxSizeBytes : false;
|
|
225
|
+
const shouldPrune = !!marker && isManagedTarget && (ageMatches || sizeMatches);
|
|
226
|
+
const reason = marker
|
|
227
|
+
? !isManagedTarget
|
|
228
|
+
? 'marked Rust target outside managed tsrust target allowlist; report-only'
|
|
229
|
+
: shouldPrune
|
|
230
|
+
? [ageMatches ? `older than ${optionsArg.days} day(s)` : '', sizeMatches ? `at least ${optionsArg.maxSizeBytes} bytes` : ''].filter(Boolean).join(', ')
|
|
231
|
+
: 'marked tsrust target cache; below prune thresholds'
|
|
232
|
+
: 'unmarked conventional Rust target; report-only';
|
|
233
|
+
pruneCandidates.push({
|
|
234
|
+
path: candidate,
|
|
235
|
+
workspace,
|
|
236
|
+
bytes,
|
|
237
|
+
marked: !!marker,
|
|
238
|
+
shouldPrune,
|
|
239
|
+
reason,
|
|
240
|
+
truncated: usage.truncated,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
return pruneCandidates;
|
|
244
|
+
}
|
|
245
|
+
export async function applyTsrustPrunePlan(planArg) {
|
|
246
|
+
for (const candidate of planArg) {
|
|
247
|
+
if (!candidate.shouldPrune) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (!isSafeManagedTargetDir(candidate.workspace, candidate.path)) {
|
|
251
|
+
throw new Error(`Refusing unsafe Rust target cache path: ${candidate.path}`);
|
|
252
|
+
}
|
|
253
|
+
const marker = await readTargetCacheMarker(candidate.path);
|
|
254
|
+
if (!marker) {
|
|
255
|
+
throw new Error(`Refusing to remove unmarked Rust target cache: ${candidate.path}`);
|
|
256
|
+
}
|
|
257
|
+
await fs.rm(candidate.path, { recursive: true, force: true });
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50YXJnZXRjYWNoZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL21vZF9jYXJnby9jbGFzc2VzLnRhcmdldGNhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDdkMsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUM7QUFFbEMsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsMEJBQTBCLENBQUM7QUFDOUQsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUM7QUFDbkQsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLG1CQUFtQixDQUFDO0FBMkJuRCxNQUFNLFVBQVUsdUJBQXVCO0lBQ3JDLE9BQU87UUFDTCxLQUFLLEVBQUUsZ0JBQWdCO1FBQ3ZCLElBQUksRUFBRSxlQUFlO1FBQ3JCLFdBQVcsRUFBRSxJQUFJO1FBQ2pCLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtRQUNuQyxhQUFhLEVBQUUsQ0FBQztLQUNqQixDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSx3QkFBd0IsQ0FBQyxTQUFrQjtJQUN6RCxNQUFNLE1BQU0sR0FBRyxTQUFzQyxDQUFDO0lBQ3RELE9BQU8sTUFBTSxDQUFDLEtBQUssS0FBSyxnQkFBZ0I7V0FDbkMsTUFBTSxDQUFDLElBQUksS0FBSyxlQUFlO1dBQy9CLE1BQU0sQ0FBQyxXQUFXLEtBQUssSUFBSTtXQUMzQixNQUFNLENBQUMsYUFBYSxLQUFLLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBRUQsTUFBTSxVQUFVLDBCQUEwQixDQUFDLFlBQW9CO0lBQzdELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFFRCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsWUFBb0IsRUFBRSxZQUFvQjtJ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
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { CargoConfig } from './classes.cargoconfig.js';
|
|
2
2
|
export { CargoRunner } from './classes.cargorunner.js';
|
|
3
|
-
|
|
3
|
+
export * from './classes.targetcache.js';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfY2FyZ28vaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN2RCxjQUFjLDBCQUEwQixDQUFDIn0=
|
|
@@ -11,8 +11,10 @@ export declare class TsRustCli {
|
|
|
11
11
|
*/
|
|
12
12
|
private resolveToolchain;
|
|
13
13
|
private registerStandardCommand;
|
|
14
|
+
private shouldPruneAfterBuild;
|
|
14
15
|
private buildRustflags;
|
|
15
16
|
private registerCleanCommand;
|
|
17
|
+
private registerPruneCommand;
|
|
16
18
|
private detectRustDir;
|
|
17
19
|
run(): void;
|
|
18
20
|
}
|
|
@@ -3,6 +3,7 @@ import * as os from 'os';
|
|
|
3
3
|
import * as plugins from '../plugins.js';
|
|
4
4
|
import { CargoConfig } from '../mod_cargo/index.js';
|
|
5
5
|
import { CargoRunner } from '../mod_cargo/index.js';
|
|
6
|
+
import { applyTsrustPrunePlan, createTsrustPrunePlan, getCargoArtifactDir, parseSizeToBytes, resolveManagedTargetDir, writeTargetCacheMarker, } from '../mod_cargo/index.js';
|
|
6
7
|
import { ElfInspector } from '../mod_elf/index.js';
|
|
7
8
|
import { FsHelpers } from '../mod_fs/index.js';
|
|
8
9
|
import { ToolchainManager } from '../mod_toolchain/index.js';
|
|
@@ -59,6 +60,7 @@ export class TsRustCli {
|
|
|
59
60
|
registerCommands() {
|
|
60
61
|
this.registerStandardCommand();
|
|
61
62
|
this.registerCleanCommand();
|
|
63
|
+
this.registerPruneCommand();
|
|
62
64
|
}
|
|
63
65
|
/**
|
|
64
66
|
* Resolves the Rust toolchain to use. Tries system cargo first,
|
|
@@ -107,6 +109,8 @@ export class TsRustCli {
|
|
|
107
109
|
const shouldClean = !!argvArg.clean;
|
|
108
110
|
const distDir = path.join(this.cwd, 'dist_rust');
|
|
109
111
|
const profile = isDebug ? 'debug' : 'release';
|
|
112
|
+
const managedTargetDir = resolveManagedTargetDir(this.cwd, this.config.targetDir);
|
|
113
|
+
await writeTargetCacheMarker(managedTargetDir);
|
|
110
114
|
// Parse --target flag (can appear multiple times), fall back to smartconfig.json config
|
|
111
115
|
const cliTargets = argvArg.target;
|
|
112
116
|
const targets = cliTargets
|
|
@@ -140,13 +144,13 @@ export class TsRustCli {
|
|
|
140
144
|
target: triple,
|
|
141
145
|
crtStatic: useStatic && wantsCrtStatic(triple),
|
|
142
146
|
rustflags,
|
|
147
|
+
targetDir: managedTargetDir,
|
|
143
148
|
});
|
|
144
149
|
if (!buildResult.success) {
|
|
145
150
|
console.error(`Build failed for target ${triple} with exit code ${buildResult.exitCode}`);
|
|
146
151
|
process.exit(1);
|
|
147
152
|
}
|
|
148
|
-
|
|
149
|
-
const targetDir = path.join(rustDir, 'target', triple, profile);
|
|
153
|
+
const targetDir = getCargoArtifactDir(managedTargetDir, profile, triple);
|
|
150
154
|
for (const binName of workspaceInfo.binTargets) {
|
|
151
155
|
const srcBinary = path.join(targetDir, binName);
|
|
152
156
|
const destName = `${binName}_${friendly}`;
|
|
@@ -191,14 +195,13 @@ export class TsRustCli {
|
|
|
191
195
|
target: nativeTriple,
|
|
192
196
|
crtStatic: !!nativeTriple && wantsCrtStatic(nativeTriple),
|
|
193
197
|
rustflags,
|
|
198
|
+
targetDir: managedTargetDir,
|
|
194
199
|
});
|
|
195
200
|
if (!buildResult.success) {
|
|
196
201
|
console.error(`Build failed with exit code ${buildResult.exitCode}`);
|
|
197
202
|
process.exit(1);
|
|
198
203
|
}
|
|
199
|
-
const targetDir = nativeTriple
|
|
200
|
-
? path.join(rustDir, 'target', nativeTriple, profile)
|
|
201
|
-
: path.join(rustDir, 'target', profile);
|
|
204
|
+
const targetDir = getCargoArtifactDir(managedTargetDir, profile, nativeTriple);
|
|
202
205
|
await FsHelpers.ensureEmptyDir(distDir);
|
|
203
206
|
for (const binName of workspaceInfo.binTargets) {
|
|
204
207
|
const srcBinary = path.join(targetDir, binName);
|
|
@@ -220,10 +223,23 @@ export class TsRustCli {
|
|
|
220
223
|
}
|
|
221
224
|
}
|
|
222
225
|
}
|
|
226
|
+
if (this.shouldPruneAfterBuild()) {
|
|
227
|
+
const plan = await createTsrustPrunePlan({
|
|
228
|
+
workspace: this.cwd,
|
|
229
|
+
targetDir: managedTargetDir,
|
|
230
|
+
days: 0,
|
|
231
|
+
});
|
|
232
|
+
await applyTsrustPrunePlan(plan);
|
|
233
|
+
console.log('Pruned marked tsrust target cache after successful build.');
|
|
234
|
+
}
|
|
223
235
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
224
236
|
console.log(`\nDone in ${elapsed}s`);
|
|
225
237
|
});
|
|
226
238
|
}
|
|
239
|
+
shouldPruneAfterBuild() {
|
|
240
|
+
const normalized = process.env.TSRUST_PRUNE_AFTER_BUILD?.toLowerCase();
|
|
241
|
+
return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'y' || this.config.pruneAfterBuild === true;
|
|
242
|
+
}
|
|
227
243
|
buildRustflags(rustDir) {
|
|
228
244
|
const rustflags = [...(this.config.rustflags || [])];
|
|
229
245
|
if (this.config.remapLocalPaths) {
|
|
@@ -248,7 +264,7 @@ export class TsRustCli {
|
|
|
248
264
|
const envPrefix = await this.resolveToolchain();
|
|
249
265
|
console.log('Running cargo clean...');
|
|
250
266
|
const runner = new CargoRunner(rustDir, envPrefix);
|
|
251
|
-
await runner.clean();
|
|
267
|
+
await runner.clean({ targetDir: resolveManagedTargetDir(this.cwd, this.config.targetDir) });
|
|
252
268
|
console.log('Cargo clean complete.');
|
|
253
269
|
}
|
|
254
270
|
// Remove dist_rust/
|
|
@@ -260,6 +276,35 @@ export class TsRustCli {
|
|
|
260
276
|
console.log('Clean complete.');
|
|
261
277
|
});
|
|
262
278
|
}
|
|
279
|
+
registerPruneCommand() {
|
|
280
|
+
this.cli.addCommand('prune').subscribe(async (argvArg) => {
|
|
281
|
+
const workspace = argvArg.workspace || this.cwd;
|
|
282
|
+
const daysArg = argvArg.days;
|
|
283
|
+
const days = daysArg === undefined ? 14 : Number(daysArg);
|
|
284
|
+
const maxSizeBytes = parseSizeToBytes(argvArg.maxSize);
|
|
285
|
+
const apply = !!argvArg.apply;
|
|
286
|
+
const plan = await createTsrustPrunePlan({
|
|
287
|
+
workspace,
|
|
288
|
+
targetDir: resolveManagedTargetDir(workspace, this.config.targetDir),
|
|
289
|
+
days: Number.isFinite(days) ? days : 14,
|
|
290
|
+
maxSizeBytes,
|
|
291
|
+
});
|
|
292
|
+
console.log(apply ? 'tsrust prune apply plan:' : 'tsrust prune dry-run plan:');
|
|
293
|
+
if (plan.length === 0) {
|
|
294
|
+
console.log('No Rust target caches found.');
|
|
295
|
+
}
|
|
296
|
+
for (const candidate of plan) {
|
|
297
|
+
const action = candidate.shouldPrune ? (apply ? 'remove' : 'would remove') : 'report';
|
|
298
|
+
console.log(`${action}: ${candidate.path} (${FsHelpers.formatFileSize(candidate.bytes)}) - ${candidate.reason}`);
|
|
299
|
+
}
|
|
300
|
+
if (apply) {
|
|
301
|
+
await applyTsrustPrunePlan(plan);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
console.log('Dry-run only. Re-run with --apply to remove marked tsrust target caches.');
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
263
308
|
async detectRustDir() {
|
|
264
309
|
// Check rust/ first
|
|
265
310
|
const rustDir = path.join(this.cwd, 'rust');
|
|
@@ -281,4 +326,4 @@ export const runCli = async () => {
|
|
|
281
326
|
const cli = new TsRustCli();
|
|
282
327
|
cli.run();
|
|
283
328
|
};
|
|
284
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50c3J1c3RjbGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfY2xpL2NsYXNzZXMudHNydXN0Y2xpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUU3RCx3REFBd0Q7QUFDeEQsTUFBTSxjQUFjLEdBQTJCO0lBQzdDLFdBQVcsRUFBRSwwQkFBMEI7SUFDdkMsV0FBVyxFQUFFLDJCQUEyQjtJQUN4QyxnQkFBZ0IsRUFBRSwyQkFBMkI7SUFDN0MsZ0JBQWdCLEVBQUUsNEJBQTRCO0lBQzlDLFdBQVcsRUFBRSxxQkFBcUI7SUFDbEMsV0FBVyxFQUFFLHNCQUFzQjtDQUNwQyxDQUFDO0FBRUYsK0NBQStDO0FBQy9DLE1BQU0sbUJBQW1CLEdBQTJCLEVBQUUsQ0FBQztBQUN2RCxLQUFLLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO0lBQ2hFLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQztBQUN6QyxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxrQkFBa0IsQ0FBQyxJQUFZO0lBQ3RDLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FB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
|
|
329
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50c3J1c3RjbGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfY2xpL2NsYXNzZXMudHNydXN0Y2xpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixxQkFBcUIsRUFDckIsbUJBQW1CLEVBQ25CLGdCQUFnQixFQUNoQix1QkFBdUIsRUFDdkIsc0JBQXNCLEdBQ3ZCLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUU3RCx3REFBd0Q7QUFDeEQsTUFBTSxjQUFjLEdBQTJCO0lBQzdDLFdBQVcsRUFBRSwwQkFBMEI7SUFDdkMsV0FBVyxFQUFFLDJCQUEyQjtJQUN4QyxnQkFBZ0IsRUFBRSwyQkFBMkI7SUFDN0MsZ0JBQWdCLEVBQUUsNEJBQTRCO0lBQzlDLFdBQVcsRUFBRSxxQkFBcUI7SUFDbEMsV0FBVyxFQUFFLHNCQUFzQjtDQUNwQyxDQUFDO0FBRUYsK0NBQStDO0FBQy9DLE1BQU0sbUJBQW1CLEdBQTJCLEVBQUUsQ0FBQztBQUN2RCxLQUFLLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO0lBQ2hFLG1CQUFt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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@git.zone/tsrust",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A tool for compiling Rust projects, detecting Cargo workspaces, building with cargo, and placing binaries in a conventional dist_rust directory.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@git.zone/tsbuild": "^4.4.2",
|
|
42
42
|
"@git.zone/tsrun": "^2.0.4",
|
|
43
43
|
"@git.zone/tstest": "^3.6.6",
|
|
44
|
-
"@types/node": "^25.9.
|
|
44
|
+
"@types/node": "^25.9.3"
|
|
45
45
|
},
|
|
46
46
|
"files": [
|
|
47
47
|
"ts/**/*",
|
package/readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @git.zone/tsrust
|
|
2
2
|
|
|
3
|
-
A CLI build tool for Rust projects that follows the same conventions as `@git.zone/tsbuild`. It detects your `rust/` source directory, parses `Cargo.toml` (including workspaces), runs `cargo build --release
|
|
3
|
+
A CLI build tool for Rust projects that follows the same conventions as `@git.zone/tsbuild`. It detects your `rust/` source directory, parses `Cargo.toml` (including workspaces), runs `cargo build --release` with a managed target cache, and copies the resulting binaries into a clean `dist_rust/` directory at the project root.
|
|
4
4
|
|
|
5
5
|
## Issue Reporting and Security
|
|
6
6
|
|
|
@@ -48,8 +48,9 @@ This will:
|
|
|
48
48
|
2. Locate your `rust/` directory (containing `Cargo.toml`)
|
|
49
49
|
3. Parse the workspace to discover all `[[bin]]` targets
|
|
50
50
|
4. Run `cargo build --release` with full streaming output
|
|
51
|
-
5.
|
|
52
|
-
6.
|
|
51
|
+
5. Store Cargo intermediates in `.nogit/tsrust-target` by default
|
|
52
|
+
6. Copy each binary to `dist_rust/` with executable permissions (`chmod 755`)
|
|
53
|
+
7. Report file sizes and total build time
|
|
53
54
|
|
|
54
55
|
**Example output:**
|
|
55
56
|
|
|
@@ -58,7 +59,7 @@ Using cargo 1.90.0 (840b83a10 2025-07-30)
|
|
|
58
59
|
Found Rust project at: rust
|
|
59
60
|
Detected Cargo workspace
|
|
60
61
|
Binary targets: rustproxy
|
|
61
|
-
Running: cargo build --release
|
|
62
|
+
Running: CARGO_TARGET_DIR="/path/to/project/.nogit/tsrust-target" cargo build --release
|
|
62
63
|
Compiling rustproxy v0.1.0
|
|
63
64
|
Finished `release` profile [optimized] target(s) in 29.01s
|
|
64
65
|
Copied rustproxy (13.4 MB) -> dist_rust/rustproxy
|
|
@@ -85,7 +86,7 @@ Build with the debug profile instead of release:
|
|
|
85
86
|
tsrust --debug
|
|
86
87
|
```
|
|
87
88
|
|
|
88
|
-
Binaries are taken from
|
|
89
|
+
Binaries are taken from `.nogit/tsrust-target/debug/` instead of `.nogit/tsrust-target/release/`.
|
|
89
90
|
|
|
90
91
|
### 🧹 Clean Before Building
|
|
91
92
|
|
|
@@ -138,13 +139,17 @@ You can set default cross-compilation targets in your project's `.smartconfig.js
|
|
|
138
139
|
```json
|
|
139
140
|
{
|
|
140
141
|
"@git.zone/tsrust": {
|
|
141
|
-
"targets": ["linux_arm64", "linux_amd64"]
|
|
142
|
+
"targets": ["linux_arm64", "linux_amd64"],
|
|
143
|
+
"targetDir": ".nogit/tsrust-target",
|
|
144
|
+
"pruneAfterBuild": false
|
|
142
145
|
}
|
|
143
146
|
}
|
|
144
147
|
```
|
|
145
148
|
|
|
146
149
|
When targets are configured in `.smartconfig.json`, simply running `tsrust` will cross-compile for all listed targets. CLI `--target` flags take full precedence — if any `--target` is provided, the `.smartconfig.json` targets are ignored entirely.
|
|
147
150
|
|
|
151
|
+
`targetDir` is optional. It must point to a tsrust-owned path under `.nogit/`, such as `.nogit/tsrust-target` or `.nogit/tsrust-custom-target`. You can also set `TSRUST_TARGET_DIR` for one-off runs. `pruneAfterBuild: true` or `TSRUST_PRUNE_AFTER_BUILD=true` removes the marked managed target cache after binaries have been copied to `dist_rust/`.
|
|
152
|
+
|
|
148
153
|
### Static Linking
|
|
149
154
|
|
|
150
155
|
`tsrust` can produce fully statically linked Linux binaries (static-pie) that run on both glibc distros (Debian/Ubuntu) and musl distros (Alpine). Enable it via `.smartconfig.json`:
|
|
@@ -211,6 +216,29 @@ tsrust clean
|
|
|
211
216
|
|
|
212
217
|
This runs `cargo clean` in the Rust directory and deletes the `dist_rust/` output directory.
|
|
213
218
|
|
|
219
|
+
### 🧹 Prune Rust Target Caches
|
|
220
|
+
|
|
221
|
+
Report Rust target caches without deleting anything:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
tsrust prune
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Apply cleanup to marked tsrust-managed target caches:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
tsrust prune --apply --days 14 --max-size 5GiB
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
| Option | Description |
|
|
234
|
+
| --- | --- |
|
|
235
|
+
| `--apply` | Remove marked managed target caches that match the filters |
|
|
236
|
+
| `--days <n>` | Prune marked caches whose newest file is at least `n` days old; default `14` |
|
|
237
|
+
| `--max-size <size>` | Prune marked caches at or above a size such as `5GiB` |
|
|
238
|
+
| `--workspace <path>` | Inspect another workspace path |
|
|
239
|
+
|
|
240
|
+
Conventional `rust/target` and `ts_rust/target` directories are report-only, even if they carry a marker. Only managed `.nogit/tsrust*` target directories are eligible for `--apply`; arbitrary app data is never marked or removed.
|
|
241
|
+
|
|
214
242
|
## Project Structure
|
|
215
243
|
|
|
216
244
|
`tsrust` expects your project to follow this layout:
|
|
@@ -230,6 +258,8 @@ my-project/
|
|
|
230
258
|
│ └── src/
|
|
231
259
|
├── dist_rust/ # 📦 Output: compiled binaries go here
|
|
232
260
|
│ └── my-binary
|
|
261
|
+
├── .nogit/
|
|
262
|
+
│ └── tsrust-target/ # 🧹 Managed Cargo target cache
|
|
233
263
|
├── ts/ # (your TypeScript code, built by tsbuild)
|
|
234
264
|
├── dist_ts/ # (TypeScript output)
|
|
235
265
|
└── package.json
|
|
@@ -253,7 +283,7 @@ If no `rust/` directory is found, `tsrust` checks for `ts_rust/` as a fallback.
|
|
|
253
283
|
`tsrust` exports its internals for use in other Node.js/TypeScript tools:
|
|
254
284
|
|
|
255
285
|
```typescript
|
|
256
|
-
import { CargoConfig, CargoRunner, FsHelpers, TsRustCli } from '@git.zone/tsrust';
|
|
286
|
+
import { CargoConfig, CargoRunner, FsHelpers, TsRustCli, resolveManagedTargetDir } from '@git.zone/tsrust';
|
|
257
287
|
|
|
258
288
|
// Parse a Cargo workspace
|
|
259
289
|
const config = new CargoConfig('/path/to/rust');
|
|
@@ -263,7 +293,8 @@ console.log(info.binTargets); // ['rustproxy']
|
|
|
263
293
|
|
|
264
294
|
// Run cargo build
|
|
265
295
|
const runner = new CargoRunner('/path/to/rust');
|
|
266
|
-
const
|
|
296
|
+
const targetDir = resolveManagedTargetDir('/path/to/project');
|
|
297
|
+
const result = await runner.build({ debug: false, clean: false, targetDir });
|
|
267
298
|
console.log(result.success); // true
|
|
268
299
|
console.log(result.exitCode); // 0
|
|
269
300
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -29,10 +29,10 @@ export class CargoRunner {
|
|
|
29
29
|
return result.stdout.trim();
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
public async build(options: { debug?: boolean; clean?: boolean; target?: string; crtStatic?: boolean; rustflags?: string[] } = {}): Promise<ICargoRunResult> {
|
|
32
|
+
public async build(options: { debug?: boolean; clean?: boolean; target?: string; crtStatic?: boolean; rustflags?: string[]; targetDir?: string } = {}): Promise<ICargoRunResult> {
|
|
33
33
|
if (options.clean) {
|
|
34
34
|
console.log('Cleaning previous build...');
|
|
35
|
-
await this.clean();
|
|
35
|
+
await this.clean({ targetDir: options.targetDir });
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// crt-static may only be injected together with an explicit --target:
|
|
@@ -53,9 +53,10 @@ export class CargoRunner {
|
|
|
53
53
|
rustflags.unshift('-C', 'target-feature=+crt-static');
|
|
54
54
|
}
|
|
55
55
|
const rustflagsPrefix = rustflags.length ? `RUSTFLAGS=${this.shellQuote(rustflags.join(' '))} ` : '';
|
|
56
|
-
const
|
|
56
|
+
const targetDirPrefix = options.targetDir ? `CARGO_TARGET_DIR=${this.shellQuote(options.targetDir)} ` : '';
|
|
57
|
+
const command = `${this.envPrefix}cd ${this.rustDir} && ${targetDirPrefix}${rustflagsPrefix}cargo build${profile}${targetFlag}`;
|
|
57
58
|
|
|
58
|
-
console.log(`Running: ${rustflagsPrefix}cargo build${profile}${targetFlag}`);
|
|
59
|
+
console.log(`Running: ${targetDirPrefix}${rustflagsPrefix}cargo build${profile}${targetFlag}`);
|
|
59
60
|
const result = await this.shell.exec(command);
|
|
60
61
|
|
|
61
62
|
return {
|
|
@@ -85,8 +86,9 @@ export class CargoRunner {
|
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
public async clean(): Promise<ICargoRunResult> {
|
|
89
|
-
const
|
|
89
|
+
public async clean(options: { targetDir?: string } = {}): Promise<ICargoRunResult> {
|
|
90
|
+
const targetDirPrefix = options.targetDir ? `CARGO_TARGET_DIR=${this.shellQuote(options.targetDir)} ` : '';
|
|
91
|
+
const command = `${this.envPrefix}cd ${this.rustDir} && ${targetDirPrefix}cargo clean`;
|
|
90
92
|
const result = await this.shell.exec(command);
|
|
91
93
|
|
|
92
94
|
return {
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
|
|
4
|
+
export const toolCacheMarkerFile = '.gitzone-tool-cache.json';
|
|
5
|
+
export const tsrustCacheOwner = '@git.zone/tsrust';
|
|
6
|
+
export const targetCacheKind = 'rust-target-cache';
|
|
7
|
+
|
|
8
|
+
export interface IToolCacheMarker {
|
|
9
|
+
owner: string;
|
|
10
|
+
kind: string;
|
|
11
|
+
safeToPrune: boolean;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
schemaVersion: 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ITsrustPruneCandidate {
|
|
17
|
+
path: string;
|
|
18
|
+
workspace: string;
|
|
19
|
+
bytes: number;
|
|
20
|
+
marked: boolean;
|
|
21
|
+
shouldPrune: boolean;
|
|
22
|
+
reason: string;
|
|
23
|
+
truncated?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ITsrustPruneOptions {
|
|
27
|
+
workspace: string;
|
|
28
|
+
targetDir?: string;
|
|
29
|
+
days?: number;
|
|
30
|
+
maxSizeBytes?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function createTargetCacheMarker(): IToolCacheMarker {
|
|
34
|
+
return {
|
|
35
|
+
owner: tsrustCacheOwner,
|
|
36
|
+
kind: targetCacheKind,
|
|
37
|
+
safeToPrune: true,
|
|
38
|
+
createdAt: new Date().toISOString(),
|
|
39
|
+
schemaVersion: 1,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function isValidTargetCacheMarker(markerArg: unknown): markerArg is IToolCacheMarker {
|
|
44
|
+
const marker = markerArg as Partial<IToolCacheMarker>;
|
|
45
|
+
return marker.owner === tsrustCacheOwner
|
|
46
|
+
&& marker.kind === targetCacheKind
|
|
47
|
+
&& marker.safeToPrune === true
|
|
48
|
+
&& marker.schemaVersion === 1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getDefaultManagedTargetDir(workspaceArg: string): string {
|
|
52
|
+
return path.resolve(workspaceArg, '.nogit', 'tsrust-target');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function isSafeManagedTargetDir(workspaceArg: string, targetDirArg: string): boolean {
|
|
56
|
+
const workspace = path.resolve(workspaceArg);
|
|
57
|
+
const targetDir = path.resolve(targetDirArg);
|
|
58
|
+
const relative = path.relative(workspace, targetDir);
|
|
59
|
+
if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return relative === path.join('.nogit', 'tsrust-target')
|
|
63
|
+
|| relative.startsWith(`${path.join('.nogit', 'tsrust-')}`)
|
|
64
|
+
|| relative.startsWith(`${path.join('.nogit', 'tsrust')}${path.sep}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function resolveManagedTargetDir(workspaceArg: string, configTargetDirArg?: string): string {
|
|
68
|
+
const configured = process.env.TSRUST_TARGET_DIR || configTargetDirArg;
|
|
69
|
+
const targetDir = configured
|
|
70
|
+
? path.isAbsolute(configured) ? configured : path.resolve(workspaceArg, configured)
|
|
71
|
+
: getDefaultManagedTargetDir(workspaceArg);
|
|
72
|
+
if (!isSafeManagedTargetDir(workspaceArg, targetDir)) {
|
|
73
|
+
throw new Error(`Refusing unsafe tsrust target dir outside workspace .nogit/: ${targetDir}`);
|
|
74
|
+
}
|
|
75
|
+
return targetDir;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function getCargoArtifactDir(targetDirArg: string, profileArg: string, targetTripleArg?: string): string {
|
|
79
|
+
return targetTripleArg
|
|
80
|
+
? path.join(targetDirArg, targetTripleArg, profileArg)
|
|
81
|
+
: path.join(targetDirArg, profileArg);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function parseSizeToBytes(valueArg: string | undefined): number | undefined {
|
|
85
|
+
if (!valueArg) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
const match = valueArg.trim().match(/^(\d+(?:\.\d+)?)(b|kb|kib|mb|mib|gb|gib)?$/i);
|
|
89
|
+
if (!match) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
const value = Number(match[1]);
|
|
93
|
+
const unit = (match[2] || 'b').toLowerCase();
|
|
94
|
+
const multiplier = unit === 'gb' || unit === 'gib'
|
|
95
|
+
? 1024 ** 3
|
|
96
|
+
: unit === 'mb' || unit === 'mib'
|
|
97
|
+
? 1024 ** 2
|
|
98
|
+
: unit === 'kb' || unit === 'kib'
|
|
99
|
+
? 1024
|
|
100
|
+
: 1;
|
|
101
|
+
return Math.round(value * multiplier);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export async function writeTargetCacheMarker(targetDirArg: string): Promise<void> {
|
|
105
|
+
await fs.mkdir(targetDirArg, { recursive: true });
|
|
106
|
+
const existingMarker = await readTargetCacheMarker(targetDirArg);
|
|
107
|
+
if (existingMarker) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const entries = await fs.readdir(targetDirArg);
|
|
111
|
+
if (entries.length > 0) {
|
|
112
|
+
throw new Error(`Refusing to mark pre-existing non-empty tsrust target cache: ${targetDirArg}`);
|
|
113
|
+
}
|
|
114
|
+
await fs.writeFile(
|
|
115
|
+
path.join(targetDirArg, toolCacheMarkerFile),
|
|
116
|
+
`${JSON.stringify(createTargetCacheMarker(), null, 2)}\n`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function readTargetCacheMarker(targetDirArg: string): Promise<IToolCacheMarker | undefined> {
|
|
121
|
+
try {
|
|
122
|
+
const markerRaw = await fs.readFile(path.join(targetDirArg, toolCacheMarkerFile), 'utf8');
|
|
123
|
+
const marker = JSON.parse(markerRaw);
|
|
124
|
+
return isValidTargetCacheMarker(marker) ? marker : undefined;
|
|
125
|
+
} catch {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function pathExists(pathArg: string): Promise<boolean> {
|
|
131
|
+
try {
|
|
132
|
+
await fs.stat(pathArg);
|
|
133
|
+
return true;
|
|
134
|
+
} catch {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export async function getDirectorySize(pathArg: string): Promise<number> {
|
|
140
|
+
let total = 0;
|
|
141
|
+
let entries;
|
|
142
|
+
try {
|
|
143
|
+
entries = await fs.readdir(pathArg, { withFileTypes: true });
|
|
144
|
+
} catch {
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
for (const entry of entries) {
|
|
149
|
+
const entryPath = path.join(pathArg, entry.name);
|
|
150
|
+
if (entry.isDirectory()) {
|
|
151
|
+
total += await getDirectorySize(entryPath);
|
|
152
|
+
} else if (entry.isFile()) {
|
|
153
|
+
try {
|
|
154
|
+
total += (await fs.stat(entryPath)).size;
|
|
155
|
+
} catch {
|
|
156
|
+
// Ignore files that disappear while planning a prune.
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return total;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async function getDirectoryUsage(pathArg: string, maxEntriesArg = 100_000): Promise<{ bytes: number; newestMtimeMs: number; truncated: boolean }> {
|
|
165
|
+
let bytes = 0;
|
|
166
|
+
let newestMtimeMs = 0;
|
|
167
|
+
let visitedEntries = 0;
|
|
168
|
+
let truncated = false;
|
|
169
|
+
|
|
170
|
+
const visit = async (entryPathArg: string): Promise<void> => {
|
|
171
|
+
if (visitedEntries >= maxEntriesArg) {
|
|
172
|
+
truncated = true;
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
visitedEntries++;
|
|
176
|
+
|
|
177
|
+
let stat;
|
|
178
|
+
try {
|
|
179
|
+
stat = await fs.stat(entryPathArg);
|
|
180
|
+
} catch {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
newestMtimeMs = Math.max(newestMtimeMs, stat.mtimeMs);
|
|
184
|
+
if (stat.isFile()) {
|
|
185
|
+
bytes += stat.size;
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (!stat.isDirectory()) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let entries;
|
|
193
|
+
try {
|
|
194
|
+
entries = await fs.readdir(entryPathArg, { withFileTypes: true });
|
|
195
|
+
} catch {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
for (const entry of entries) {
|
|
199
|
+
if (visitedEntries >= maxEntriesArg) {
|
|
200
|
+
truncated = true;
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
await visit(path.join(entryPathArg, entry.name));
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
await visit(pathArg);
|
|
208
|
+
return { bytes, newestMtimeMs, truncated };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async function getNewestMtimeMs(pathArg: string): Promise<number> {
|
|
212
|
+
let newest = 0;
|
|
213
|
+
try {
|
|
214
|
+
const stat = await fs.stat(pathArg);
|
|
215
|
+
newest = stat.mtimeMs;
|
|
216
|
+
} catch {
|
|
217
|
+
return 0;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let entries;
|
|
221
|
+
try {
|
|
222
|
+
entries = await fs.readdir(pathArg, { withFileTypes: true });
|
|
223
|
+
} catch {
|
|
224
|
+
return newest;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
for (const entry of entries) {
|
|
228
|
+
const entryPath = path.join(pathArg, entry.name);
|
|
229
|
+
if (entry.isDirectory()) {
|
|
230
|
+
newest = Math.max(newest, await getNewestMtimeMs(entryPath));
|
|
231
|
+
} else if (entry.isFile()) {
|
|
232
|
+
try {
|
|
233
|
+
newest = Math.max(newest, (await fs.stat(entryPath)).mtimeMs);
|
|
234
|
+
} catch {
|
|
235
|
+
// Ignore files that disappear while planning a prune.
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return newest;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export async function createTsrustPrunePlan(optionsArg: ITsrustPruneOptions): Promise<ITsrustPruneCandidate[]> {
|
|
244
|
+
const workspace = path.resolve(optionsArg.workspace);
|
|
245
|
+
const managedTargetDir = optionsArg.targetDir
|
|
246
|
+
? resolveManagedTargetDir(workspace, optionsArg.targetDir)
|
|
247
|
+
: resolveManagedTargetDir(workspace);
|
|
248
|
+
const candidates = [
|
|
249
|
+
managedTargetDir,
|
|
250
|
+
path.join(workspace, 'rust', 'target'),
|
|
251
|
+
path.join(workspace, 'ts_rust', 'target'),
|
|
252
|
+
];
|
|
253
|
+
const uniqueCandidates = [...new Set(candidates.map((candidate) => path.resolve(candidate)))];
|
|
254
|
+
const pruneCandidates: ITsrustPruneCandidate[] = [];
|
|
255
|
+
const maxAgeMs = typeof optionsArg.days === 'number' ? optionsArg.days * 24 * 60 * 60 * 1000 : undefined;
|
|
256
|
+
|
|
257
|
+
for (const candidate of uniqueCandidates) {
|
|
258
|
+
if (!(await pathExists(candidate))) {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const marker = await readTargetCacheMarker(candidate);
|
|
262
|
+
const usage = await getDirectoryUsage(candidate);
|
|
263
|
+
const isManagedTarget = isSafeManagedTargetDir(workspace, candidate);
|
|
264
|
+
const ageMatches = typeof maxAgeMs === 'number' ? Date.now() - usage.newestMtimeMs >= maxAgeMs : false;
|
|
265
|
+
const bytes = usage.bytes;
|
|
266
|
+
const sizeMatches = typeof optionsArg.maxSizeBytes === 'number' ? bytes >= optionsArg.maxSizeBytes : false;
|
|
267
|
+
const shouldPrune = !!marker && isManagedTarget && (ageMatches || sizeMatches);
|
|
268
|
+
const reason = marker
|
|
269
|
+
? !isManagedTarget
|
|
270
|
+
? 'marked Rust target outside managed tsrust target allowlist; report-only'
|
|
271
|
+
: shouldPrune
|
|
272
|
+
? [ageMatches ? `older than ${optionsArg.days} day(s)` : '', sizeMatches ? `at least ${optionsArg.maxSizeBytes} bytes` : ''].filter(Boolean).join(', ')
|
|
273
|
+
: 'marked tsrust target cache; below prune thresholds'
|
|
274
|
+
: 'unmarked conventional Rust target; report-only';
|
|
275
|
+
|
|
276
|
+
pruneCandidates.push({
|
|
277
|
+
path: candidate,
|
|
278
|
+
workspace,
|
|
279
|
+
bytes,
|
|
280
|
+
marked: !!marker,
|
|
281
|
+
shouldPrune,
|
|
282
|
+
reason,
|
|
283
|
+
truncated: usage.truncated,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return pruneCandidates;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export async function applyTsrustPrunePlan(planArg: ITsrustPruneCandidate[]): Promise<void> {
|
|
291
|
+
for (const candidate of planArg) {
|
|
292
|
+
if (!candidate.shouldPrune) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (!isSafeManagedTargetDir(candidate.workspace, candidate.path)) {
|
|
296
|
+
throw new Error(`Refusing unsafe Rust target cache path: ${candidate.path}`);
|
|
297
|
+
}
|
|
298
|
+
const marker = await readTargetCacheMarker(candidate.path);
|
|
299
|
+
if (!marker) {
|
|
300
|
+
throw new Error(`Refusing to remove unmarked Rust target cache: ${candidate.path}`);
|
|
301
|
+
}
|
|
302
|
+
await fs.rm(candidate.path, { recursive: true, force: true });
|
|
303
|
+
}
|
|
304
|
+
}
|
package/ts/mod_cargo/index.ts
CHANGED
|
@@ -3,6 +3,14 @@ import * as os from 'os';
|
|
|
3
3
|
import * as plugins from '../plugins.js';
|
|
4
4
|
import { CargoConfig } from '../mod_cargo/index.js';
|
|
5
5
|
import { CargoRunner } from '../mod_cargo/index.js';
|
|
6
|
+
import {
|
|
7
|
+
applyTsrustPrunePlan,
|
|
8
|
+
createTsrustPrunePlan,
|
|
9
|
+
getCargoArtifactDir,
|
|
10
|
+
parseSizeToBytes,
|
|
11
|
+
resolveManagedTargetDir,
|
|
12
|
+
writeTargetCacheMarker,
|
|
13
|
+
} from '../mod_cargo/index.js';
|
|
6
14
|
import { ElfInspector } from '../mod_elf/index.js';
|
|
7
15
|
import { FsHelpers } from '../mod_fs/index.js';
|
|
8
16
|
import { ToolchainManager } from '../mod_toolchain/index.js';
|
|
@@ -48,6 +56,8 @@ interface ITsrustConfig {
|
|
|
48
56
|
static?: boolean;
|
|
49
57
|
rustflags?: string[];
|
|
50
58
|
remapLocalPaths?: boolean;
|
|
59
|
+
targetDir?: string;
|
|
60
|
+
pruneAfterBuild?: boolean;
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
/** crt-static injection only applies to glibc targets; musl is static by default. */
|
|
@@ -75,6 +85,7 @@ export class TsRustCli {
|
|
|
75
85
|
private registerCommands(): void {
|
|
76
86
|
this.registerStandardCommand();
|
|
77
87
|
this.registerCleanCommand();
|
|
88
|
+
this.registerPruneCommand();
|
|
78
89
|
}
|
|
79
90
|
|
|
80
91
|
/**
|
|
@@ -135,6 +146,8 @@ export class TsRustCli {
|
|
|
135
146
|
const shouldClean = !!(argvArg as any).clean;
|
|
136
147
|
const distDir = path.join(this.cwd, 'dist_rust');
|
|
137
148
|
const profile = isDebug ? 'debug' : 'release';
|
|
149
|
+
const managedTargetDir = resolveManagedTargetDir(this.cwd, this.config.targetDir);
|
|
150
|
+
await writeTargetCacheMarker(managedTargetDir);
|
|
138
151
|
|
|
139
152
|
// Parse --target flag (can appear multiple times), fall back to smartconfig.json config
|
|
140
153
|
const cliTargets = (argvArg as any).target;
|
|
@@ -175,6 +188,7 @@ export class TsRustCli {
|
|
|
175
188
|
target: triple,
|
|
176
189
|
crtStatic: useStatic && wantsCrtStatic(triple),
|
|
177
190
|
rustflags,
|
|
191
|
+
targetDir: managedTargetDir,
|
|
178
192
|
});
|
|
179
193
|
|
|
180
194
|
if (!buildResult.success) {
|
|
@@ -182,8 +196,7 @@ export class TsRustCli {
|
|
|
182
196
|
process.exit(1);
|
|
183
197
|
}
|
|
184
198
|
|
|
185
|
-
|
|
186
|
-
const targetDir = path.join(rustDir, 'target', triple, profile);
|
|
199
|
+
const targetDir = getCargoArtifactDir(managedTargetDir, profile, triple);
|
|
187
200
|
|
|
188
201
|
for (const binName of workspaceInfo.binTargets) {
|
|
189
202
|
const srcBinary = path.join(targetDir, binName);
|
|
@@ -234,6 +247,7 @@ export class TsRustCli {
|
|
|
234
247
|
target: nativeTriple,
|
|
235
248
|
crtStatic: !!nativeTriple && wantsCrtStatic(nativeTriple),
|
|
236
249
|
rustflags,
|
|
250
|
+
targetDir: managedTargetDir,
|
|
237
251
|
});
|
|
238
252
|
|
|
239
253
|
if (!buildResult.success) {
|
|
@@ -241,9 +255,7 @@ export class TsRustCli {
|
|
|
241
255
|
process.exit(1);
|
|
242
256
|
}
|
|
243
257
|
|
|
244
|
-
const targetDir = nativeTriple
|
|
245
|
-
? path.join(rustDir, 'target', nativeTriple, profile)
|
|
246
|
-
: path.join(rustDir, 'target', profile);
|
|
258
|
+
const targetDir = getCargoArtifactDir(managedTargetDir, profile, nativeTriple);
|
|
247
259
|
|
|
248
260
|
await FsHelpers.ensureEmptyDir(distDir);
|
|
249
261
|
|
|
@@ -272,11 +284,26 @@ export class TsRustCli {
|
|
|
272
284
|
}
|
|
273
285
|
}
|
|
274
286
|
|
|
287
|
+
if (this.shouldPruneAfterBuild()) {
|
|
288
|
+
const plan = await createTsrustPrunePlan({
|
|
289
|
+
workspace: this.cwd,
|
|
290
|
+
targetDir: managedTargetDir,
|
|
291
|
+
days: 0,
|
|
292
|
+
});
|
|
293
|
+
await applyTsrustPrunePlan(plan);
|
|
294
|
+
console.log('Pruned marked tsrust target cache after successful build.');
|
|
295
|
+
}
|
|
296
|
+
|
|
275
297
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
276
298
|
console.log(`\nDone in ${elapsed}s`);
|
|
277
299
|
});
|
|
278
300
|
}
|
|
279
301
|
|
|
302
|
+
private shouldPruneAfterBuild(): boolean {
|
|
303
|
+
const normalized = process.env.TSRUST_PRUNE_AFTER_BUILD?.toLowerCase();
|
|
304
|
+
return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'y' || this.config.pruneAfterBuild === true;
|
|
305
|
+
}
|
|
306
|
+
|
|
280
307
|
private buildRustflags(rustDir: string): string[] {
|
|
281
308
|
const rustflags = [...(this.config.rustflags || [])];
|
|
282
309
|
if (this.config.remapLocalPaths) {
|
|
@@ -303,7 +330,7 @@ export class TsRustCli {
|
|
|
303
330
|
const envPrefix = await this.resolveToolchain();
|
|
304
331
|
console.log('Running cargo clean...');
|
|
305
332
|
const runner = new CargoRunner(rustDir, envPrefix);
|
|
306
|
-
await runner.clean();
|
|
333
|
+
await runner.clean({ targetDir: resolveManagedTargetDir(this.cwd, this.config.targetDir) });
|
|
307
334
|
console.log('Cargo clean complete.');
|
|
308
335
|
}
|
|
309
336
|
|
|
@@ -318,6 +345,36 @@ export class TsRustCli {
|
|
|
318
345
|
});
|
|
319
346
|
}
|
|
320
347
|
|
|
348
|
+
private registerPruneCommand(): void {
|
|
349
|
+
this.cli.addCommand('prune').subscribe(async (argvArg) => {
|
|
350
|
+
const workspace = ((argvArg as any).workspace as string | undefined) || this.cwd;
|
|
351
|
+
const daysArg = (argvArg as any).days;
|
|
352
|
+
const days = daysArg === undefined ? 14 : Number(daysArg);
|
|
353
|
+
const maxSizeBytes = parseSizeToBytes((argvArg as any).maxSize as string | undefined);
|
|
354
|
+
const apply = !!(argvArg as any).apply;
|
|
355
|
+
const plan = await createTsrustPrunePlan({
|
|
356
|
+
workspace,
|
|
357
|
+
targetDir: resolveManagedTargetDir(workspace, this.config.targetDir),
|
|
358
|
+
days: Number.isFinite(days) ? days : 14,
|
|
359
|
+
maxSizeBytes,
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
console.log(apply ? 'tsrust prune apply plan:' : 'tsrust prune dry-run plan:');
|
|
363
|
+
if (plan.length === 0) {
|
|
364
|
+
console.log('No Rust target caches found.');
|
|
365
|
+
}
|
|
366
|
+
for (const candidate of plan) {
|
|
367
|
+
const action = candidate.shouldPrune ? (apply ? 'remove' : 'would remove') : 'report';
|
|
368
|
+
console.log(`${action}: ${candidate.path} (${FsHelpers.formatFileSize(candidate.bytes)}) - ${candidate.reason}`);
|
|
369
|
+
}
|
|
370
|
+
if (apply) {
|
|
371
|
+
await applyTsrustPrunePlan(plan);
|
|
372
|
+
} else {
|
|
373
|
+
console.log('Dry-run only. Re-run with --apply to remove marked tsrust target caches.');
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
321
378
|
private async detectRustDir(): Promise<string | null> {
|
|
322
379
|
// Check rust/ first
|
|
323
380
|
const rustDir = path.join(this.cwd, 'rust');
|