@ganakailabs/cloudeval-cli 0.27.2 → 0.28.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/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/{App-VSOTHLOD.js → App-3RDW53BW.js} +2 -2
- package/dist/{Banner-7XUOJYL5.js → Banner-HGG5NHXF.js} +2 -2
- package/dist/{chunk-3DBCT463.js → chunk-GGHX5LSI.js} +1 -1
- package/dist/{chunk-SLRYBS3P.js → chunk-JFJQZGZH.js} +1 -1
- package/dist/cli.js +179 -34
- package/package.json +1 -1
- package/sbom.spdx.json +4 -4
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -235,7 +235,7 @@ This notice is not a substitute for legal review before public or enterprise dis
|
|
|
235
235
|
| safer-buffer | 2.1.2 | MIT | Nikita Skovoroda | https://github.com/ChALkeR/safer-buffer#readme |
|
|
236
236
|
| scheduler | 0.23.2 | MIT | NOASSERTION | https://reactjs.org/ |
|
|
237
237
|
| semver | 7.7.3 | ISC | GitHub Inc. | https://github.com/npm/node-semver#readme |
|
|
238
|
-
| shell-quote | 1.8.
|
|
238
|
+
| shell-quote | 1.8.4 | MIT | James Halliday | https://github.com/ljharb/shell-quote |
|
|
239
239
|
| signal-exit | 3.0.7 | ISC | Ben Coe | https://github.com/tapjs/signal-exit |
|
|
240
240
|
| skin-tone | 2.0.0 | MIT | Sindre Sorhus | https://github.com/sindresorhus/skin-tone#readme |
|
|
241
241
|
| slice-ansi | 5.0.0 | MIT | NOASSERTION | https://github.com/chalk/slice-ansi#readme |
|
|
@@ -38,10 +38,10 @@ import {
|
|
|
38
38
|
} from "./chunk-USSCB2ZU.js";
|
|
39
39
|
import {
|
|
40
40
|
Banner
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-GGHX5LSI.js";
|
|
42
42
|
import {
|
|
43
43
|
CLI_VERSION
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-JFJQZGZH.js";
|
|
45
45
|
import {
|
|
46
46
|
raisedButtonStyle,
|
|
47
47
|
terminalTheme
|
package/dist/cli.js
CHANGED
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
} from "./chunk-USSCB2ZU.js";
|
|
40
40
|
import {
|
|
41
41
|
CLI_VERSION
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-JFJQZGZH.js";
|
|
43
43
|
|
|
44
44
|
// src/runtime/prepareInk.ts
|
|
45
45
|
import fs from "fs";
|
|
@@ -2842,10 +2842,14 @@ var namedAmount = (record) => numberFrom(
|
|
|
2842
2842
|
record.amount,
|
|
2843
2843
|
record.monthly_cost,
|
|
2844
2844
|
record.monthlyCost,
|
|
2845
|
+
record.monthly_cost_estimate,
|
|
2846
|
+
record.monthlyCostEstimate,
|
|
2845
2847
|
record.cost,
|
|
2846
2848
|
record.value
|
|
2847
2849
|
);
|
|
2848
|
-
var namedLabel = (record, fallback) => String(
|
|
2850
|
+
var namedLabel = (record, fallback) => String(
|
|
2851
|
+
record.name ?? record.resource_name ?? record.resourceName ?? record.service ?? record.label ?? record.category ?? fallback
|
|
2852
|
+
);
|
|
2849
2853
|
var mermaidLabel = (value) => value.replace(/"/g, "'");
|
|
2850
2854
|
var joinReadableList = (values) => {
|
|
2851
2855
|
if (values.length <= 1) {
|
|
@@ -2869,6 +2873,7 @@ var costServiceRows = (services, currency) => (Array.isArray(services) ? service
|
|
|
2869
2873
|
...rowCurrency ? { currency: rowCurrency } : {}
|
|
2870
2874
|
};
|
|
2871
2875
|
}).filter((service) => service !== void 0);
|
|
2876
|
+
var sortedPositiveCostRows = (rows) => rows.filter((row) => row.amount > 0).sort((left, right) => right.amount - left.amount);
|
|
2872
2877
|
var reconcileCostServiceRows = (services, totalAmount, currency) => {
|
|
2873
2878
|
const total = numberFrom(totalAmount);
|
|
2874
2879
|
if (total === void 0 || services.length === 0) {
|
|
@@ -2897,7 +2902,80 @@ var reconcileCostServiceRows = (services, totalAmount, currency) => {
|
|
|
2897
2902
|
}
|
|
2898
2903
|
return services;
|
|
2899
2904
|
};
|
|
2905
|
+
var compactCostRowsForChart = (rows, totalAmount, currency, options = {}) => {
|
|
2906
|
+
const maxRows = options.maxRows ?? 5;
|
|
2907
|
+
const remainderLabel = options.remainderLabel ?? "Unallocated";
|
|
2908
|
+
const total = numberFrom(totalAmount);
|
|
2909
|
+
const positiveRows = sortedPositiveCostRows(rows);
|
|
2910
|
+
const selected = positiveRows.slice(0, maxRows);
|
|
2911
|
+
const collapsed = positiveRows.slice(maxRows);
|
|
2912
|
+
const collapsedSum = Number(
|
|
2913
|
+
collapsed.reduce((sum, row) => sum + row.amount, 0).toFixed(3)
|
|
2914
|
+
);
|
|
2915
|
+
const result = [...selected];
|
|
2916
|
+
if (collapsedSum > 1e-3) {
|
|
2917
|
+
result.push({
|
|
2918
|
+
name: "Other",
|
|
2919
|
+
amount: collapsedSum,
|
|
2920
|
+
...currency ? { currency } : {}
|
|
2921
|
+
});
|
|
2922
|
+
}
|
|
2923
|
+
const represented = result.reduce((sum, row) => sum + row.amount, 0);
|
|
2924
|
+
if (total !== void 0) {
|
|
2925
|
+
const delta = Number((total - represented).toFixed(3));
|
|
2926
|
+
if (delta > 1e-3) {
|
|
2927
|
+
result.push({
|
|
2928
|
+
name: remainderLabel,
|
|
2929
|
+
amount: delta,
|
|
2930
|
+
...currency ? { currency } : {}
|
|
2931
|
+
});
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2934
|
+
return result;
|
|
2935
|
+
};
|
|
2900
2936
|
var markdownLink = (label, url) => url ? `[${label}](${url})` : label;
|
|
2937
|
+
var openInCloudEvalLines = (links) => {
|
|
2938
|
+
if (!links) {
|
|
2939
|
+
return [];
|
|
2940
|
+
}
|
|
2941
|
+
const reports = asRecord(links.reports);
|
|
2942
|
+
const downloads = asRecord(links.downloads);
|
|
2943
|
+
const entries = [
|
|
2944
|
+
["Project preview", links.project],
|
|
2945
|
+
["Architecture report", reports.architecture],
|
|
2946
|
+
["Cost report", reports.cost],
|
|
2947
|
+
["Validation details", reports.validation],
|
|
2948
|
+
["Download PDF", downloads.pdf],
|
|
2949
|
+
["Workflow run", links.workflowRun],
|
|
2950
|
+
["Download review artifacts", downloads.reviewArtifacts]
|
|
2951
|
+
].filter((entry) => typeof entry[1] === "string" && entry[1].length > 0);
|
|
2952
|
+
return entries.map(([label, url]) => `- ${markdownLink(label, url)}`);
|
|
2953
|
+
};
|
|
2954
|
+
var monthlyCostImpactLines = (currentAmount, savingsAmount, currency) => {
|
|
2955
|
+
const current = numberFrom(currentAmount);
|
|
2956
|
+
const savings = numberFrom(savingsAmount);
|
|
2957
|
+
if (current === void 0 || current <= 0 || savings === void 0 || savings <= 0) {
|
|
2958
|
+
return [];
|
|
2959
|
+
}
|
|
2960
|
+
const optimized = Math.max(current - savings, 0);
|
|
2961
|
+
const savingsPercent = current > 0 ? savings / current * 100 : void 0;
|
|
2962
|
+
const yMax = Math.max(current, optimized, savings);
|
|
2963
|
+
return [
|
|
2964
|
+
"| Metric | Amount |",
|
|
2965
|
+
"| --- | ---: |",
|
|
2966
|
+
`| Current monthly cost | **${formatMonthlyMoney(current, currency)}** |`,
|
|
2967
|
+
`| Potential savings | **${formatMonthlyMoney(savings, currency)}${savingsPercent !== void 0 ? ` (${trimNumber(savingsPercent, 1)}%)` : ""}** |`,
|
|
2968
|
+
`| Optimized monthly cost | **${formatMonthlyMoney(optimized, currency)}** |`,
|
|
2969
|
+
"",
|
|
2970
|
+
"```mermaid",
|
|
2971
|
+
"xychart-beta",
|
|
2972
|
+
' title "Monthly cost impact"',
|
|
2973
|
+
' x-axis ["Current", "Optimized"]',
|
|
2974
|
+
` y-axis "${currency ? `${currency}/mo` : "monthly cost"}" 0 --> ${trimNumber(yMax, 3)}`,
|
|
2975
|
+
` bar [${trimNumber(current, 3)}, ${trimNumber(optimized, 3)}]`,
|
|
2976
|
+
"```"
|
|
2977
|
+
];
|
|
2978
|
+
};
|
|
2901
2979
|
var extractPillars = (waf) => {
|
|
2902
2980
|
const fromArray = waf?.parsed?.score?.pillars;
|
|
2903
2981
|
if (Array.isArray(fromArray)) {
|
|
@@ -3125,6 +3203,16 @@ var evaluateGate = ({
|
|
|
3125
3203
|
currency
|
|
3126
3204
|
},
|
|
3127
3205
|
topServices: (Array.isArray(cost?.parsed?.serviceGroups) ? cost.parsed.serviceGroups : entriesAsNamedRecords(cost?.report?.processed?.cost_by_service_family)).slice(0, 5),
|
|
3206
|
+
topResources: (firstArray(
|
|
3207
|
+
cost?.report?.raw?.resource_estimates,
|
|
3208
|
+
cost?.report?.raw?.resourceEstimates,
|
|
3209
|
+
cost?.raw?.resource_estimates,
|
|
3210
|
+
cost?.raw?.resourceEstimates,
|
|
3211
|
+
cost?.parsed?.resourceEstimates,
|
|
3212
|
+
cost?.parsed?.resource_estimates,
|
|
3213
|
+
preload?.latest_payloads?.cost?.raw?.resource_estimates,
|
|
3214
|
+
preload?.latest_payloads?.cost?.raw?.resourceEstimates
|
|
3215
|
+
) ?? []).slice(0, 20),
|
|
3128
3216
|
recommendations: (Array.isArray(cost?.parsed?.recommendations) ? cost.parsed.recommendations : Array.isArray(cost?.report?.processed?.optimization_recommendations) ? cost.report.processed.optimization_recommendations : []).slice(0, 5)
|
|
3129
3217
|
};
|
|
3130
3218
|
if (!gateConfig) {
|
|
@@ -3397,9 +3485,9 @@ var deterministicAiSummary = (data, error) => {
|
|
|
3397
3485
|
const policyFailed = numberFrom(validation?.policyChecks?.failed) ?? numberFrom(validation?.policy_checks?.failed) ?? numberFrom(data.gate?.policy?.failed) ?? 0;
|
|
3398
3486
|
const policyStatus = policyFailed > 0 ? "has failed checks" : "GOOD";
|
|
3399
3487
|
const summary = [
|
|
3400
|
-
`CloudEval review completed with
|
|
3401
|
-
`Well-Architected posture is
|
|
3402
|
-
"Prioritize failed validation checks and the weakest Well-Architected pillar first."
|
|
3488
|
+
`CloudEval review completed with **${String(data.gate?.status ?? "UNKNOWN").toUpperCase()}**.`,
|
|
3489
|
+
`Well-Architected posture is **${formatScore(score)} (${rating})**, validation has **${displayNumber(failedTests)} failed unit tests**, policy checks are **${policyStatus}**, and monthly cost is **${formatMonthlyMoney(cost?.amount, cost?.currency)}**.`,
|
|
3490
|
+
"Prioritize **failed validation checks** and the **weakest Well-Architected pillar** first."
|
|
3403
3491
|
].join(" ");
|
|
3404
3492
|
return {
|
|
3405
3493
|
enabled: true,
|
|
@@ -3409,17 +3497,17 @@ var deterministicAiSummary = (data, error) => {
|
|
|
3409
3497
|
shortSummary: summary,
|
|
3410
3498
|
detailsMarkdown: [
|
|
3411
3499
|
"**Main risk**\nCloudEval could not produce an AI-written review summary, so use the deterministic gate evidence.",
|
|
3412
|
-
"**Why it matters**\
|
|
3413
|
-
"**Recommended actions**\nFix failed validation checks
|
|
3414
|
-
"**Evidence used**\
|
|
3500
|
+
"**Why it matters**\n**Failed validation** and **weak architecture pillars** are the highest-signal remediation inputs.",
|
|
3501
|
+
"**Recommended actions**\nFix **failed validation checks**, address the **weakest pillar**, rerun CloudEval review, and compare the updated gate.",
|
|
3502
|
+
"**Evidence used**\n**Gate status**, **Well-Architected score**, **validation totals**, **policy totals**, and **monthly cost**."
|
|
3415
3503
|
].join("\n\n"),
|
|
3416
3504
|
markdown: renderAiSummarySections(
|
|
3417
3505
|
summary,
|
|
3418
3506
|
[
|
|
3419
3507
|
"**Main risk**\nCloudEval could not produce an AI-written review summary, so use the deterministic gate evidence.",
|
|
3420
|
-
"**Why it matters**\
|
|
3421
|
-
"**Recommended actions**\nFix failed validation checks
|
|
3422
|
-
"**Evidence used**\
|
|
3508
|
+
"**Why it matters**\n**Failed validation** and **weak architecture pillars** are the highest-signal remediation inputs.",
|
|
3509
|
+
"**Recommended actions**\nFix **failed validation checks**, address the **weakest pillar**, rerun CloudEval review, and compare the updated gate.",
|
|
3510
|
+
"**Evidence used**\n**Gate status**, **Well-Architected score**, **validation totals**, **policy totals**, and **monthly cost**."
|
|
3423
3511
|
].join("\n\n")
|
|
3424
3512
|
)
|
|
3425
3513
|
};
|
|
@@ -3481,7 +3569,14 @@ var buildMarkdownSummary = (data) => {
|
|
|
3481
3569
|
cost?.amount,
|
|
3482
3570
|
cost?.currency
|
|
3483
3571
|
);
|
|
3484
|
-
const
|
|
3572
|
+
const resourceCostRows = compactCostRowsForChart(
|
|
3573
|
+
costServiceRows(data.gate?.cost?.topResources, cost?.currency),
|
|
3574
|
+
cost?.amount,
|
|
3575
|
+
cost?.currency,
|
|
3576
|
+
{ maxRows: 5, remainderLabel: "Unallocated" }
|
|
3577
|
+
);
|
|
3578
|
+
const positiveResourceCosts = resourceCostRows.filter((resource) => resource.amount > 0);
|
|
3579
|
+
const openLinks = openInCloudEvalLines(data.links);
|
|
3485
3580
|
const architectureLines = architectureSignalLines({
|
|
3486
3581
|
architecture,
|
|
3487
3582
|
costServices,
|
|
@@ -3505,6 +3600,9 @@ var buildMarkdownSummary = (data) => {
|
|
|
3505
3600
|
`- **Ref**: \`${ref}\``,
|
|
3506
3601
|
`- **Commit**: \`${commit}\``
|
|
3507
3602
|
];
|
|
3603
|
+
if (openLinks.length) {
|
|
3604
|
+
lines.push("", "#### Open in CloudEval", "", ...openLinks);
|
|
3605
|
+
}
|
|
3508
3606
|
if (data.aiSummary?.markdown) {
|
|
3509
3607
|
lines.push("", "#### AI summary", "", data.aiSummary.markdown);
|
|
3510
3608
|
}
|
|
@@ -3528,11 +3626,29 @@ var buildMarkdownSummary = (data) => {
|
|
|
3528
3626
|
}
|
|
3529
3627
|
if (cost?.amount !== void 0 || cost?.threshold !== void 0) {
|
|
3530
3628
|
const costLines = [];
|
|
3531
|
-
|
|
3629
|
+
const impactLines = monthlyCostImpactLines(
|
|
3630
|
+
cost?.amount,
|
|
3631
|
+
data.gate?.cost?.estimatedSavings?.amount,
|
|
3632
|
+
cost?.currency ?? data.gate?.cost?.estimatedSavings?.currency
|
|
3633
|
+
);
|
|
3634
|
+
if (impactLines.length) {
|
|
3635
|
+
costLines.push(...impactLines);
|
|
3636
|
+
} else if (data.gate?.cost?.estimatedSavings?.amount !== void 0) {
|
|
3532
3637
|
costLines.push(
|
|
3533
3638
|
`- Estimated savings: **${formatMonthlyMoney(data.gate.cost.estimatedSavings.amount, data.gate.cost.estimatedSavings.currency)}**`
|
|
3534
3639
|
);
|
|
3535
3640
|
}
|
|
3641
|
+
if (positiveResourceCosts.length) {
|
|
3642
|
+
costLines.push(
|
|
3643
|
+
"",
|
|
3644
|
+
"```mermaid",
|
|
3645
|
+
"pie title Monthly cost by resource",
|
|
3646
|
+
...positiveResourceCosts.map(
|
|
3647
|
+
(resource) => ` "${mermaidLabel(resource.name)}" : ${trimNumber(resource.amount, 3)}`
|
|
3648
|
+
),
|
|
3649
|
+
"```"
|
|
3650
|
+
);
|
|
3651
|
+
}
|
|
3536
3652
|
if (costServices.length) {
|
|
3537
3653
|
costLines.push(
|
|
3538
3654
|
"",
|
|
@@ -3543,17 +3659,6 @@ var buildMarkdownSummary = (data) => {
|
|
|
3543
3659
|
)
|
|
3544
3660
|
);
|
|
3545
3661
|
}
|
|
3546
|
-
if (positiveCostServices.length) {
|
|
3547
|
-
costLines.push(
|
|
3548
|
-
"",
|
|
3549
|
-
"```mermaid",
|
|
3550
|
-
"pie title Monthly cost by service",
|
|
3551
|
-
...positiveCostServices.map(
|
|
3552
|
-
(service) => ` "${mermaidLabel(service.name)}" : ${trimNumber(service.amount, 3)}`
|
|
3553
|
-
),
|
|
3554
|
-
"```"
|
|
3555
|
-
);
|
|
3556
|
-
}
|
|
3557
3662
|
if (costLines.length) {
|
|
3558
3663
|
lines.push(
|
|
3559
3664
|
"",
|
|
@@ -3673,18 +3778,58 @@ var registerReviewCommand = (program2, deps) => {
|
|
|
3673
3778
|
}),
|
|
3674
3779
|
readConfigText(cwd, options)
|
|
3675
3780
|
]);
|
|
3781
|
+
const frontendBaseUrl = resolveFrontendBaseUrl({ apiBaseUrl: context.baseUrl });
|
|
3782
|
+
const projectUrl = buildFrontendUrl({
|
|
3783
|
+
baseUrl: frontendBaseUrl,
|
|
3784
|
+
target: "project",
|
|
3785
|
+
projectId,
|
|
3786
|
+
view: "preview",
|
|
3787
|
+
layout: "architecture"
|
|
3788
|
+
});
|
|
3789
|
+
const workflowRunUrl = githubWorkflowRunUrl();
|
|
3676
3790
|
const data = {
|
|
3677
3791
|
projectId,
|
|
3678
3792
|
project: {
|
|
3679
3793
|
id: projectId,
|
|
3680
3794
|
name: String(project?.name ?? projectId),
|
|
3681
|
-
url:
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3795
|
+
url: projectUrl
|
|
3796
|
+
},
|
|
3797
|
+
links: {
|
|
3798
|
+
project: projectUrl,
|
|
3799
|
+
reports: {
|
|
3800
|
+
architecture: buildFrontendUrl({
|
|
3801
|
+
baseUrl: frontendBaseUrl,
|
|
3802
|
+
target: "reports",
|
|
3803
|
+
projectId,
|
|
3804
|
+
tab: "architecture",
|
|
3805
|
+
reportType: "architecture"
|
|
3806
|
+
}),
|
|
3807
|
+
cost: buildFrontendUrl({
|
|
3808
|
+
baseUrl: frontendBaseUrl,
|
|
3809
|
+
target: "reports",
|
|
3810
|
+
projectId,
|
|
3811
|
+
tab: "cost",
|
|
3812
|
+
reportType: "cost"
|
|
3813
|
+
}),
|
|
3814
|
+
validation: buildFrontendUrl({
|
|
3815
|
+
baseUrl: frontendBaseUrl,
|
|
3816
|
+
target: "reports",
|
|
3817
|
+
projectId,
|
|
3818
|
+
tab: "validation",
|
|
3819
|
+
reportType: "unit_tests"
|
|
3820
|
+
})
|
|
3821
|
+
},
|
|
3822
|
+
downloads: {
|
|
3823
|
+
pdf: buildFrontendUrl({
|
|
3824
|
+
baseUrl: frontendBaseUrl,
|
|
3825
|
+
target: "reports",
|
|
3826
|
+
projectId,
|
|
3827
|
+
downloadPdf: true,
|
|
3828
|
+
pdfVerbosity: "full"
|
|
3829
|
+
}),
|
|
3830
|
+
...workflowRunUrl ? { reviewArtifacts: workflowRunUrl } : {}
|
|
3831
|
+
},
|
|
3832
|
+
...workflowRunUrl ? { workflowRun: workflowRunUrl } : {}
|
|
3688
3833
|
},
|
|
3689
3834
|
repo,
|
|
3690
3835
|
ref,
|
|
@@ -15626,7 +15771,7 @@ program.command("tui").description("Open the CloudEval Terminal UI").option(
|
|
|
15626
15771
|
const { assertSecureBaseUrl } = await import("./dist-PEYJDO7A.js");
|
|
15627
15772
|
const [{ render }, { App }] = await Promise.all([
|
|
15628
15773
|
import("ink"),
|
|
15629
|
-
import("./App-
|
|
15774
|
+
import("./App-3RDW53BW.js")
|
|
15630
15775
|
]);
|
|
15631
15776
|
const baseUrl = await resolveBaseUrl(options, command);
|
|
15632
15777
|
assertSecureBaseUrl(baseUrl);
|
|
@@ -15684,7 +15829,7 @@ program.command("chat").description("Start an interactive chat session").option(
|
|
|
15684
15829
|
const { assertSecureBaseUrl } = await import("./dist-PEYJDO7A.js");
|
|
15685
15830
|
const [{ render }, { App }] = await Promise.all([
|
|
15686
15831
|
import("ink"),
|
|
15687
|
-
import("./App-
|
|
15832
|
+
import("./App-3RDW53BW.js")
|
|
15688
15833
|
]);
|
|
15689
15834
|
const baseUrl = await resolveBaseUrl(options, command);
|
|
15690
15835
|
assertSecureBaseUrl(baseUrl);
|
|
@@ -16438,7 +16583,7 @@ Error: ${errorMsg}
|
|
|
16438
16583
|
program.command("banner").description("Preview the startup banner and terminal capabilities").action(async () => {
|
|
16439
16584
|
const { render } = await import("ink");
|
|
16440
16585
|
const BannerPreview = React.lazy(async () => ({
|
|
16441
|
-
default: (await import("./Banner-
|
|
16586
|
+
default: (await import("./Banner-HGG5NHXF.js")).Banner
|
|
16442
16587
|
}));
|
|
16443
16588
|
render(
|
|
16444
16589
|
/* @__PURE__ */ jsx(React.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(BannerPreview, { disable: false }) })
|
package/package.json
CHANGED
package/sbom.spdx.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
{
|
|
15
15
|
"SPDXID": "SPDXRef-Package-CloudEval-CLI",
|
|
16
16
|
"name": "CloudEval CLI",
|
|
17
|
-
"versionInfo": "0.
|
|
17
|
+
"versionInfo": "0.28.0",
|
|
18
18
|
"downloadLocation": "https://github.com/ganakailabs/cloudeval-cli",
|
|
19
19
|
"filesAnalyzed": false,
|
|
20
20
|
"licenseConcluded": "LicenseRef-CloudEval-CLI",
|
|
@@ -2354,9 +2354,9 @@
|
|
|
2354
2354
|
"summary": "The semantic version parser used by npm."
|
|
2355
2355
|
},
|
|
2356
2356
|
{
|
|
2357
|
-
"SPDXID": "SPDXRef-Package-shell-quote-1.8.
|
|
2357
|
+
"SPDXID": "SPDXRef-Package-shell-quote-1.8.4",
|
|
2358
2358
|
"name": "shell-quote",
|
|
2359
|
-
"versionInfo": "1.8.
|
|
2359
|
+
"versionInfo": "1.8.4",
|
|
2360
2360
|
"downloadLocation": "https://github.com/ljharb/shell-quote",
|
|
2361
2361
|
"filesAnalyzed": false,
|
|
2362
2362
|
"licenseConcluded": "MIT",
|
|
@@ -3847,7 +3847,7 @@
|
|
|
3847
3847
|
{
|
|
3848
3848
|
"spdxElementId": "SPDXRef-Package-CloudEval-CLI",
|
|
3849
3849
|
"relationshipType": "DEPENDS_ON",
|
|
3850
|
-
"relatedSpdxElement": "SPDXRef-Package-shell-quote-1.8.
|
|
3850
|
+
"relatedSpdxElement": "SPDXRef-Package-shell-quote-1.8.4"
|
|
3851
3851
|
},
|
|
3852
3852
|
{
|
|
3853
3853
|
"spdxElementId": "SPDXRef-Package-CloudEval-CLI",
|