@@ -23,22 +23,27 @@ import (
2323 "github.com/slackapi/slack-cli/internal/iostreams"
2424 "github.com/slackapi/slack-cli/internal/prompts"
2525 "github.com/slackapi/slack-cli/internal/shared"
26+ "github.com/slackapi/slack-cli/internal/slackdotenv"
2627 "github.com/slackapi/slack-cli/internal/slacktrace"
2728 "github.com/slackapi/slack-cli/internal/style"
29+ "github.com/spf13/afero"
2830 "github.com/spf13/cobra"
2931)
3032
3133func NewEnvAddCommand (clients * shared.ClientFactory ) * cobra.Command {
3234 cmd := & cobra.Command {
33- Use : "add <name> < value> [flags]" ,
34- Short : "Add an environment variable to the app " ,
35+ Use : "add <name> [ value] [flags]" ,
36+ Short : "Add an environment variable to the project " ,
3537 Long : strings .Join ([]string {
36- "Add an environment variable to an app deployed to Slack managed infrastructure ." ,
38+ "Add an environment variable to the project ." ,
3739 "" ,
3840 "If a name or value is not provided, you will be prompted to provide these." ,
3941 "" ,
40- "This command is supported for apps deployed to Slack managed infrastructure but" ,
41- "other apps can attempt to run the command with the --force flag." ,
42+ "Commands that run in the context of a project source environment variables from" ,
43+ `the ".env" file. This includes the "run" command.` ,
44+ "" ,
45+ `The "deploy" command gathers environment variables from the ".env" file as well` ,
46+ "unless the app is using ROSI features." ,
4247 }, "\n " ),
4348 Example : style .ExampleCommandsf ([]style.ExampleCommand {
4449 {
@@ -69,85 +74,97 @@ func NewEnvAddCommand(clients *shared.ClientFactory) *cobra.Command {
6974 return cmd
7075}
7176
72- // preRunEnvAddCommandFunc determines if the command is supported for a project
77+ // preRunEnvAddCommandFunc determines if the command is run in a valid project
7378// and configures flags
7479func preRunEnvAddCommandFunc (ctx context.Context , clients * shared.ClientFactory , cmd * cobra.Command ) error {
7580 clients .Config .SetFlags (cmd )
76- err := cmdutil .IsValidProjectDirectory (clients )
77- if err != nil {
78- return err
79- }
80- if clients .Config .ForceFlag {
81- return nil
82- }
83- return cmdutil .IsSlackHostedProject (ctx , clients )
81+ return cmdutil .IsValidProjectDirectory (clients )
8482}
8583
8684// runEnvAddCommandFunc sets an app environment variable to given values
8785func runEnvAddCommandFunc (clients * shared.ClientFactory , cmd * cobra.Command , args []string ) error {
8886 ctx := cmd .Context ()
8987
90- // Get the workspace from the flag or prompt
91- selection , err := appSelectPromptFunc (ctx , clients , prompts .ShowHostedOnly , prompts .ShowInstalledAppsOnly )
92- if err != nil {
93- return err
88+ // Hosted apps require selecting an app before gathering variable inputs.
89+ hosted := isHostedRuntime (ctx , clients )
90+ var selection prompts.SelectedApp
91+ if hosted {
92+ s , err := appSelectPromptFunc (ctx , clients , prompts .ShowAllEnvironments , prompts .ShowInstalledAppsOnly )
93+ if err != nil {
94+ return err
95+ }
96+ selection = s
9497 }
9598
9699 // Get the variable name from the args or prompt
97- var variableName string
100+ variableName := ""
98101 if len (args ) < 1 {
99- variableName , err = clients .IO .InputPrompt (ctx , "Variable name" , iostreams.InputPromptConfig {
102+ name , err : = clients .IO .InputPrompt (ctx , "Variable name" , iostreams.InputPromptConfig {
100103 Required : false ,
101104 })
102105 if err != nil {
103106 return err
104107 }
108+ variableName = name
105109 } else {
106110 variableName = args [0 ]
107-
108- // Display the variable name before getting the variable value
109- if len (args ) < 2 && ! clients .Config .Flags .Lookup ("value" ).Changed {
110- mimickedInput := iostreams .MimicInputPrompt ("Variable name" , variableName )
111- clients .IO .PrintInfo (ctx , false , "%s" , mimickedInput )
112- }
113111 }
114112
115113 // Get the variable value from the args or prompt
116- var variableValue string
114+ variableValue := ""
117115 if len (args ) < 2 {
118116 response , err := clients .IO .PasswordPrompt (ctx , "Variable value" , iostreams.PasswordPromptConfig {
119117 Flag : clients .Config .Flags .Lookup ("value" ),
120118 })
121119 if err != nil {
122120 return err
123- } else {
124- variableValue = response .Value
125121 }
122+ variableValue = response .Value
126123 } else {
127124 variableValue = args [1 ]
128125 }
129126
130- err = clients .API ().AddVariable (
131- ctx ,
132- selection .Auth .Token ,
133- selection .App .AppID ,
134- variableName ,
135- variableValue ,
136- )
137- if err != nil {
138- return err
127+ // Add the environment variable using either the Slack API method or the
128+ // project ".env" file depending on the app hosting.
129+ if hosted && ! selection .App .IsDev {
130+ err := clients .API ().AddVariable (
131+ ctx ,
132+ selection .Auth .Token ,
133+ selection .App .AppID ,
134+ variableName ,
135+ variableValue ,
136+ )
137+ if err != nil {
138+ return err
139+ }
140+ clients .IO .PrintTrace (ctx , slacktrace .EnvAddSuccess )
141+ clients .IO .PrintInfo (ctx , false , "\n %s" , style .Sectionf (style.TextSection {
142+ Emoji : "evergreen_tree" ,
143+ Text : "App Environment" ,
144+ Secondary : []string {
145+ fmt .Sprintf ("Successfully added \" %s\" as an app environment variable" , variableName ),
146+ },
147+ }))
148+ } else {
149+ exists , err := afero .Exists (clients .Fs , ".env" )
150+ if err != nil {
151+ return err
152+ }
153+ err = slackdotenv .Set (clients .Fs , variableName , variableValue )
154+ if err != nil {
155+ return err
156+ }
157+ clients .IO .PrintTrace (ctx , slacktrace .EnvAddSuccess )
158+ var details []string
159+ if ! exists {
160+ details = append (details , "Created a project .env file that shouldn't be added to version control" )
161+ }
162+ details = append (details , fmt .Sprintf ("Successfully added \" %s\" as a project environment variable" , variableName ))
163+ clients .IO .PrintInfo (ctx , false , "\n %s" , style .Sectionf (style.TextSection {
164+ Emoji : "evergreen_tree" ,
165+ Text : "App Environment" ,
166+ Secondary : details ,
167+ }))
139168 }
140-
141- clients .IO .PrintTrace (ctx , slacktrace .EnvAddSuccess )
142- clients .IO .PrintInfo (ctx , false , "\n %s" , style .Sectionf (style.TextSection {
143- Emoji : "evergreen_tree" ,
144- Text : "App Environment" ,
145- Secondary : []string {
146- fmt .Sprintf (
147- "Successfully added \" %s\" as an environment variable" ,
148- variableName ,
149- ),
150- },
151- }))
152169 return nil
153170}
0 commit comments