github.com/mhlo/force@v0.22.28-0.20150915022417-6d05ecfb0b47/aura.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strings" 10 ) 11 12 // Brief comment to fire commit 13 14 var cmdAura = &Command{ 15 Usage: "aura", 16 Short: "force aura push -resourcepath=<filepath>", 17 Long: ` 18 The aura command needs context to work. If you execute "aura get" 19 it will create a folder structure that provides the context for 20 aura components on disk. 21 22 The aura components will be created in "metadata/aurabundles/<componentname>" 23 relative to the current working directory and a .manifest file will be 24 created that associates components and their artifacts with their ids in 25 the database. 26 27 To create a new component (application, evt or component), create a new 28 folder under "aura". Then create a new file in your new folder. You 29 must follow a naming convention for your files to enable proper definition 30 of the component type. 31 32 Naming convention <compnentName><artifact type>.<file type extension> 33 Examples: metadata 34 aura 35 MyApp 36 MyAppApplication.app 37 MyAppStyle.css 38 MyList 39 MyComponent.cmp 40 MyComponentHelper.js 41 MyComponentStyle.css 42 43 force aura push -f <fullFilePath> -b <bundle name> 44 45 force aura create -t=<entity type> <entityName> 46 47 force aura delete -f=<fullFilePath> 48 49 force aura list 50 51 `, 52 } 53 54 func init() { 55 cmdAura.Run = runAura 56 cmdAura.Flag.Var(&resourcepath, "p", "fully qualified file name for entity") 57 cmdAura.Flag.Var(&resourcepath, "f", "fully qualified file name for entity") 58 cmdAura.Flag.StringVar(&metadataType, "entitytype", "", "fully qualified file name for entity") 59 cmdAura.Flag.StringVar(&auraentityname, "entityname", "", "fully qualified file name for entity") 60 cmdAura.Flag.StringVar(&metadataType, "t", "", "fully qualified file name for entity") 61 cmdAura.Flag.StringVar(&auraentityname, "n", "", "fully qualified file name for entity") 62 } 63 64 var ( 65 auraentityname string 66 ) 67 68 func runAura(cmd *Command, args []string) { 69 if err := cmd.Flag.Parse(args[0:]); err != nil { 70 os.Exit(2) 71 } 72 73 force, _ := ActiveForce() 74 75 subcommand := args[0] 76 // Sublime hack - the way sublime passes parameters seems to 77 // break the flag parsing by sending a single element array 78 // for the args. ARGH!!! 79 if strings.HasPrefix(subcommand, "delete ") || strings.HasPrefix(subcommand, "push ") { 80 what := strings.Split(subcommand, " ") 81 if err := cmd.Flag.Parse(what[1:]); err != nil { 82 ErrorAndExit(err.Error()) 83 } 84 subcommand = what[0] 85 } else { 86 if err := cmd.Flag.Parse(args[1:]); err != nil { 87 ErrorAndExit(err.Error()) 88 } 89 } 90 91 switch strings.ToLower(subcommand) { 92 case "create": 93 /*if *auraentitytype == "" || *auraentityname == "" { 94 fmt.Println("Must specify entity type and name") 95 os.Exit(2) 96 }*/ 97 ErrorAndExit("force aura create not yet implemented") 98 99 case "delete": 100 runDeleteAura() 101 case "list": 102 bundles, err := force.GetAuraBundlesList() 103 if err != nil { 104 ErrorAndExit(err.Error()) 105 } 106 for _, bundle := range bundles.Records { 107 fmt.Println(bundle["DeveloperName"]) 108 } 109 case "push": 110 // absPath, _ := filepath.Abs(resourcepath[0]) 111 runPushAura(cmd, resourcepath) 112 } 113 } 114 115 func runDeleteAura() { 116 absPath, _ := filepath.Abs(resourcepath[0]) 117 //resourcepath = absPath 118 119 if InAuraBundlesFolder(absPath) { 120 info, err := os.Stat(absPath) 121 if err != nil { 122 ErrorAndExit(err.Error()) 123 } 124 manifest, err := GetManifest(absPath) 125 isBundle := false 126 if info.IsDir() { 127 force, _ := ActiveForce() 128 manifest, err = GetManifest(filepath.Join(absPath, ".manifest")) 129 bid := "" 130 if err != nil { // Could not find a manifest, use bundle name 131 // Try to look up the bundle by name 132 b, err := force.GetAuraBundleByName(filepath.Base(absPath)) 133 if err != nil { 134 ErrorAndExit(err.Error()) 135 } else { 136 if len(b.Records) == 0 { 137 ErrorAndExit(fmt.Sprintf("No bundle definition named %q", filepath.Base(absPath))) 138 } else { 139 bid = b.Records[0]["Id"].(string) 140 } 141 } 142 } else { 143 bid = manifest.Id 144 } 145 146 err = force.DeleteToolingRecord("AuraDefinitionBundle", bid) 147 if err != nil { 148 ErrorAndExit(err.Error()) 149 } 150 // Now walk the bundle and remove all the atrifacts 151 filepath.Walk(absPath, func(path string, inf os.FileInfo, err error) error { 152 os.Remove(path) 153 return nil 154 }) 155 os.Remove(absPath) 156 fmt.Println("Bundle ", filepath.Base(absPath), " deleted.") 157 return 158 } 159 160 for key := range manifest.Files { 161 mfile := manifest.Files[key].FileName 162 cfile := absPath 163 if !filepath.IsAbs(mfile) { 164 cfile = filepath.Base(cfile) 165 } 166 if isBundle { 167 if !filepath.IsAbs(mfile) { 168 cfile = filepath.Join(absPath, mfile) 169 } else { 170 cfile = mfile 171 deleteAuraDefinition(manifest, key) 172 } 173 } else { 174 if mfile == cfile { 175 deleteAuraDefinition(manifest, key) 176 return 177 } 178 } 179 } 180 if isBundle { 181 // Need to remove the bundle using the id in the manifest 182 deleteAuraDefinitionBundle(manifest) 183 } 184 } 185 } 186 func deleteAuraDefinitionBundle(manifest BundleManifest) { 187 force, err := ActiveForce() 188 err = force.DeleteToolingRecord("AuraDefinitionBundle", manifest.Id) 189 if err != nil { 190 ErrorAndExit(err.Error()) 191 } 192 os.Remove(filepath.Join(resourcepath[0], ".manifest")) 193 os.Remove(resourcepath[0]) 194 } 195 196 func deleteAuraDefinition(manifest BundleManifest, key int) { 197 force, err := ActiveForce() 198 err = force.DeleteToolingRecord("AuraDefinition", manifest.Files[key].ComponentId) 199 if err != nil { 200 ErrorAndExit(err.Error()) 201 } 202 fname := manifest.Files[key].FileName 203 os.Remove(fname) 204 manifest.Files = append(manifest.Files[:key], manifest.Files[key+1:]...) 205 bmBody, _ := json.Marshal(manifest) 206 ioutil.WriteFile(filepath.Join(filepath.Dir(fname), ".manifest"), bmBody, 0644) 207 }