github.com/kaixiang/packer@v0.5.2-0.20140114230416-1f5786b0d7f1/command/inspect/command.go (about) 1 package inspect 2 3 import ( 4 "flag" 5 "fmt" 6 "github.com/mitchellh/packer/packer" 7 "log" 8 "sort" 9 "strings" 10 ) 11 12 type Command struct{} 13 14 func (Command) Help() string { 15 return strings.TrimSpace(helpText) 16 } 17 18 func (c Command) Synopsis() string { 19 return "see components of a template" 20 } 21 22 func (c Command) Run(env packer.Environment, args []string) int { 23 flags := flag.NewFlagSet("inspect", flag.ContinueOnError) 24 flags.Usage = func() { env.Ui().Say(c.Help()) } 25 if err := flags.Parse(args); err != nil { 26 return 1 27 } 28 29 args = flags.Args() 30 if len(args) != 1 { 31 flags.Usage() 32 return 1 33 } 34 35 // Read the file into a byte array so that we can parse the template 36 log.Printf("Reading template: %#v", args[0]) 37 tpl, err := packer.ParseTemplateFile(args[0], nil) 38 if err != nil { 39 env.Ui().Error(fmt.Sprintf("Failed to parse template: %s", err)) 40 return 1 41 } 42 43 // Convenience... 44 ui := env.Ui() 45 46 // Description 47 if tpl.Description != "" { 48 ui.Say("Description:\n") 49 ui.Say(tpl.Description + "\n") 50 } 51 52 // Variables 53 if len(tpl.Variables) == 0 { 54 ui.Say("Variables:\n") 55 ui.Say(" <No variables>") 56 } else { 57 requiredHeader := false 58 for k, v := range tpl.Variables { 59 if v.Required { 60 if !requiredHeader { 61 requiredHeader = true 62 ui.Say("Required variables:\n") 63 } 64 65 ui.Machine("template-variable", k, v.Default, "1") 66 ui.Say(" " + k) 67 } 68 } 69 70 if requiredHeader { 71 ui.Say("") 72 } 73 74 ui.Say("Optional variables and their defaults:\n") 75 keys := make([]string, 0, len(tpl.Variables)) 76 max := 0 77 for k, _ := range tpl.Variables { 78 keys = append(keys, k) 79 if len(k) > max { 80 max = len(k) 81 } 82 } 83 84 sort.Strings(keys) 85 86 for _, k := range keys { 87 v := tpl.Variables[k] 88 if v.Required { 89 continue 90 } 91 92 padding := strings.Repeat(" ", max-len(k)) 93 output := fmt.Sprintf(" %s%s = %s", k, padding, v.Default) 94 95 ui.Machine("template-variable", k, v.Default, "0") 96 ui.Say(output) 97 } 98 } 99 100 ui.Say("") 101 102 // Builders 103 ui.Say("Builders:\n") 104 if len(tpl.Builders) == 0 { 105 ui.Say(" <No builders>") 106 } else { 107 keys := make([]string, 0, len(tpl.Builders)) 108 max := 0 109 for k, _ := range tpl.Builders { 110 keys = append(keys, k) 111 if len(k) > max { 112 max = len(k) 113 } 114 } 115 116 sort.Strings(keys) 117 118 for _, k := range keys { 119 v := tpl.Builders[k] 120 padding := strings.Repeat(" ", max-len(k)) 121 output := fmt.Sprintf(" %s%s", k, padding) 122 if v.Name != v.Type { 123 output = fmt.Sprintf("%s (%s)", output, v.Type) 124 } 125 126 ui.Machine("template-builder", k, v.Type) 127 ui.Say(output) 128 129 } 130 } 131 132 ui.Say("") 133 134 // Provisioners 135 ui.Say("Provisioners:\n") 136 if len(tpl.Provisioners) == 0 { 137 ui.Say(" <No provisioners>") 138 } else { 139 for _, v := range tpl.Provisioners { 140 ui.Machine("template-provisioner", v.Type) 141 ui.Say(fmt.Sprintf(" %s", v.Type)) 142 } 143 } 144 145 ui.Say("\nNote: If your build names contain user variables or template\n" + 146 "functions such as 'timestamp', these are processed at build time,\n" + 147 "and therefore only show in their raw form here.") 148 149 return 0 150 }