88import { Command , Flags } from '@oclif/core' ;
99import { fs , Messages } from '@salesforce/core' ;
1010import { Env } from '@salesforce/kit' ;
11- import { Deployable , Deployer , generateTableChoices , Prompter } from '@salesforce/plugin-project-utils' ;
11+ import {
12+ Deployable ,
13+ Deployer ,
14+ generateTableChoices ,
15+ ProjectDeployOptions ,
16+ Prompter ,
17+ } from '@salesforce/plugin-project-utils' ;
1218
1319Messages . importMessagesDirectory ( __dirname ) ;
1420
1521const messages = Messages . loadMessages ( '@salesforce/plugin-project' , 'project.deploy' ) ;
1622
23+ export const DEPLOY_OPTIONS_FILE = 'project-deploy-options.json' ;
24+
1725export default class ProjectDeploy extends Command {
1826 public static summary = messages . getMessage ( 'summary' ) ;
1927 public static description = messages . getMessage ( 'description' ) ;
@@ -31,23 +39,41 @@ export default class ProjectDeploy extends Command {
3139 const { flags } = await this . parse ( ProjectDeploy ) ;
3240
3341 flags . interactive = await this . isInteractive ( flags . interactive ) ;
42+ const options = await this . readOptions ( ) ;
3443
3544 this . log ( 'Analyzing project' ) ;
3645
37- let deployers = ( await this . config . runHook ( 'project:findDeployers' , { } ) ) as Deployer [ ] ;
46+ if ( ! flags . interactive ) {
47+ this . log ( `Using options found in ${ DEPLOY_OPTIONS_FILE } ` ) ;
48+ }
49+
50+ let deployers = ( await this . config . runHook ( 'project:findDeployers' , options ) ) as Deployer [ ] ;
3851 deployers = deployers . reduce ( ( x , y ) => x . concat ( y ) , [ ] as Deployer [ ] ) ;
3952
4053 if ( deployers . length === 0 ) {
4154 this . log ( 'Found nothing in the project to deploy' ) ;
4255 } else {
43- deployers = await this . selectDeployers ( deployers ) ;
56+ if ( flags . interactive ) {
57+ deployers = await this . selectDeployers ( deployers ) ;
58+ }
4459
4560 if ( deployers . length === 0 ) {
4661 this . log ( 'Nothing was selected to deploy.' ) ;
4762 }
4863
64+ const deployOptions : ProjectDeployOptions = { } ;
65+ for ( const deployer of deployers ) {
66+ const opts = options [ deployer . getName ( ) ] ?? { } ;
67+ deployOptions [ deployer . getName ( ) ] = await deployer . setup ( flags , opts ) ;
68+ }
69+
70+ if ( flags . interactive && ( await this . askToSave ( ) ) ) {
71+ await fs . writeJson ( DEPLOY_OPTIONS_FILE , deployOptions , { space : 2 } ) ;
72+ this . log ( ) ;
73+ this . log ( `Your deploy options have been saved to ${ DEPLOY_OPTIONS_FILE } ` ) ;
74+ }
75+
4976 for ( const deployer of deployers ) {
50- await deployer . setup ( flags ) ;
5177 await deployer . deploy ( ) ;
5278 }
5379 }
@@ -59,10 +85,28 @@ export default class ProjectDeploy extends Command {
5985 */
6086 public async isInteractive ( interactive : boolean ) : Promise < boolean > {
6187 if ( interactive ) return true ;
62- const deployFileExists = await fs . fileExists ( 'project-deploy-options.json' ) ;
88+ const deployFileExists = await fs . fileExists ( DEPLOY_OPTIONS_FILE ) ;
6389 return deployFileExists ? false : true ;
6490 }
6591
92+ public async readOptions ( ) : Promise < ProjectDeployOptions > {
93+ if ( await fs . fileExists ( DEPLOY_OPTIONS_FILE ) ) {
94+ return ( await fs . readJson ( DEPLOY_OPTIONS_FILE ) ) as ProjectDeployOptions ;
95+ } else {
96+ return { } ;
97+ }
98+ }
99+
100+ public async askToSave ( ) : Promise < boolean > {
101+ const prompter = new Prompter ( ) ;
102+ const { save } = await prompter . prompt < { save : boolean } > ( {
103+ name : 'save' ,
104+ message : 'Would you like to save these deploy options for future runs?' ,
105+ type : 'confirm' ,
106+ } ) ;
107+ return save ;
108+ }
109+
66110 public async selectDeployers ( deployers : Deployer [ ] ) : Promise < Deployer [ ] > {
67111 const deployables : Deployable [ ] = deployers . reduce ( ( x , y ) => x . concat ( y . deployables ) , [ ] as Deployable [ ] ) ;
68112 const columns = { name : 'APP OR PACKAGE' , type : 'TYPE' , path : 'PATH' } ;
0 commit comments