github.com/actions-on-google/gactions@v3.2.0+incompatible/cmd/gactions/cli/versions/versions.go (about) 1 // Copyright 2021 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // Package versions provides an implementation of an action on "versions". 16 package versions 17 18 import ( 19 "context" 20 "fmt" 21 "os" 22 "regexp" 23 "text/tabwriter" 24 25 "github.com/actions-on-google/gactions/api/sdk" 26 "github.com/actions-on-google/gactions/project" 27 "github.com/actions-on-google/gactions/project/studio" 28 "github.com/spf13/cobra" 29 ) 30 31 var versionIDRegExp = regexp.MustCompile(`^projects/[^/]+/versions/(?P<versionID>[^/]+)$`) 32 var modifiedOnRegExp = regexp.MustCompile(`(?P<date>\d{4}-\d{2}-\d{2})+T+(?P<time>\d{2}:\d{2}:\d{2})(\.\d{6})+Z`) 33 34 // AddCommand adds the release-channels list sub-command to the passed in root command. 35 func AddCommand(ctx context.Context, root *cobra.Command, project project.Project) { 36 versions := &cobra.Command{ 37 Use: "versions", 38 Short: "This is the main command for viewing and managing versions. See below for a complete list of sub-commands.", 39 Long: "This is the main command for viewing and managing versions. See below for a complete list of sub-commands.", 40 Args: cobra.MinimumNArgs(1), 41 } 42 list := &cobra.Command{ 43 Use: "list", 44 Short: "This command lists all versions and their metadata.", 45 Long: "This command lists all versions and their metadata.", 46 RunE: func(cmd *cobra.Command, _ []string) error { 47 studioProj, ok := project.(studio.Studio) 48 if !ok { 49 return fmt.Errorf("can not convert %T to %T", project, studio.Studio{}) 50 } 51 pid, err := cmd.Flags().GetString("project-id") 52 if err != nil { 53 return err 54 } 55 if err := (&studioProj).SetProjectID(pid); err != nil { 56 return err 57 } 58 res, err := sdk.ListVersionsJSON(ctx, studioProj) 59 if err != nil { 60 return err 61 } 62 return printVersions(res) 63 }, 64 } 65 list.Flags().String("project-id", "", "List versions of the project specified by the ID. The value provided in this flag will overwrite the value from settings file, if present.") 66 versions.AddCommand(list) 67 root.AddCommand(versions) 68 } 69 70 func printVersions(versions []project.Version) error { 71 w := new(tabwriter.Writer) 72 // Format in tab-separated columns with a tab stop of 8. 73 w.Init(os.Stdout, 20, 8, 1, '\t', 0) 74 fmt.Fprintln(w, "Version\tStatus\tLast Modified By\tModified On\t") 75 for _, version := range versions { 76 fmt.Fprintf(w, "%v\t%v\t%v\t%v\t\n", versionID(version.ID), version.State.Message, version.LastModifiedBy, formatModifiedOn(version.ModifiedOn)) 77 } 78 fmt.Fprintf(w, "To learn more about release channels, visit https://developers.google.com/assistant/actionssdk/reference/rest/Shared.Types/ReleaseChannel.") 79 fmt.Fprintln(w) 80 return w.Flush() 81 } 82 83 func versionID(version string) string { 84 versionIDMatch := versionIDRegExp.FindStringSubmatch(version) 85 if versionIDMatch == nil { 86 return "N/A" 87 } 88 return versionIDMatch[versionIDRegExp.SubexpIndex("versionID")] 89 } 90 91 func formatModifiedOn(modifiedOn string) string { 92 modifiedOnMatch := modifiedOnRegExp.FindStringSubmatch(modifiedOn) 93 if modifiedOnMatch == nil { 94 return "N/A" 95 } 96 97 return modifiedOnMatch[modifiedOnRegExp.SubexpIndex("date")] + " " + modifiedOnMatch[modifiedOnRegExp.SubexpIndex("time")] 98 }