github.com/getgauge/gauge@v1.6.9/cmd/list.go (about) 1 /*---------------------------------------------------------------- 2 * Copyright (c) ThoughtWorks, Inc. 3 * Licensed under the Apache License, Version 2.0 4 * See LICENSE in the project root for license information. 5 *----------------------------------------------------------------*/ 6 7 package cmd 8 9 import ( 10 "fmt" 11 supersort "sort" 12 13 gm "github.com/getgauge/gauge-proto/go/gauge_messages" 14 "github.com/getgauge/gauge/config" 15 "github.com/getgauge/gauge/manifest" 16 "github.com/getgauge/gauge/runner" 17 "github.com/getgauge/gauge/util" 18 19 "github.com/getgauge/gauge/filter" 20 "github.com/getgauge/gauge/gauge" 21 "github.com/getgauge/gauge/logger" 22 "github.com/getgauge/gauge/parser" 23 "github.com/spf13/cobra" 24 ) 25 26 var ( 27 listCmd = &cobra.Command{ 28 Use: "list [flags] [args]", 29 Short: "List specifications, scenarios, steps or tags for a gauge project", 30 Long: `List specifications, scenarios, steps or tags for a gauge project`, 31 Example: ` gauge list --tags specs`, 32 Run: func(cmd *cobra.Command, args []string) { 33 if err := config.SetProjectRoot(args); err != nil { 34 exit(err, cmd.UsageString()) 35 } 36 loadEnvAndReinitLogger(cmd) 37 specs, failed := parser.ParseSpecs(getSpecsDir(args), gauge.NewConceptDictionary(), gauge.NewBuildErrors()) 38 if failed { 39 return 40 } 41 if specsFlag { 42 logger.Info(true, "[Specifications]") 43 listSpecifications(specs, print) 44 } 45 if scenariosFlag { 46 logger.Info(true, "[Scenarios]") 47 listScenarios(specs, print) 48 } 49 if tagsFlag { 50 logger.Info(true, "[Tags]") 51 listTags(specs, print) 52 } 53 if stepsFlag { 54 logger.Info(true, "[Steps]") 55 listSteps(specs, print) 56 } 57 if !specsFlag && !scenariosFlag && !tagsFlag && !stepsFlag { 58 exit(fmt.Errorf("Missing flag, nothing to list"), cmd.UsageString()) 59 } 60 }, 61 DisableAutoGenTag: true, 62 } 63 tagsFlag bool 64 specsFlag bool 65 scenariosFlag bool 66 stepsFlag bool 67 ) 68 69 func init() { 70 GaugeCmd.AddCommand(listCmd) 71 listCmd.Flags().BoolVarP(&tagsFlag, "tags", "", false, "List the tags in projects") 72 listCmd.Flags().BoolVarP(&specsFlag, "specs", "", false, "List the specifications in projects") 73 listCmd.Flags().BoolVarP(&scenariosFlag, "scenarios", "", false, "List the scenarios in projects") 74 listCmd.Flags().BoolVarP(&stepsFlag, "steps", "", false, "List all the steps in projects (including concept steps). Does not include unused steps.") 75 } 76 77 type handleResult func([]string) 78 79 func print(res []string) { 80 for _, element := range res { 81 logger.Info(true, element) 82 } 83 } 84 85 func listTags(s []*gauge.Specification, f handleResult) { 86 allTags := []string{} 87 for _, spec := range s { 88 allTags = appendTags(allTags, spec.Tags) 89 for _, scenario := range spec.Scenarios { 90 allTags = appendTags(allTags, scenario.Tags) 91 } 92 } 93 f(sortedDistinctElements(allTags)) 94 } 95 96 func listScenarios(s []*gauge.Specification, f handleResult) { 97 allScenarios := filter.GetAllScenarios(s) 98 f(sortedDistinctElements(allScenarios)) 99 } 100 101 func listSpecifications(s []*gauge.Specification, f handleResult) { 102 allSpecs := []string{} 103 for _, spec := range s { 104 allSpecs = append(allSpecs, spec.Heading.Value) 105 } 106 f(sortedDistinctElements(allSpecs)) 107 } 108 109 func listSteps(s []*gauge.Specification, f handleResult) { 110 f(sortedDistinctElements(getImplementedStepsWithAliases())) 111 } 112 113 func sortedDistinctElements(s []string) []string { 114 unique := uniqueNonEmptyElementsOf(s) 115 supersort.Strings(unique) 116 return unique 117 } 118 119 func appendTags(s []string, tags *gauge.Tags) []string { 120 if tags != nil { 121 s = append(s, tags.Values()...) 122 } 123 return s 124 } 125 126 func uniqueNonEmptyElementsOf(input []string) []string { 127 unique := make(map[string]bool, len(input)) 128 us := make([]string, len(unique)) 129 for _, elem := range input { 130 if len(elem) != 0 && !unique[elem] { 131 us = append(us, elem) 132 unique[elem] = true 133 } 134 } 135 136 return us 137 } 138 139 func getImplementedStepsWithAliases() []string { 140 r, err := connectToRunner() 141 defer func() { _ = r.Kill() }() 142 if err != nil { 143 panic(err) 144 } 145 getAllStepsRequest := &gm.Message{MessageType: gm.Message_StepNamesRequest, StepNamesRequest: &gm.StepNamesRequest{}} 146 response, err := r.ExecuteMessageWithTimeout(getAllStepsRequest) 147 if err != nil { 148 exit(fmt.Errorf("error while connecting to runner : %s", err.Error()), "unable to get steps from runner") 149 } 150 return response.GetStepNamesResponse().GetSteps() 151 } 152 153 var connectToRunner = func() (runner.Runner, error) { 154 outFile, err := util.OpenFile(logger.ActiveLogFile) 155 if err != nil { 156 return nil, err 157 } 158 manifest, err := manifest.ProjectManifest() 159 if err != nil { 160 return nil, err 161 } 162 163 return runner.StartGrpcRunner(manifest, outFile, outFile, config.IdeRequestTimeout(), false) 164 }