Skip to content

Commit

Permalink
add support for fetch based on package.xml manifest #361
Browse files Browse the repository at this point in the history
  • Loading branch information
dcarroll committed Dec 23, 2016
1 parent d91da1c commit 82cd30b
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 17 deletions.
47 changes: 30 additions & 17 deletions fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var cmdFetch = &Command{
-d, -directory # override the default target directory
-u, -unpack # unpack any zipped static resources (ignored if type is not StaticResource)
-p, -preserve # preserve the zip file
-x, -xml # provide a package.xml file to fetch data specified within
Export specified artifact(s) to a local directory. Use "package" type to retrieve an unmanaged package.
Expand All @@ -30,6 +31,7 @@ Examples
force fetch -t=CustomObject n=Book__c n=Author__c
force fetch -t Aura -n MyComponent -d /Users/me/Documents/Project/home
force fetch -t AuraDefinitionBundle -t ApexClass
force fetch -x myproj/metadata/package.xml
`,
}

Expand All @@ -56,6 +58,7 @@ var (
makefile bool
preserveZip bool
mdbase string
packageXml string
)

func init() {
Expand All @@ -69,6 +72,8 @@ func init() {
cmdFetch.Flag.BoolVar(&unpack, "unpack", false, "Unpack any static resources")
cmdFetch.Flag.BoolVar(&preserveZip, "p", false, "keep zip file on disk")
cmdFetch.Flag.BoolVar(&preserveZip, "preserve", false, "keep zip file on disk")
cmdFetch.Flag.StringVar(&packageXml, "x", "", "Package.xml file to use for fetch.")
cmdFetch.Flag.StringVar(&packageXml, "xml", "", "Package.xml file to use for fetch.")
cmdFetch.Run = runFetch
makefile = true
}
Expand Down Expand Up @@ -180,14 +185,16 @@ func persistBundles(bundles AuraDefinitionBundleResult, definitions AuraDefiniti
}

func runFetch(cmd *Command, args []string) {
if len(metadataTypes) == 0 {
ErrorAndExit("must specify object type and/or object name")

force, _ := ActiveForce()

if len(packageXml) == 0 && len(metadataTypes) == 0 {
ErrorAndExit("must specify object type and/or object name or package xml path")
}
if len(metadataTypes) > 1 && len(metadataName) > 1 {
ErrorAndExit("You cannot specify entity names if you specify more than one metadata type.")
}

force, _ := ActiveForce()
var files ForceMetadataFiles
var err error
var expandResources bool = unpack
Expand All @@ -213,17 +220,21 @@ func runFetch(cmd *Command, args []string) {
}
}
} else {
query := ForceMetadataQuery{}
if len(metadataName) > 0 {
mq := ForceMetadataQueryElement{metadataTypes, metadataName}
query = append(query, mq)
if len(packageXml) > 0 {
files, err = force.Metadata.RetrieveByPackageXml(packageXml)
} else {
mq := ForceMetadataQueryElement{metadataTypes, []string{"*"}}
query = append(query, mq)
}
files, err = force.Metadata.Retrieve(query)
if err != nil {
ErrorAndExit(err.Error())
query := ForceMetadataQuery{}
if len(metadataName) > 0 {
mq := ForceMetadataQueryElement{metadataTypes, metadataName}
query = append(query, mq)
} else {
mq := ForceMetadataQueryElement{metadataTypes, []string{"*"}}
query = append(query, mq)
}
files, err = force.Metadata.Retrieve(query)
if err != nil {
ErrorAndExit(err.Error())
}
}
}

Expand Down Expand Up @@ -251,10 +262,12 @@ func runFetch(cmd *Command, args []string) {
ErrorAndExit(err.Error())
}
var isResource = false
if strings.ToLower(metadataTypes[0]) == "staticresource" {
isResource = true
} else if strings.HasSuffix(file, ".resource-meta.xml") {
isResource = true
if len(packageXml) == 0 {
if strings.ToLower(metadataTypes[0]) == "staticresource" {
isResource = true
} else if strings.HasSuffix(file, ".resource-meta.xml") {
isResource = true
}
}
//Handle expanding static resources into a "bundle" folder
if isResource && expandResources {
Expand Down
68 changes: 68 additions & 0 deletions metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ func (fm *ForceMetadata) CheckStatus(id string) (err error) {
switch {
case !status.Done:
fmt.Printf("Not done yet: %s Will check again in five seconds.\n", status.State)
//fmt.Printf("ID: %s State: %s - message: %s\n", id, status.State, status.Message)
time.Sleep(5000 * time.Millisecond)
return fm.CheckStatus(id)
case status.State == "Error":
Expand Down Expand Up @@ -1142,6 +1143,73 @@ func (fm *ForceMetadata) DeployZipFile(soap string, zipfile []byte) (results For
return
}

func (fm *ForceMetadata) RetrieveByPackageXml(package_xml string) (files ForceMetadataFiles, err error) {
// Need to crack open the xml file and pull out the <types> array
data, err := ioutil.ReadFile(package_xml)

if err != nil {
ErrorAndExit(err.Error())
}
soap := `
<retrieveRequest>
<apiVersion>%s</apiVersion>
<unpackaged>
%s
</unpackaged>
</retrieveRequest>
`

type types struct {
Name string `xml:"name"`
Members []string `xml:"members"`
}

var pxml struct {
Results []types `xml:"types"`
}

xml.Unmarshal(data, &pxml)

xml_types := ""
for _, p_xml := range pxml.Results {
xml, err := xml.MarshalIndent(p_xml, " ", " ")
if err != nil {
ErrorAndExit(err.Error())
}
xml_types += fmt.Sprintf("%s\n", xml)
}

body, err := fm.soapExecute("retrieve", fmt.Sprintf(soap, apiVersionNumber, xml_types))
if err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
var status struct {
Id string `xml:"Body>retrieveResponse>result>id"`
}
if err = xml.Unmarshal(body, &status); err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}

if err = fm.CheckStatus(status.Id); err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
raw_files, err := fm.CheckRetrieveStatus(status.Id)
if err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
files = make(ForceMetadataFiles)
for raw_name, data := range raw_files {
name := strings.Replace(raw_name, "unpackaged/", "", -1)
files[name] = data
}

return
}

func (fm *ForceMetadata) Retrieve(query ForceMetadataQuery) (files ForceMetadataFiles, err error) {

soap := `
Expand Down

0 comments on commit 82cd30b

Please sign in to comment.