-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsf-metadata
executable file
·161 lines (149 loc) · 5.83 KB
/
sf-metadata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env bash
#
# Download metadata of all or of specific Salesforce metadata types as xml files
#
# USAGE
#
# sf-metadata # retrieve all metadata
# sf-metadata -o ORG # retrieve all metadata from ORG
# sf-metadata -m NAME1 -m NAME2 # retrieve metadata of type NAME1 and NAME2
# sf-metadata -x # retrieve only metadata declared in manifest/package.xml (same as 'sf project retrieve start -x')
# sf-metadata -p # create minimal empty SFDX-project named 'ORG' before retrieval
# sf-metadata -P # create minimal empty SFDX-project named 'ORG_COUNT' before retrieval
# sf-metadata -l # only fetch metadata-types that contained data during the last run
#
# EXAMPLES
#
# sf-metadata -p -o org1; sf-metadata -p -o org2; diff -qr org1 org2 # compare metadata of org1 and org2
# sf-metadata -P; sf-metadata -P; diff -qr org_001 org_002 # compare metadata of an org at two different points in time
# sf-metadata -m ExperienceBundle -m Audience -m NavigationMenu -m NetworkBranding -m Network -m CustomSite # retrieve Expereince Builder related metadata
#
# COMMANDS
#
# sf org list metadata-types | jq -r '.metadataObjects[].xmlName, .metadataObjects[].childXmlNames[]' # list of all metadata types
# sf project retrieve start -m NAME:MEMBER # retrieve metadata of type NAME:MEMBER
#
# echo '{"packageDirectories": [{"path": "force-app"}]}' > sfdx-project.json; mkdir force-app;
# while read name; do sf project retrieve start -m $name; done < <(sf org list metadata-types | jq -r '.metadataObjects[].xmlName')
yesno() {
echo ""
read -p "$1 [Y/n] " response
[[ $response == "n" || $response == "N" ]] && exit 1
}
show_help() {
awk '/^[^ #]/{c=1}c==0{print $0}' $0 | sed -n '/^#/p' | sed 1d | sed 's/^#/ /g' \
| perl -pe "s/ #(.*)$/$(tput setaf 0)\1$(tput sgr 0)/" \
| perl -pe "s/(USAGE|EXAMPLES|COMMANDS)/$(tput setaf 0)\1$(tput sgr 0)/" \
| perl -pe "s/\`(.+)\`/$(tput sgr 0 1)\1$(tput sgr 0)/"
exit 1
}
setTargetOrg() {
if [[ -z "$org" ]]; then
org=$(cat .sf/config.json 2>/dev/null | jq -r '."target-org" | select( . != null )')
fi
if [[ -z "$org" ]]; then
org=$(cat ~/.sf/config.json 2>/dev/null | jq -r '."target-org" | select( . != null )')
fi
if [[ -z "$org" ]]; then
echo -e >&2 "\n $(tput setaf 1)Missing target org$(tput sgr 0)\n\n Either provide with $(tput setaf 0)-o$(tput sgr 0) option, or set via $(tput setaf 0)sf config set target-org <org>$(tput sgr 0)"
exit 1
fi
}
org=""
name=""
names_list=$(mktemp)
project=false
projectsequence=false
manifest=false
last=false
while [ $# -gt 0 ]; do
case $1 in
-o|--org)
shift
org=$1
;;
-m|--metadata)
shift
if [[ $name == "" ]]; then
name=$1
else
name="${name},${1}"
fi
;;
-p|--project)
project=true
;;
-P|--projects)
project=true
projectsequence=true
;;
-x|--manifest)
manifest=true
;;
-l|--last)
last=true # TODO create a protocol on each run and use the one from the last run
echo "Is yet to be implemented"
exit 1
;;
-h|--help)
show_help
;;
*)
;;
esac
shift
done
setTargetOrg
if [[ ! -f "./sfdx-project.json" ]] && [[ $project == true ]]; then
if [[ $projectsequence == true ]]; then
counter=$(fd -t d ${org}_ | wc -l | tr -d " ")
let counter++
projectdir="${org}_${counter}"
else
projectdir=${org}
fi
mkdir -p "${projectdir}/force-app"
cd "$projectdir"
echo '{"packageDirectories": [{"path": "force-app"}]}' > sfdx-project.json
fi
if [[ ! -f "./sfdx-project.json" ]]; then
echo -e >&2 "\n $(tput setaf 1)not a SFDX project$(tput sgr0)"
exit 1
fi
if [[ ! -f "./manifest/package.xml" ]] && [[ $manifest == true ]]; then
echo -e >&2 "\n $(tput setaf 1)no package manifest$(tput sgr0)"
exit 1
fi
if [[ $name == "" && $manifest == false ]]; then
name="all"
[[ $DEBUG == "1" ]] && echo -e "\n $(tput setaf 0)sf org list metadata-types -o ${org} | jq -r '.metadataObjects[].xmlName'$(tput sgr0)"
yesno " Retrieve $(tput setaf 4)${name}$(tput sgr0) metadata from $(tput setaf 1)${org}$(tput sgr0)?"
# exclude metadata types which are not supported
sf org list metadata-types -o ${org} \
| jq -r '.metadataObjects[].xmlName' \
| sed /ProcessFlowMigration/d \
| sed /ExperienceContainer/d \
| sed /EventRelayConfig/d \
| sed /RegisteredExternalService/d \
| sed /PortalDelegablePermissionSet/d \
| sed /WaveAnalyticAssetCollection/d \
| sort \
> "$names_list"
elif [[ $name == "" && $manifest == true ]]; then
yesno " Retrieve all metadata declared in $(tput setaf 4)manifest/package.xml$(tput sgr0) from $(tput setaf 1)${org}$(tput sgr0)?"
[[ $DEBUG == "1" ]] && echo -e "\n $(tput setaf 0)sf project retrieve start -o ${org} -x manifest/package.xml$(tput sgr0)\n"
sf project retrieve start -o "$org" -x manifest/package.xml > /dev/null
exit 0
else
names=$(echo ${name} | perl -pe "s/,/, /g" | perl -pe "s/(\w+)/$(tput setaf 4)\1$(tput sgr0)/g")
[[ $DEBUG == "1" ]] && echo -e "\n $(tput setaf 0)sf project retrieve start -o ${org} -m ${name//,/ -m }$(tput sgr0)"
yesno " Retrieve metadata ${names} from $(tput setaf 1)${org}$(tput sgr0)?"
echo ${name} | tr -d ' ' | tr ',' '\n' > "$names_list"
fi
total=$(cat $names_list | wc -l | tr -d ' ')
c=0
while read name; do
c=$((c+1))
echo -e "\n $(tput setaf 8)[${c}/${total}]$(tput sgr0) $(tput setaf 4)${name}$(tput sgr0)"
sf project retrieve start -o "$org" -m "$name" > /dev/null
done < <(cat "$names_list")