@@ -72,7 +72,6 @@ func init() {
7272 rootCmd .Flags ().IntVar (& timeoutSeconds , "timeout" , 30 , "GitHub API timeout in seconds" )
7373 rootCmd .Flags ().IntVar (& refreshInterval , "refresh-interval" , 0 , "Auto-refresh interval in seconds (0 = disabled, min 5)" )
7474
75- // Store original help functions before overriding
7675 originalRootHelpFunc := rootCmd .HelpFunc ()
7776 originalInitHelpFunc := initCmd .HelpFunc ()
7877
@@ -118,7 +117,6 @@ func runView(cmd *cobra.Command, _ []string) error {
118117 return err
119118 }
120119
121- // If a config path was explicitly provided via CLI flag, use it directly
122120 if cmd .Flags ().Changed ("config" ) {
123121 cfg , err := config .LoadMerged ([]string {configPath })
124122 if err != nil {
@@ -130,7 +128,6 @@ func runView(cmd *cobra.Command, _ []string) error {
130128 return runViewWithConfig (cfg , configPath )
131129 }
132130
133- // Otherwise, use the proper precedence system
134131 projectRoot , _ := git .GetGitRepositoryRoot ()
135132 var p * paths.Paths
136133 var err error
@@ -143,7 +140,6 @@ func runView(cmd *cobra.Command, _ []string) error {
143140 return fmt .Errorf ("failed to initialize paths: %w" , err )
144141 }
145142
146- // Load and merge all available configs
147143 configPaths := p .GetConfigPaths ()
148144 if len (configPaths ) > 0 {
149145 cfg , err := config .LoadMerged (configPaths )
@@ -153,17 +149,14 @@ func runView(cmd *cobra.Command, _ []string) error {
153149 if err := cfg .Validate (); err != nil {
154150 return fmt .Errorf ("invalid configuration: %w" , err )
155151 }
156- // Use the last loaded path as the primary config path for display/save purposes
157152 primaryPath := configPaths [len (configPaths )- 1 ]
158153 return runViewWithConfig (cfg , primaryPath )
159154 }
160155
161- // No config found, trigger init flow
162156 return handleMissingConfig ()
163157}
164158
165159func runViewWithConfig (cfg * config.Config , configPath string ) error {
166- // Use --repo flag if provided, otherwise use config repository
167160 if repo == "" {
168161 repo = cfg .Repository
169162 if repo != "" {
@@ -182,7 +175,6 @@ func runViewWithConfig(cfg *config.Config, configPath string) error {
182175 timeout := time .Duration (timeoutSeconds ) * time .Second
183176 gh := github .NewClientWithTimeout (repo , timeout )
184177
185- // Use CLI flag if provided, otherwise use config value
186178 interval := refreshInterval
187179 if interval == 0 && cfg .GetRefreshInterval () > 0 {
188180 interval = cfg .GetRefreshInterval ()
@@ -203,80 +195,131 @@ func runViewWithConfig(cfg *config.Config, configPath string) error {
203195}
204196
205197func runInit (cmd * cobra.Command , _ []string ) error {
206- // Initialize paths first - we'll need this throughout
198+ p , err := initializePaths ()
199+ if err != nil {
200+ return err
201+ }
202+
203+ explicitConfigPath := cmd != nil && cmd .Flags ().Changed ("config" )
204+ savePathHint := determineSavePathHint (p , explicitConfigPath )
205+
206+ workflows , useRemoteWorkflows , err := discoverWorkflows ()
207+ if err != nil {
208+ return err
209+ }
210+
211+ if len (workflows ) == 0 {
212+ return handleNoWorkflows (p , repo , useRemoteWorkflows )
213+ }
214+
215+ cfg , configType , err := runConfigWizard (workflows , savePathHint , useRemoteWorkflows )
216+ if err != nil {
217+ return err
218+ }
219+
220+ targetPath , location , err := determineConfigSaveTarget (p , explicitConfigPath , configPath , configType )
221+ if err != nil {
222+ return err
223+ }
224+
225+ if err := validateConfigOverwrite (targetPath ); err != nil {
226+ return err
227+ }
228+
229+ if err := saveConfigToLocation (cfg , targetPath , location , p ); err != nil {
230+ return err
231+ }
232+
233+ printSuccessSummary (targetPath , cfg )
234+ return nil
235+ }
236+
237+ func initializePaths () (* paths.Paths , error ) {
207238 projectRoot , _ := git .GetGitRepositoryRoot ()
239+
208240 var p * paths.Paths
209241 var err error
210242 if projectRoot != "" {
211243 p , err = paths .NewWithProject (projectRoot )
212244 } else {
213245 p , err = paths .New ()
214246 }
247+
215248 if err != nil {
216- return fmt .Errorf ("failed to initialize paths: %w" , err )
249+ return nil , fmt .Errorf ("failed to initialize paths: %w" , err )
217250 }
218251
219- // Determine if user explicitly provided a config path via CLI
220- explicitConfigPath := cmd != nil && cmd . Flags (). Changed ( "config" )
252+ return p , nil
253+ }
221254
222- // Use current best guess for save path - the wizard may change this later.
255+ func determineSavePathHint ( p * paths. Paths , explicitConfigPath bool ) string {
223256 savePathHint := p .UserConfigFile ()
224257 if explicitConfigPath && configPath != "" {
225258 savePathHint = configPath
226259 }
260+ return savePathHint
261+ }
227262
228- var workflows []string
229- var useRemoteWorkflows bool
230-
231- // If --repo flag is provided, fetch workflows from GitHub
263+ func discoverWorkflows () ([]string , bool , error ) {
232264 if repo != "" {
233- if err := git .ValidateRepositoryFormat (repo ); err != nil {
234- return err
235- }
236-
237- timeout := time .Duration (timeoutSeconds ) * time .Second
238- ghClient := github .NewClientWithTimeout ("" , timeout )
239- ctx := context .Background ()
240-
241- // Validate repository exists with spinner
242- _ , err := wizard .RunWithSpinner (ctx , fmt .Sprintf ("Validating repository %s" , repo ), func () (any , error ) {
243- exists , err := ghClient .RepositoryExists (ctx , repo )
244- if err != nil {
245- return nil , err
246- }
247- if ! exists {
248- return nil , fmt .Errorf ("repository not found or not accessible" )
249- }
250- return nil , nil
251- })
265+ workflows , err := fetchRemoteWorkflows ()
252266 if err != nil {
253- return err
267+ return nil , false , err
254268 }
269+ return workflows , true , nil
270+ }
255271
256- // Fetch workflows from GitHub with spinner
257- result , err := wizard .RunWithSpinner (ctx , fmt .Sprintf ("Fetching workflows from %s" , repo ), func () (interface {}, error ) {
258- return ghClient .GetWorkflows (ctx , repo )
259- })
260- if err != nil {
261- return fmt .Errorf ("failed to fetch workflows: %w" , err )
262- }
272+ workflows , err := discoverLocalWorkflows ()
273+ if err != nil {
274+ return nil , false , err
275+ }
263276
264- workflows = result .([]string )
265- useRemoteWorkflows = true
266- } else {
267- // Try to discover local workflows
268- workflowDir := ".github/workflows"
269- localWorkflows , err := wizard .DiscoverWorkflows (workflowDir )
277+ return workflows , false , nil
278+ }
279+
280+ func fetchRemoteWorkflows () ([]string , error ) {
281+ if err := git .ValidateRepositoryFormat (repo ); err != nil {
282+ return nil , err
283+ }
284+
285+ timeout := time .Duration (timeoutSeconds ) * time .Second
286+ ghClient := github .NewClientWithTimeout ("" , timeout )
287+ ctx := context .Background ()
288+
289+ _ , err := wizard .RunWithSpinner (ctx , fmt .Sprintf ("Validating repository %s" , repo ), func () (any , error ) {
290+ exists , err := ghClient .RepositoryExists (ctx , repo )
270291 if err != nil {
271- return handleNoLocalWorkflows ()
292+ return nil , err
272293 }
273- workflows = localWorkflows
294+ if ! exists {
295+ return nil , fmt .Errorf ("repository not found or not accessible" )
296+ }
297+ return nil , nil
298+ })
299+ if err != nil {
300+ return nil , err
274301 }
275302
276- if len (workflows ) == 0 {
277- return handleNoWorkflows (p , repo , useRemoteWorkflows )
303+ result , err := wizard .RunWithSpinner (ctx , fmt .Sprintf ("Fetching workflows from %s" , repo ), func () (interface {}, error ) {
304+ return ghClient .GetWorkflows (ctx , repo )
305+ })
306+ if err != nil {
307+ return nil , fmt .Errorf ("failed to fetch workflows: %w" , err )
308+ }
309+
310+ return result .([]string ), nil
311+ }
312+
313+ func discoverLocalWorkflows () ([]string , error ) {
314+ workflowDir := ".github/workflows"
315+ workflows , err := wizard .DiscoverWorkflows (workflowDir )
316+ if err != nil {
317+ return nil , handleNoLocalWorkflows ()
278318 }
319+ return workflows , nil
320+ }
279321
322+ func runConfigWizard (workflows []string , savePathHint string , useRemoteWorkflows bool ) (* config.Config , string , error ) {
280323 w := wizard .New (workflows , savePathHint )
281324
282325 // Set repository if using remote workflows
@@ -286,30 +329,34 @@ func runInit(cmd *cobra.Command, _ []string) error {
286329
287330 cfg , err := w .Run ()
288331 if err != nil {
289- return fmt .Errorf ("wizard failed: %w" , err )
332+ return nil , "" , fmt .Errorf ("wizard failed: %w" , err )
290333 }
291334
292- targetPath , location , err := determineConfigSaveTarget (p , explicitConfigPath , configPath , w .GetConfigType ())
293- if err != nil {
294- return err
295- }
335+ return cfg , w .GetConfigType (), nil
336+ }
296337
297- // Handle --reset flag for the chosen target
338+ func validateConfigOverwrite ( targetPath string ) error {
298339 if reset {
299340 if err := os .Remove (targetPath ); err == nil {
300341 fmt .Println (infoStyle .Render ("Removed existing config: " + targetPath ))
301342 } else if ! os .IsNotExist (err ) {
302343 return fmt .Errorf ("failed to remove existing config at %s: %w" , targetPath , err )
303344 }
304- } else if ! force {
345+ return nil
346+ }
347+
348+ if ! force {
305349 if _ , err := os .Stat (targetPath ); err == nil {
306350 return fmt .Errorf ("configuration file %s already exists. Use --force to overwrite or --reset to start fresh" , targetPath )
307351 } else if ! os .IsNotExist (err ) {
308352 return fmt .Errorf ("failed to check existing config at %s: %w" , targetPath , err )
309353 }
310354 }
311355
312- // Ensure directories exist and save to the desired location
356+ return nil
357+ }
358+
359+ func saveConfigToLocation (cfg * config.Config , targetPath string , location configSaveLocation , p * paths.Paths ) error {
313360 switch location {
314361 case saveLocationTeam :
315362 if err := cfg .SaveToRepoDefault (p ); err != nil {
@@ -330,13 +377,10 @@ func runInit(cmd *cobra.Command, _ []string) error {
330377 return fmt .Errorf ("failed to save configuration: %w" , err )
331378 }
332379 }
333-
334- printSuccessSummary (targetPath , cfg )
335380 return nil
336381}
337382
338383func runUpdateRepo (cmd * cobra.Command , args []string ) error {
339- // Auto-detect config path if not explicitly provided
340384 var actualConfigPath string
341385 if cmd .Flags ().Changed ("config" ) {
342386 actualConfigPath = configPath
@@ -367,11 +411,9 @@ func runUpdateRepo(cmd *cobra.Command, args []string) error {
367411
368412 var newRepo string
369413
370- // If repository is provided as argument, use it
371414 if len (args ) > 0 {
372415 newRepo = strings .TrimSpace (args [0 ])
373416 } else {
374- // Try to detect from .git/config
375417 detectedRepo , err := git .DetectRepository ()
376418 if err != nil || detectedRepo == "" {
377419 return fmt .Errorf ("could not detect repository from .git/config and no repository provided\n Usage: rivet update-repo owner/repo" )
@@ -380,7 +422,6 @@ func runUpdateRepo(cmd *cobra.Command, args []string) error {
380422 fmt .Println (infoStyle .Render ("Detected repository: " + newRepo ))
381423 }
382424
383- // Validate format
384425 if err := git .ValidateRepositoryFormat (newRepo ); err != nil {
385426 return err
386427 }
@@ -393,10 +434,7 @@ func runUpdateRepo(cmd *cobra.Command, args []string) error {
393434 return fmt .Errorf ("failed to validate repository %s: %v" , newRepo , err )
394435 }
395436
396- // Update config
397437 cfg .Repository = newRepo
398-
399- // Save updated config
400438 if err := cfg .Save (actualConfigPath ); err != nil {
401439 return fmt .Errorf ("failed to save configuration: %w" , err )
402440 }
0 commit comments