2023-10-11 14:26:22 +00:00
package cli
import (
"encoding/json"
"fmt"
"strings"
"time"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/cli/cliui"
"github.com/coder/coder/v2/codersdk"
2023-10-18 20:08:02 +00:00
"github.com/coder/pretty"
2024-03-15 16:24:38 +00:00
"github.com/coder/serpent"
2023-10-11 14:26:22 +00:00
)
2024-03-17 14:45:26 +00:00
func ( r * RootCmd ) unarchiveTemplateVersion ( ) * serpent . Command {
2023-10-11 14:26:22 +00:00
return r . setArchiveTemplateVersion ( false )
}
2024-03-17 14:45:26 +00:00
func ( r * RootCmd ) archiveTemplateVersion ( ) * serpent . Command {
2023-10-11 14:26:22 +00:00
return r . setArchiveTemplateVersion ( true )
}
//nolint:revive
2024-03-17 14:45:26 +00:00
func ( r * RootCmd ) setArchiveTemplateVersion ( archive bool ) * serpent . Command {
2023-10-11 14:26:22 +00:00
presentVerb := "archive"
pastVerb := "archived"
if ! archive {
presentVerb = "unarchive"
pastVerb = "unarchived"
}
client := new ( codersdk . Client )
2024-03-17 14:45:26 +00:00
cmd := & serpent . Command {
2023-10-11 14:26:22 +00:00
Use : presentVerb + " <template-name> [template-version-names...] " ,
Short : strings . ToUpper ( string ( presentVerb [ 0 ] ) ) + presentVerb [ 1 : ] + " a template version(s)." ,
2024-03-15 16:24:38 +00:00
Middleware : serpent . Chain (
2023-10-11 14:26:22 +00:00
r . InitClient ( client ) ,
) ,
2024-03-15 16:24:38 +00:00
Options : serpent . OptionSet {
2023-10-11 14:26:22 +00:00
cliui . SkipPromptOption ( ) ,
} ,
2024-03-15 16:24:38 +00:00
Handler : func ( inv * serpent . Invocation ) error {
2023-10-11 14:26:22 +00:00
var (
ctx = inv . Context ( )
versions [ ] codersdk . TemplateVersion
)
2024-02-26 16:03:49 +00:00
organization , err := CurrentOrganization ( r , inv , client )
2023-10-11 14:26:22 +00:00
if err != nil {
return err
}
if len ( inv . Args ) == 0 {
return xerrors . Errorf ( "missing template name" )
}
if len ( inv . Args ) < 2 {
return xerrors . Errorf ( "missing template version name(s)" )
}
templateName := inv . Args [ 0 ]
template , err := client . TemplateByName ( ctx , organization . ID , templateName )
if err != nil {
return xerrors . Errorf ( "get template by name: %w" , err )
}
for _ , versionName := range inv . Args [ 1 : ] {
version , err := client . TemplateVersionByOrganizationAndName ( ctx , organization . ID , template . Name , versionName )
if err != nil {
return xerrors . Errorf ( "get template version by name %q: %w" , versionName , err )
}
versions = append ( versions , version )
}
for _ , version := range versions {
if version . Archived == archive {
_ , _ = fmt . Fprintln (
inv . Stdout , fmt . Sprintf ( "Version " + pretty . Sprint ( cliui . DefaultStyles . Keyword , version . Name ) + " already " + pastVerb ) ,
)
continue
}
err := client . SetArchiveTemplateVersion ( ctx , version . ID , archive )
if err != nil {
return xerrors . Errorf ( "%s template version %q: %w" , presentVerb , version . Name , err )
}
_ , _ = fmt . Fprintln (
inv . Stdout , fmt . Sprintf ( "Version " + pretty . Sprint ( cliui . DefaultStyles . Keyword , version . Name ) + " " + pastVerb + " at " + cliui . Timestamp ( time . Now ( ) ) ) ,
)
}
return nil
} ,
}
return cmd
}
2024-03-17 14:45:26 +00:00
func ( r * RootCmd ) archiveTemplateVersions ( ) * serpent . Command {
2024-03-15 16:24:38 +00:00
var all serpent . Bool
2023-10-11 14:26:22 +00:00
client := new ( codersdk . Client )
2024-03-17 14:45:26 +00:00
cmd := & serpent . Command {
2023-10-11 14:26:22 +00:00
Use : "archive [template-name...] " ,
Short : "Archive unused or failed template versions from a given template(s)" ,
2024-03-15 16:24:38 +00:00
Middleware : serpent . Chain (
2023-10-11 14:26:22 +00:00
r . InitClient ( client ) ,
) ,
2024-03-15 16:24:38 +00:00
Options : serpent . OptionSet {
2023-10-11 14:26:22 +00:00
cliui . SkipPromptOption ( ) ,
2024-03-15 16:24:38 +00:00
serpent . Option {
2023-10-11 14:26:22 +00:00
Name : "all" ,
Description : "Include all unused template versions. By default, only failed template versions are archived." ,
Flag : "all" ,
Value : & all ,
} ,
} ,
2024-03-15 16:24:38 +00:00
Handler : func ( inv * serpent . Invocation ) error {
2023-10-11 14:26:22 +00:00
var (
ctx = inv . Context ( )
templateNames = [ ] string { }
templates = [ ] codersdk . Template { }
)
2024-02-26 16:03:49 +00:00
organization , err := CurrentOrganization ( r , inv , client )
2023-10-11 14:26:22 +00:00
if err != nil {
return err
}
if len ( inv . Args ) > 0 {
templateNames = inv . Args
for _ , templateName := range templateNames {
template , err := client . TemplateByName ( ctx , organization . ID , templateName )
if err != nil {
return xerrors . Errorf ( "get template by name: %w" , err )
}
templates = append ( templates , template )
}
} else {
template , err := selectTemplate ( inv , client , organization )
if err != nil {
return err
}
templates = append ( templates , template )
templateNames = append ( templateNames , template . Name )
}
// Confirm archive of the template.
_ , err = cliui . Prompt ( inv , cliui . PromptOptions {
Text : fmt . Sprintf ( "Archive template versions of these templates: %s?" , pretty . Sprint ( cliui . DefaultStyles . Code , strings . Join ( templateNames , ", " ) ) ) ,
IsConfirm : true ,
Default : cliui . ConfirmNo ,
} )
if err != nil {
return err
}
for _ , template := range templates {
resp , err := client . ArchiveTemplateVersions ( ctx , template . ID , all . Value ( ) )
if err != nil {
return xerrors . Errorf ( "archive template %q: %w" , template . Name , err )
}
_ , _ = fmt . Fprintln (
inv . Stdout , fmt . Sprintf ( "Archived %d versions from " + pretty . Sprint ( cliui . DefaultStyles . Keyword , template . Name ) + " at " + cliui . Timestamp ( time . Now ( ) ) , len ( resp . ArchivedIDs ) ) ,
)
if ok , _ := inv . ParsedFlags ( ) . GetBool ( "verbose" ) ; err == nil && ok {
data , err := json . Marshal ( resp )
if err != nil {
return xerrors . Errorf ( "marshal verbose response: %w" , err )
}
_ , _ = fmt . Fprintln (
inv . Stdout , string ( data ) ,
)
}
}
return nil
} ,
}
return cmd
}