7
7
import * as path from 'path' ;
8
8
import { SfdxCommand } from '@salesforce/command' ;
9
9
import { ComponentSet } from '@salesforce/source-deploy-retrieve' ;
10
- import { fs , SfdxError } from '@salesforce/core' ;
10
+ import { fs , SfdxError , Logger } from '@salesforce/core' ;
11
11
import { ComponentLike } from '@salesforce/source-deploy-retrieve/lib/src/common' ;
12
12
13
13
export type FlagOptions = {
14
14
packagenames ?: string [ ] ;
15
15
sourcepath : string [ ] ;
16
16
manifest : string ;
17
17
metadata : string [ ] ;
18
+ apiversion ?: string ;
18
19
} ;
19
20
20
21
export abstract class SourceCommand extends SfdxCommand {
21
- public static MINIMUM_SRC_WAIT_MINUTES = 1 ;
22
22
public static DEFAULT_SRC_WAIT_MINUTES = 33 ;
23
23
/**
24
24
* will create one ComponentSet to be deployed/retrieved
@@ -27,11 +27,13 @@ export abstract class SourceCommand extends SfdxCommand {
27
27
* @param options: FlagOptions where to create ComponentSets from
28
28
*/
29
29
protected async createComponentSet ( options : FlagOptions ) : Promise < ComponentSet > {
30
+ const logger = Logger . childFromRoot ( this . constructor . name ) ;
30
31
const setAggregator : ComponentLike [ ] = [ ] ;
31
32
32
33
// go through options to create a list of ComponentSets
33
34
// we'll then combine all of those to deploy/retrieve
34
35
if ( options . sourcepath ) {
36
+ logger . debug ( `Building ComponentSet from sourcepath: ${ options . sourcepath . toString ( ) } ` ) ;
35
37
options . sourcepath . forEach ( ( filepath ) => {
36
38
if ( fs . fileExistsSync ( filepath ) ) {
37
39
setAggregator . push ( ...ComponentSet . fromSource ( path . resolve ( filepath ) ) ) ;
@@ -41,38 +43,69 @@ export abstract class SourceCommand extends SfdxCommand {
41
43
} ) ;
42
44
}
43
45
46
+ // Return empty ComponentSet and use packageNames in the library via `.retrieve` options
44
47
if ( options . packagenames ) {
45
- // return ComponentSet and use packageNames in the library via `.retrieve` options
48
+ logger . debug ( `Building ComponentSet for packagenames: ${ options . packagenames . toString ( ) } ` ) ;
46
49
setAggregator . push ( ...new ComponentSet ( [ ] ) ) ;
47
50
}
48
51
52
+ // Resolve manifest with source in package directories.
49
53
if ( options . manifest ) {
50
- setAggregator . push (
51
- ...( await ComponentSet . fromManifestFile ( options . manifest , {
52
- // to create a link to the actual source component we need to have it resolve through all packages
53
- // to find the matching source metadata
54
- // this allows us to deploy after
55
- resolve : process . cwd ( ) ,
56
- } ) )
57
- ) ;
54
+ logger . debug ( `Building ComponentSet from manifest: ${ options . manifest } ` ) ;
55
+ const packageDirs = this . project . getUniquePackageDirectories ( ) . map ( ( pDir ) => pDir . fullPath ) ;
56
+ for ( const packageDir of packageDirs ) {
57
+ logger . debug ( `Searching in packageDir: ${ packageDir } for matching metadata` ) ;
58
+ const compSet = await ComponentSet . fromManifestFile ( options . manifest , { resolve : packageDir } ) ;
59
+ setAggregator . push ( ...compSet ) ;
60
+ }
58
61
}
59
62
63
+ // Resolve metadata entries with source in package directories.
60
64
if ( options . metadata ) {
65
+ logger . debug ( `Building ComponentSet from metadata: ${ options . metadata . toString ( ) } ` ) ;
66
+
67
+ // Build a Set of metadata entries
68
+ const filter = new ComponentSet ( ) ;
61
69
options . metadata . forEach ( ( entry ) => {
62
70
const splitEntry = entry . split ( ':' ) ;
63
- const metadata : ComponentLike = {
71
+ filter . add ( {
64
72
type : splitEntry [ 0 ] ,
65
- // either -m ApexClass or -m ApexClass:MyApexClass
66
73
fullName : splitEntry . length === 1 ? '*' : splitEntry [ 1 ] ,
67
- } ;
68
- const cs = new ComponentSet ( [ metadata ] ) ;
69
- // we need to search the entire project for the matching metadata component
70
- // no better way than to have it search than process.cwd()
71
- cs . resolveSourceComponents ( process . cwd ( ) , { filter : cs } ) ;
72
- setAggregator . push ( ...cs ) ;
74
+ } ) ;
73
75
} ) ;
76
+
77
+ // Search the packages directories for matching metadata
78
+ const packageDirs = this . project . getUniquePackageDirectories ( ) . map ( ( pDir ) => pDir . fullPath ) ;
79
+ logger . debug ( `Searching for matching metadata in packageDirs: ${ packageDirs . toString ( ) } ` ) ;
80
+ setAggregator . push ( ...ComponentSet . fromSource ( { inclusiveFilter : filter , fsPaths : packageDirs } ) ) ;
81
+ }
82
+
83
+ const componentSet = new ComponentSet ( setAggregator ) ;
84
+
85
+ // This is only for debug output of matched files based on the command flags.
86
+ // It will log up to 20 file matches.
87
+ // TODO: add logger.debugEnabled
88
+ if ( componentSet . size ) {
89
+ logger . debug ( `Matching metadata files (${ componentSet . size } ):` ) ;
90
+ const components = componentSet . getSourceComponents ( ) . toArray ( ) ;
91
+ for ( let i = 0 ; i < componentSet . size ; i ++ ) {
92
+ if ( components [ i ] ?. content ) {
93
+ logger . debug ( components [ i ] . content ) ;
94
+ } else if ( components [ i ] ?. xml ) {
95
+ logger . debug ( components [ i ] . xml ) ;
96
+ }
97
+
98
+ if ( i > 18 ) {
99
+ logger . debug ( `(showing 20 of ${ componentSet . size } matches)` ) ;
100
+ break ;
101
+ }
102
+ }
103
+ }
104
+
105
+ if ( options . apiversion ) {
106
+ componentSet . apiVersion = options . apiversion ;
74
107
}
75
108
76
- return new ComponentSet ( setAggregator ) ;
109
+ return componentSet ;
77
110
}
78
111
}
0 commit comments