Skip to content

Commit 721b2d0

Browse files
feat: non tested implementation of package bundle version report
1 parent 0535646 commit 721b2d0

4 files changed

Lines changed: 333 additions & 0 deletions

File tree

command-snapshot.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@
124124
"flags": ["api-version", "flags-dir", "json", "loglevel", "target-dev-hub", "verbose"],
125125
"plugin": "@salesforce/plugin-packaging"
126126
},
127+
{
128+
"alias": [],
129+
"command": "package:bundle:version:report",
130+
"flagAliases": ["apiversion", "target-hub-org", "targetdevhubusername"],
131+
"flagChars": ["p", "v"],
132+
"flags": ["api-version", "bundle-version", "flags-dir", "json", "loglevel", "target-dev-hub", "verbose"],
133+
"plugin": "@salesforce/plugin-packaging"
134+
},
127135
{
128136
"alias": ["force:package:convert"],
129137
"command": "package:convert",

messages/bundle_version_report.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# summary
2+
3+
Retrieve details about a package bundle version in the Dev Hub org.
4+
5+
# description
6+
7+
Use this command to retrieve detailed information about a package bundle version, including its bundle information, version details, and ancestor information if available.
8+
9+
# examples
10+
11+
- Retrieve details about the package bundle version with the specified ID from your default Dev Hub org:
12+
13+
<%= config.bin %> <%= command.id %> --bundle-version 0Ho0x0000000000000
14+
15+
- Retrieve details about the package bundle version with verbose output:
16+
17+
<%= config.bin %> <%= command.id %> --bundle-version 0Ho0x0000000000000 --verbose
18+
19+
# flags.bundleVersion.summary
20+
21+
ID of the package bundle version to retrieve details for.
22+
23+
# flags.verbose.summary
24+
25+
Display extended package bundle version details.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$ref": "#/definitions/BundleSObjects.BundleVersion",
4+
"definitions": {
5+
"BundleSObjects.BundleVersion": {
6+
"type": "object",
7+
"properties": {
8+
"Id": {
9+
"type": "string"
10+
},
11+
"PackageBundle": {
12+
"$ref": "#/definitions/BundleSObjects.Bundle"
13+
},
14+
"VersionName": {
15+
"type": "string"
16+
},
17+
"MajorVersion": {
18+
"type": "string"
19+
},
20+
"MinorVersion": {
21+
"type": "string"
22+
},
23+
"Ancestor": {
24+
"anyOf": [
25+
{
26+
"$ref": "#/definitions/BundleSObjects.BundleVersion"
27+
},
28+
{
29+
"type": "null"
30+
}
31+
]
32+
},
33+
"IsReleased": {
34+
"type": "boolean"
35+
},
36+
"CreatedDate": {
37+
"type": "string"
38+
},
39+
"CreatedById": {
40+
"type": "string"
41+
},
42+
"LastModifiedDate": {
43+
"type": "string"
44+
},
45+
"LastModifiedById": {
46+
"type": "string"
47+
}
48+
},
49+
"required": [
50+
"Id",
51+
"PackageBundle",
52+
"VersionName",
53+
"MajorVersion",
54+
"MinorVersion",
55+
"IsReleased",
56+
"CreatedDate",
57+
"CreatedById",
58+
"LastModifiedDate",
59+
"LastModifiedById"
60+
],
61+
"additionalProperties": false
62+
},
63+
"BundleSObjects.Bundle": {
64+
"type": "object",
65+
"properties": {
66+
"BundleName": {
67+
"type": "string"
68+
},
69+
"Description": {
70+
"type": "string"
71+
},
72+
"Id": {
73+
"type": "string"
74+
},
75+
"IsDeleted": {
76+
"type": "boolean"
77+
},
78+
"CreatedDate": {
79+
"type": "string"
80+
},
81+
"CreatedById": {
82+
"type": "string"
83+
},
84+
"LastModifiedDate": {
85+
"type": "string"
86+
},
87+
"LastModifiedById": {
88+
"type": "string"
89+
},
90+
"SystemModstamp": {
91+
"type": "string"
92+
}
93+
},
94+
"required": [
95+
"BundleName",
96+
"Id",
97+
"IsDeleted",
98+
"CreatedDate",
99+
"CreatedById",
100+
"LastModifiedDate",
101+
"LastModifiedById",
102+
"SystemModstamp"
103+
],
104+
"additionalProperties": false
105+
}
106+
}
107+
}
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
* Copyright (c) 2022, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
import { Flags, loglevel, orgApiVersionFlagWithDeprecations, SfCommand } from '@salesforce/sf-plugins-core';
9+
import { Messages } from '@salesforce/core/messages';
10+
import { PackageBundleVersion, BundleSObjects, PackagingSObjects } from '@salesforce/packaging';
11+
import chalk from 'chalk';
12+
import { requiredHubFlag } from '../../../../utils/hubFlag.js';
13+
14+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
15+
const messages = Messages.loadMessages('@salesforce/plugin-packaging', 'bundle_version_report');
16+
17+
export class PackageBundleVersionReportCommand extends SfCommand<BundleSObjects.BundleVersion> {
18+
public static readonly summary = messages.getMessage('summary');
19+
public static readonly description = messages.getMessage('description');
20+
public static readonly examples = messages.getMessages('examples');
21+
public static readonly flags = {
22+
loglevel,
23+
'target-dev-hub': requiredHubFlag,
24+
'api-version': orgApiVersionFlagWithDeprecations,
25+
'bundle-version': Flags.string({
26+
char: 'p',
27+
summary: messages.getMessage('flags.bundleVersion.summary'),
28+
required: true,
29+
}),
30+
verbose: Flags.boolean({
31+
summary: messages.getMessage('flags.verbose.summary'),
32+
}),
33+
};
34+
35+
public async run(): Promise<BundleSObjects.BundleVersion> {
36+
const { flags } = await this.parse(PackageBundleVersionReportCommand);
37+
const connection = flags['target-dev-hub'].getConnection(flags['api-version']);
38+
const results = await PackageBundleVersion.report(connection, flags['bundle-version']);
39+
const componentPackages = await PackageBundleVersion.componentPackages(connection, flags['bundle-version']);
40+
41+
if (!results) {
42+
throw new Error(`No bundle version found with ID: ${flags['bundle-version']}`);
43+
}
44+
45+
const massagedResults = this.massageResultsForDisplay(results);
46+
this.display(massagedResults, flags.verbose);
47+
this.displayComponentPackages(componentPackages);
48+
return massagedResults;
49+
}
50+
51+
private display(record: BundleSObjects.BundleVersion, verbose: boolean): void {
52+
if (this.jsonEnabled()) {
53+
return;
54+
}
55+
56+
// transform the results into a table
57+
const displayRecords = [
58+
{
59+
key: 'Bundle Name',
60+
value: record.PackageBundle.BundleName,
61+
},
62+
{
63+
key: 'Bundle ID',
64+
value: record.PackageBundle.Id,
65+
},
66+
{
67+
key: 'Version ID',
68+
value: record.Id,
69+
},
70+
{
71+
key: 'Version Name',
72+
value: record.VersionName,
73+
},
74+
{
75+
key: 'Major Version',
76+
value: record.MajorVersion,
77+
},
78+
{
79+
key: 'Minor Version',
80+
value: record.MinorVersion,
81+
},
82+
{
83+
key: 'Description',
84+
value: record.PackageBundle.Description ?? 'N/A',
85+
},
86+
{
87+
key: 'Released',
88+
value: record.IsReleased ? 'Yes' : 'No',
89+
},
90+
{
91+
key: 'Created Date',
92+
value: record.CreatedDate,
93+
},
94+
{
95+
key: 'Created By',
96+
value: record.CreatedById,
97+
},
98+
{
99+
key: 'Last Modified Date',
100+
value: record.LastModifiedDate,
101+
},
102+
{
103+
key: 'Last Modified By',
104+
value: record.LastModifiedById,
105+
},
106+
];
107+
108+
// Add ancestor information if available
109+
if (record.Ancestor) {
110+
displayRecords.push(
111+
{
112+
key: 'Ancestor ID',
113+
value: record.Ancestor.Id,
114+
},
115+
{
116+
key: 'Ancestor Version',
117+
value: `${record.Ancestor.MajorVersion}.${record.Ancestor.MinorVersion}`,
118+
},
119+
{
120+
key: 'Ancestor Bundle Name',
121+
value: record.Ancestor.PackageBundle.BundleName,
122+
}
123+
);
124+
} else {
125+
displayRecords.push({
126+
key: 'Ancestor',
127+
value: 'N/A',
128+
});
129+
}
130+
131+
// Add verbose information if requested
132+
if (verbose) {
133+
displayRecords.push(
134+
{
135+
key: 'Bundle Deleted',
136+
value: record.PackageBundle.IsDeleted ? 'Yes' : 'No',
137+
},
138+
{
139+
key: 'Bundle System Modstamp',
140+
value: record.PackageBundle.SystemModstamp,
141+
}
142+
);
143+
}
144+
145+
this.filterVerboseRecords(record, displayRecords, verbose);
146+
147+
this.table({ data: displayRecords, title: chalk.blue('Package Bundle Version') });
148+
}
149+
150+
// eslint-disable-next-line class-methods-use-this
151+
private filterVerboseRecords(
152+
bundleRecord: BundleSObjects.BundleVersion,
153+
displayRecords: Array<Record<string, unknown>>,
154+
verbose: boolean
155+
): void {
156+
if (!verbose) {
157+
// Remove verbose fields for non-verbose output
158+
const verboseKeys = ['Bundle Deleted', 'Bundle System Modstamp'];
159+
displayRecords.splice(
160+
0,
161+
displayRecords.length,
162+
...displayRecords.filter((displayRecord) => !verboseKeys.includes(displayRecord.key as string))
163+
);
164+
}
165+
}
166+
167+
// eslint-disable-next-line class-methods-use-this
168+
private massageResultsForDisplay(results: BundleSObjects.BundleVersion): BundleSObjects.BundleVersion {
169+
// For bundle versions, the data is already in the correct format
170+
// Just return the results as they are
171+
return results;
172+
}
173+
174+
private displayComponentPackages(componentPackages: PackagingSObjects.SubscriberPackageVersion[]): void {
175+
if (this.jsonEnabled()) {
176+
return;
177+
}
178+
179+
if (componentPackages.length === 0) {
180+
this.log(chalk.yellow('No component packages found for this bundle version.'));
181+
return;
182+
}
183+
184+
const displayRecords = componentPackages.map((component) => ({
185+
'Package Name': component.Name,
186+
'Package Version Number': `${component.MajorVersion}.${component.MinorVersion}.${component.PatchVersion}.${component.BuildNumber}`,
187+
'Package Version Id': component.Id,
188+
'Package Subscriber Id': component.SubscriberPackageId,
189+
}));
190+
191+
this.table({ data: displayRecords, title: chalk.blue('Component Packages') });
192+
}
193+
}

0 commit comments

Comments
 (0)