@truefoundry/tfy-infra-cli 0.1.1 → 0.1.2
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/index.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -12,5 +12,5 @@
|
|
|
12
12
|
`).length>14&&a(" ... (diff truncated)")}}}var be=require("commander"),Ot=require("path"),Ce=require("@truefoundry/tfy-infra-engine");var Tt=require("fs/promises"),$e=require("path"),et=require("@truefoundry/tfy-infra-engine");async function xt(e,t=et.DEFAULT_PREFIX){let r=new Map,n;try{n=(await(0,Tt.readdir)(e,{withFileTypes:!0})).filter(i=>i.isFile()).map(i=>i.name)}catch(o){throw o.code==="ENOENT"?new Error(`Directory not found: ${e}`,{cause:o}):new Error(`Failed to read directory: ${o.message}`,{cause:o})}for(let o of n){if(o==="manifest.json")continue;let i=await(0,Tt.readFile)((0,$e.join)(e,o),"utf-8"),u=(0,et.classifyFile)(o,t),s={content:i,zone:u};if(u==="platform"){let c=(0,et.parseHeader)(i);c&&(s.header=c)}r.set(o,s)}return r}var wr=1;function Ie(){return new be.Command("verify").description("Check integrity of files on disk against a manifest").option("-d, --directory <dir>","Path to cluster directory containing manifest.json",".").option("--json","Output drift report as structured JSON").action(async t=>{try{let r=await vr(t);process.exit(r)}catch(r){b(r)}})}async function vr(e){let t=(0,Ot.resolve)(e.directory),r=(0,Ot.join)(t,"manifest.json");g(`Loading manifest from ${r}`);let n=await _(r);g(`Reading files from ${t}`);let o=await xt(t,n.platformPrefix),u=await(0,Ce.createEngine)().verify(o,n);return e.json?a(Rr(u.driftReport)):a(Er(u.driftReport)),u.driftReport.valid?d.SUCCESS:wr}function Er(e){let t=[],r=e.summary.driftedFiles+e.summary.missingFiles+e.summary.unexpectedFiles;if(e.valid)t.push(`\u2713 Verification passed: ${e.summary.totalFiles} files checked, ${r} issues`),t.push(""),t.push(`Aggregate Hash: ${e.aggregateHash.expected}`);else{t.push(`\u2717 Drift detected: ${r} issues found`),t.push("");for(let n of e.entries){let o=ht(n.type);t.push(` ${o} ${n.path}`),t.push(` ${n.details}`),t.push("")}t.push(`Summary: ${e.summary.totalFiles} files checked, ${e.summary.driftedFiles} drifted, ${e.summary.missingFiles} missing`+(e.summary.unexpectedFiles>0?`, ${e.summary.unexpectedFiles} unexpected`:""))}return t.join(`
|
|
13
13
|
`)}function Rr(e){return JSON.stringify(e,null,2)}var Fe=require("commander"),J=require("path"),Se=require("@truefoundry/tfy-infra-engine");var Pe=3;function Tr(e){if(e.config&&e.fromManifest)throw new Error("--config and --from-manifest are mutually exclusive. Use one or the other.");if(!e.config&&!e.fromManifest)throw new Error("Either --config <path> or --from-manifest <manifest-path> is required.");if(e.fromManifest&&!e.template)throw new Error("--from-manifest requires --template <new-uri> to specify the new template version.")}function De(){return new Fe.Command("upgrade").description("Upgrade platform files to a new template version").option("-c, --config <path>","Path to envelope config file (YAML or JSON)").option("-d, --directory <dir>","Directory containing current cluster files",".").option("-o, --output <dir>","Output directory for upgraded files (defaults to --directory)").option("--force","Proceed with upgrade even if drift is detected").option("--dry-run","Show what would change without writing files").option("--json","Output results as structured JSON").option("--from-manifest <path>","Path to manifest.json as input source").option("--template <uri>","New template URI (required with --from-manifest)").option("--skip-format","Skip tofu fmt formatting").option("--no-cache","Force re-fetch template").option("--timeout <ms>","Network timeout in milliseconds","30000").action(async t=>{try{t.config&&(t.config=(0,J.resolve)(t.config)),t.fromManifest&&(t.fromManifest=(0,J.resolve)(t.fromManifest)),Tr({config:t.config,fromManifest:t.fromManifest,template:t.template});let r=await xr(t);process.exit(r)}catch(r){b(r)}})}async function xr(e){let t=(0,J.resolve)(e.directory),r=e.output?(0,J.resolve)(e.output):t,n=parseInt(e.timeout,10),o=(0,J.join)(t,"manifest.json");g(`Loading manifest from ${o}`);let i=await _(o);g(`Reading files from ${t}`);let u=await xt(t,i.platformPrefix),s;if(e.fromManifest){let y=await _(e.fromManifest);s=K(y),s.template=e.template}else s=await X(e.config);v(`Template: ${s.template}`),g(`Intent ID: ${s.intentId}`),g("Resolving template...");let m={template:await I().resolve(s.template,{noCache:e.cache===!1,timeout:n}),inputs:s.inputs,intentId:s.intentId,platformPrefix:s.platformPrefix,options:{skipFormat:e.skipFormat??s.options?.skipFormat}},l=await(0,Se.createEngine)().upgrade(m,u,i);return l.sourceBlocked?(w("Upgrade blocked: template source mismatch"),a("The current files were generated from a different template source."),Pe):!l.driftReport.valid&&!e.force?Or(l,e.json):e.dryRun?$r(l,e.json):(await Y(r,l,"upgrade"),e.json?a(_e(l)):a(Ne(l)),d.SUCCESS)}function Or(e,t){let r=e.driftReport.summary.driftedFiles+e.driftReport.summary.missingFiles+e.driftReport.summary.unexpectedFiles;if(t)a(JSON.stringify({blocked:!0,reason:"drift_detected",driftReport:e.driftReport},null,2));else{w(`Upgrade blocked: drift detected in ${r} files`),a("");for(let n of e.driftReport.entries){let o=ht(n.type);a(` ${o} ${n.path}`),a(` ${n.details}`)}a(""),a("Use --force to override and proceed with upgrade.")}return Pe}function $r(e,t){return t?a(_e(e)):(a("Dry run \u2014 no files written."),a(""),a(Ne(e))),d.SUCCESS}function Ne(e){let t=[];t.push(`\u2713 Upgrade complete: ${e.manifest.templateSource} v${e.manifest.templateVersion}`),t.push("");let r=0,n=0;for(let[,o]of e.files)o.zone==="platform"?r++:n++;return t.push(` Updated: ${r} files (Platform Zone)`),t.push(` Unchanged: ${n} files (User Zone)`),t.push(""),t.push(`Aggregate Hash: ${e.manifest.aggregateHash}`),t.join(`
|
|
14
14
|
`)}function _e(e){return JSON.stringify({success:!0,templateSource:e.manifest.templateSource,templateVersion:e.manifest.templateVersion,aggregateHash:e.manifest.aggregateHash,driftReport:e.driftReport,files:Array.from(e.files.entries()).map(([t,r])=>({path:t,zone:r.zone}))},null,2)}var Ae=require("commander"),At=require("path"),ke=require("@truefoundry/tfy-infra-engine");function Ue(){return new Ae.Command("hash").description("Compute the expected aggregate hash without generating files").option("-c, --config <path>","Path to envelope config file (YAML or JSON)").option("--from-manifest <path>","Path to manifest.json to use as input source").option("--json","Output result as structured JSON").option("--skip-format","Skip tofu fmt formatting").option("--no-cache","Force re-fetch template").option("--timeout <ms>","Network timeout in milliseconds","30000").action(async t=>{try{if(t.config&&(t.config=(0,At.resolve)(t.config)),t.fromManifest&&(t.fromManifest=(0,At.resolve)(t.fromManifest)),t.config&&t.fromManifest)throw new Error("--config and --from-manifest are mutually exclusive. Use one or the other.");if(!t.config&&!t.fromManifest)throw new Error("Either --config <path> or --from-manifest <manifest-path> is required.");let r=await br(t);process.exit(r)}catch(r){b(r)}})}async function br(e){let t=parseInt(e.timeout,10),r;if(e.fromManifest){g(`Loading manifest from ${e.fromManifest}`);let c=await _(e.fromManifest);r=K(c)}else g(`Loading config from ${e.config}`),r=await X(e.config);g(`Template: ${r.template}`),g("Resolving template...");let i={template:await I().resolve(r.template,{noCache:e.cache===!1,timeout:t}),inputs:r.inputs,intentId:r.intentId,platformPrefix:r.platformPrefix,options:{skipFormat:e.skipFormat??r.options?.skipFormat}},s=await(0,ke.createEngine)().hashOnly(i);return e.json?a(Ir(s)):a(Cr(s)),d.SUCCESS}function Cr(e){let t=[];return t.push(`Aggregate Hash: ${e.aggregateHash}`),t.push(`Template: ${e.templateSource}`),t.push(`Version: ${e.templateVersion}`),t.push(`Files: ${e.fileCount}`),t.join(`
|
|
15
|
-
`)}function Ir(e){return JSON.stringify(e,null,2)}function je(){let e=new Me.Command("tpl").description("Template operations");return e.addCommand(xe()),e.addCommand(oe()),e.addCommand(ae()),e.addCommand(pe()),e.addCommand(he()),e.addCommand(Ie()),e.addCommand(De()),e.addCommand(Ue()),e}process.env.INIT_CWD&&process.chdir(process.env.INIT_CWD);var Fr="0.1.
|
|
15
|
+
`)}function Ir(e){return JSON.stringify(e,null,2)}function je(){let e=new Me.Command("tpl").description("Template operations");return e.addCommand(xe()),e.addCommand(oe()),e.addCommand(ae()),e.addCommand(pe()),e.addCommand(he()),e.addCommand(Ie()),e.addCommand(De()),e.addCommand(Ue()),e}process.env.INIT_CWD&&process.chdir(process.env.INIT_CWD);var Fr="0.1.2";async function Sr(){let e=new Ve.Command;e.name("tfy-init").description("TrueFoundry infrastructure templating CLI").version(Fr,"-v, --version","Show version").option("--verbose","Enable verbose output").option("-q, --quiet","Suppress non-error output").hook("preAction",t=>{let r=t.opts();r.quiet?Dt("quiet"):r.verbose&&Dt("verbose")}),e.addCommand(je()),await e.parseAsync(process.argv)}Sr().catch(e=>{console.error("Fatal error:",e),process.exit(1)});
|
|
16
16
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truefoundry/tfy-infra-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "CLI for TrueFoundry infrastructure templating engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"prepublishOnly": "yarn build"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@truefoundry/tfy-infra-engine": "
|
|
22
|
+
"@truefoundry/tfy-infra-engine": "0.1.2",
|
|
23
23
|
"chokidar": "^5.0.0",
|
|
24
24
|
"commander": "^14.0.3",
|
|
25
25
|
"diff": "^8.0.3",
|