Awesome
sfdc-cli
exiahuang/sfdc-cli is a sfdc development kit.
It is licensed under the Apache License 2.0
feature
- This is the command line app of exiahuang/SalesforceXyTools.
- Integrate with exiahuang/xysfdx, and run in vscode.
- use python3
install
install from pip
pip3 install sfdc-cli
install from git
git clone https://github.com/exiahuang/sfdc-cli
python3 setup.py install
Summary
command | description |
---|---|
sfdc project:init | init sfdc project |
sfdc meta:retrieve | retrieve metadata |
sfdc meta:template:apex:create | init apex from tempalte |
sfdc meta:template:trigger:create | init trigger from tempalte |
sfdc meta:template:page:create | init page(visualforce) from tempalte |
sfdc meta:template:component:create | init component(visualforce) from tempalte |
sfdc meta:new | create metadata in sfdc server |
sfdc meta:update | update metadata in sfdc server |
sfdc meta:update:force | force update metadata in sfdc server |
sfdc meta:delete | delete metadata in sfdc server |
sfdc meta:refresh | refresh metadata in sfdc server |
sfdc meta:attr | print metadata attribute |
sfdc meta:refresh:dir | refresh metadata dir from sfdc server |
sfdc packagexml:server | build all packagexml from server |
sfdc packagexml:local | scan local directory to build package.xml |
sfdc apex:execute | Executes anonymous Apex code |
sfdc apex:test:run | run apex testclass |
sfdc apex:test:coverage | get apex coverage |
sfdc sobject:list | list sobject |
sfdc sobject:fields:desc | describe sobject fields |
sfdc sobject:export:xlsx | export sfdc sobject as excel file |
sfdc sobject:data:create | insert sobject data from json data |
sfdc sobject:data:update | update sobject data from json data |
sfdc sobject:data:get | get sobject data from sfdc server |
sfdc sobject:data:delete | delete sobject data from sfdc server |
sfdc data:soql:query | soql query |
sfdc data:tooling:query | tooling query |
sfdc call:rest:api | call salesforce rest api |
sfdc coder:snippet:soql | soql snippet creator |
sfdc coder:apex:snippet:insert:data:from:soql | create apex code from soql query |
sfdc coder:apex:snippet:insert:ramdam:data | create insert sobject code, ramdam data |
sfdc coder:apex:testclass:generator | generator testclass from apex code |
sfdc coder:apex:page:generator | generator VisualForce/Controller/DTO/DAO Code from sobject |
sfdc coder:copy:aura | copy lightning |
sfdc coder:permission:build | create permission metadata |
sfdc folder:list | list folder |
sfdc download:attachment | download salesforce attachment |
sfdc ant:migration:tool | init Ant Migration Tool |
Usage
print help
sfdc -h
usage: sfdc [-h]
sfdc development kit v0.1.0
positional arguments:
ant:migration:tool see `ant:migration:tool -h`
apex:execute see `apex:execute -h`
apex:test:coverage see `apex:test:coverage -h`
apex:test:run see `apex:test:run -h`
call:rest:api see `call:rest:api -h`
coder:apex:page:generator
see `coder:apex:page:generator -h`
coder:apex:snippet:insert:data:from:soql
see `coder:apex:snippet:insert:data:from:soql -h`
coder:apex:snippet:insert:ramdam:data
see `coder:apex:snippet:insert:ramdam:data -h`
coder:apex:testclass:generator
see `coder:apex:testclass:generator -h`
coder:copy:aura see `coder:copy:aura -h`
coder:permission:build
see `coder:permission:build -h`
coder:permission:list
see `coder:permission:list -h`
coder:snippet:soql see `coder:snippet:soql -h`
data:soql:query see `data:soql:query -h`
data:tooling:query see `data:tooling:query -h`
download:attachment
see `download:attachment -h`
folder:list see `folder:list -h`
meta:attr see `meta:attr -h`
meta:cache see `meta:cache -h`
meta:delete see `meta:delete -h`
meta:new see `meta:new -h`
meta:refresh see `meta:refresh -h`
meta:refresh:aura see `meta:refresh:aura -h`
meta:refresh:dir see `meta:refresh:dir -h`
meta:retrieve see `meta:retrieve -h`
meta:template:apex see `meta:template:apex -h`
meta:template:component
see `meta:template:component -h`
meta:template:page see `meta:template:page -h`
meta:template:trigger
see `meta:template:trigger -h`
meta:update see `meta:update -h`
packagexml:local see `packagexml:local -h`
packagexml:server see `packagexml:server -h`
project:init see `project:init -h`
sobject:data:create
see `sobject:data:create -h`
sobject:data:delete
see `sobject:data:delete -h`
sobject:data:get see `sobject:data:get -h`
sobject:data:update
see `sobject:data:update -h`
sobject:export:xlsx
see `sobject:export:xlsx -h`
sobject:fields:desc
see `sobject:fields:desc -h`
sobject:list see `sobject:list -h`
tools:json:format json format
help see `help -h`
optional arguments:
-h, --help show this help message and exit
new project
# for product
sfdc project:init -d project/sfdc-project1 -u username -p password -t security_token -s src -v api_version
# for sandbox/stgfull
sfdc project:init -d project/sfdc-project1 -u username -p password -t security_token -s src -v api_version --sandbox
cd project/sfdc-project1
metadata retrieve
# retrieve zip file of all metadata
sfdc meta:retrieve -p . -d package_dir -n package.zip
# retrieve zip file of choice metadata : ApexClass ApexTrigger ApexPage
sfdc meta:retrieve -p . -d package_dir -n package1.zip -m ApexClass ApexTrigger ApexPage ApexComponent CustomObject
# retrieve metadata and unzip, source path: src
sfdc meta:retrieve -p . -d package_dir -n package2.zip -m ApexClass ApexTrigger ApexPage AuraDefinitionBundle LightningComponentBundle --unzip --delete_after_unzip
sfdc meta:retrieve -p . -d package_dir -n package2.zip -m CustomObject --unzip --delete_after_unzip
sfdc meta:retrieve -p . -d package_dir -n package2.zip -m PermissionSet --unzip --delete_after_unzip
metadata template
init apex class from template
sfdc meta:template:apex -n HelloApex --template ApexClass.cls
sfdc meta:template:apex -n HelloApexBatch --template BatchApexClass.cls
sfdc meta:template:apex -n HelloApexTest --template UnitTestApexClass.cls
sfdc meta:template:apex -n HelloApexBatchTest --template BDDUnitTestApexClass.cls
init trigger from template
sfdc meta:template:trigger -n HelloApexTrigger --sobject Opportunity --template ApexTrigger.trigger
sfdc meta:template:trigger -n HelloApexTriggerAllEvents --sobject Opportunity --template ApexTriggerAllEvents.trigger
sfdc meta:template:trigger -n HelloApexTriggerBulk --sobject Opportunity --template ApexTriggerBulk.trigger
init visualforce from template
sfdc meta:template:page -n HelloApexPage --template ApexPage.page
sfdc meta:template:page -n HelloHeaderPageBlock --template HeaderPageBlock.page
init visualforce component
sfdc meta:template:component -n HelloCmp
metadata new/update/refresh/delete
new metadata
sfdc meta:new -p . -s ./src/classes/HelloApex.cls
sfdc meta:new -p . -s ./src/classes/HelloApexBatch.cls
sfdc meta:new -p . -s ./src/classes/HelloApexTest.cls
sfdc meta:new -p . -s ./src/classes/HelloApexBatchTest.cls
sfdc meta:new -p . -s ./src/pages/HelloApexPage.page
sfdc meta:new -p . -s ./src/components/HelloCmp.component
sfdc meta:new -p . -s ./src/triggers/HelloApexTrigger.trigger --sobject Opportunity
sfdc meta:new -p . -s ./src/triggers/HelloApexTriggerAllEvents.trigger --sobject Opportunity
sfdc meta:new -p . -s ./src/triggers/HelloApexTriggerBulk.trigger --sobject Opportunity
update metadata
sfdc meta:update -p . -s ./src/classes/HelloApex.cls
sfdc meta:update -p . -s ./src/classes/HelloApexBatch.cls
sfdc meta:update -p . -s ./src/classes/HelloApexTest.cls
sfdc meta:update -p . -s ./src/classes/HelloApexBatchTest.cls
sfdc meta:update -p . -s ./src/pages/HelloApexPage.page
sfdc meta:update -p . -s ./src/components/HelloCmp.component
sfdc meta:update -p . -s ./src/triggers/HelloApexTrigger.trigger
sfdc meta:update -p . -s ./src/triggers/HelloApexTriggerAllEvents.trigger
sfdc meta:update -p . -s ./src/triggers/HelloApexTriggerBulk.trigger
metadata refresh
metadata refresh by filepath
# refresh apex/trigger/page/copmonent/ aura file
sfdc meta:refresh -p . -s src/classes/HelloApex.cls
sfdc meta:refresh -p . -s ./src/classes/HelloApex.cls
sfdc meta:refresh -p . -s ./src/classes/HelloApexBatch.cls
sfdc meta:refresh -p . -s ./src/aura/HelloWorld/HelloWorld.cmp
sfdc meta:refresh -p . -s ./src/aura/HelloWorld/HelloWorld.css
sfdc meta:refresh -p . -s ./src/aura/HelloWorld
metadata refresh by directory
support directorys, read more
# refresh directory, examples
sfdc meta:refresh:dir -p . -d ./src/classes
sfdc meta:refresh:dir -p . -d ./src/triggers
sfdc meta:refresh:dir -p . -d ./src/components
sfdc meta:refresh:dir -p . -d ./src/pages
sfdc meta:refresh:dir -p . -d ./src/layouts
sfdc meta:refresh:dir -p . -d ./src/lwc
sfdc meta:refresh:dir -p . -d ./src/aura
# refresh one aura componet
sfdc meta:refresh:aura -p . -s ./src/aura/HelloWorld
delete metadata
sfdc meta:delete -p . -s ./src/classes/HelloApex.cls
sfdc meta:delete -p . -s ./src/classes/HelloApexBatch.cls
sfdc meta:delete -p . -s ./src/classes/HelloApexTest.cls
sfdc meta:delete -p . -s ./src/classes/HelloApexBatchTest.cls
sfdc meta:delete -p . -s ./src/pages/HelloApexPage.page
sfdc meta:delete -p . -s ./src/components/HelloCmp.component
sfdc meta:delete -p . -s ./src/triggers/HelloApexTrigger.trigger
metadata attribute
sfdc meta:attr -p . -s ./src/classes/HelloApex.cls
package.xml
build from server
# build package in current directory, filename package.xml
sfdc packagexml:server
sfdc packagexml:server -p . -d . -n package.xml
build from local
scan directory and build package.xml
sfdc packagexml:local --scandir ./src --savedir . -n package.xml
sfdc apex
Executes anonymous Apex code
# create a apex code
mkdir ./tmp/
echo "System.debug('hello world');" > ./tmp/HelloApex.apex
# run the apex code
sfdc apex:execute -p . -s ./tmp/HelloApex.apex
# use pipe
cat ./tmp/HelloApex.apex | sfdc apex:execute -p .
run apex testclass
sfdc apex:test:run -p . -s ./src/classes/HelloApexTest.cls
sfdc apex:test:run -p . -s ./src/classes/HelloApexBatchTest.cls
get coverage
sfdc apex:test:coverage -p . -f ./log/apex_coverage.log
sobject
create sobject data
# insert a account
echo "{\"Name\":\"exiahuang\"}" | sfdc sobject:data:create -s Account
# use json_data_file to create sobject data
sfdc sobject:data:create -s Account --data $json_data_file_path
get sobject data
sfdc sobject:data:get -s Account --id $account_id
delete sobject data
sfdc sobject:data:delete -s Account --id $account_id
update sobject data
# update sobject data from pipe
echo "{\"Phone\":\"080-0000-0000\"}" | sfdc sobject:data:update -s Account --id $account_id
# update sobject data from json file
sfdc sobject:data:update -s Account --id $account_id --data $json_data_file_path
list sobject
cd $project_dir
# print in console
sfdc sobject:list
# save as markdown file
sfdc sobject:list > log/sobject.md
export sobject as xlsx file
cd $project_dir
sfdc sobject:export:xlsx -s log/sobject.xlsx
describe fields
sfdc sobject:fields:desc -s $sobject_name
data query
soql query
sfdc data:soql:query -s "SELECT id,name from USER limit 10"
tooling query
sfdc data:tooling:query -s "SELECT Id,Name FROM ApexClass limit 100"
call salesforce rest api
Get method
# call /services/data/v45.0/sobjects
sfdc call:rest:api -e /services/data/v45.0/sobjects
# call /services/data/v45.0/sobjects/Account
sfdc call:rest:api -e /services/data/v45.0/sobjects/Account
sfdc call:rest:api -e /services/data/v45.0/sobjects/Opportunity
use file as params
echo '{"q": "Select Id, Name From ApexClass Limit 3"}' > tmp/sf_rest_test.json
sfdc call:rest:api -m GET -e /services/data/v45.0/tooling/query --use_params --params tmp/sf_rest_test.json
use pipe to call rest api
example : query ApexCodeCoverage
# example1 : query ApexCodeCoverage
echo '{"q": "SELECT Id, ApexTestClassId, TestMethodName, ApexClassorTriggerId, NumLinesCovered, NumLinesUncovered, Coverage FROM ApexCodeCoverage"}' | sfdc call:rest:api -m GET -e /services/data/v45.0/tooling/query --use_params
# example1 : query ApexClass
echo '{"q": "Select Id, Name From ApexClass Limit 3"}' | sfdc call:rest:api -m GET -e /services/data/v45.0/tooling/query --use_params
code creator
create soql
#
sfdc coder:snippet:soql -s $sobject_name --custom_field_only --updateable_field_only --include_comment --include_relationship
#
sfdc coder:snippet:soql -s Account --custom_field_only --updateable_field_only --include_comment --include_relationship
insert sobject data code snippet from soql
sfdc coder:apex:snippet:insert:data:from:soql -s $soql
sfdc coder:apex:snippet:insert:data:from:soql -s "SELECT name, firstname, lastname FROM Account LIMIT 2"
insert sobject data code snippet
sfdc coder:apex:snippet:insert:ramdam:data -s $sobject_name --all_fields
sfdc coder:apex:snippet:insert:ramdam:data -s Account --all_fields
generator testclass from apex
sfdc coder:apex:testclass:generator -f $apex_code_file_path
generator VisualForce/Controller/DTO/DAO Code from sobject
sfdc coder:apex:page:generator --sobject $sobject_name --savedir tmp/mycode/src --custom_field_only --include_validate
copy lightning
sfdc coder:copy:aura -f $from_lightning_path -t $to_lightning_path
sfdc coder:copy:aura -f /app/project/sfdc-project1/src/aura/HelloWorld -t /app/project/sfdc-project1/src/aura/HelloWorld1
create permission metadata
retrieve sobject metadata first
# retrieve sobject metadata
sfdc meta:retrieve -p . -d package_dir -n package2.zip -m CustomObject --unzip --delete_after_unzip
# or use meta:refresh:dir
sfdc meta:refresh:dir -p . -d ./src/objects
create permission from sobject metadata
# include sobject permission and all fields permission
sfdc coder:permission:build --sobject_dir ./src/objects --savefile ./src/permissionsets/dev_permission.permissionset --include_all_sobject_permission
# fieldPermissions
sfdc coder:permission:build --sobject_dir ./src/objects --savefile ./src/permissionsets/dev_permission.permissionset --fields Account.custom_field1 Account.custom_field2 Opportunity.custom_field1
list fields from sobject metadata directory
# list fields
sfdc coder:permission:list -t fields --sobject_dir ./src/objects
sfdc coder:permission:list -t fields --sobject_dir ./src/objects | grep Account
list sobject from sobject metadata directory
# list sobject
sfdc coder:permission:list -t sobject --sobject_dir ./src/objects
salesforce folder
# report folder
sfdc folder:list -n ReportFolder
# email folder
sfdc folder:list -n EmailTemplate
download salesforce attachment
download salesforce attachment(ContentVersion):
- max limit size: 2000
- default filename template:
{Id}_{Title}_v{VersionNumber}.{FileExtension}
sfdc download:attachment --savedir tmp/download --filename "{Title}_v{VersionNumber}.{FileExtension}" --limit 2000
Ant Migration Tool
init Ant Migration Tool
sfdc ant:migration:tool
# or
sfdc ant:migration:tool -p .
tools
json format
cat $json_file_path | sfdc tools:json:format
sfdc tools:json:format -i $json_file_path
For developer
Set up docker
# for windows user
docker run --rm -it -v %cd%:/app -w=/app -e TZ=Asia/Tokyo --name sfdc-cli_developer_1 python:3.8 bash
# for linux/mac
docker run --rm -it -v `pwd`:/app -w=/app -e TZ=Asia/Tokyo --name sfdc-cli_developer_1 python:3.8 bash
# git clone
git clone https://github.com/exiahuang/sfdc-cli
# setup
cd sfdc-cli
pip3 install -r requirement.dev.txt
python3 -m sfdc_cli.cli
alias sfdc="python3 -m sfdc_cli.cli"
export PYTHONPATH="/app/sfdc-cli:$PYTHONPATH"
sfdc -h
# remove commmand
unalias sfdc
remove pycache
### use find
find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
### use py3clean
py3clean .
Run test case.
new project
python3 -m unittest tests.test_project
init from template
python3 -m unittest tests.test_metadata_template
sfdc metadata api
# new apex/trigger/page/component template
python3 -m unittest tests.test_metadata_template
# metadata api: new metadata
python3 -m unittest tests.test_metadata_api.MetadataApiNewMetaTestCase.test_metadata_new
# metadata api: reload cache
python3 -m unittest tests.test_metadata_api.MetadataApiNewMetaTestCase.test_metadata_cache
# metadata api: update metadata
python3 -m unittest tests.test_metadata_api.MetadataApiUpdateTestCase.test_metadata_update
# metadata api: update aura metadata
python3 -m unittest tests.test_metadata_api.MetadataApiUpdateTestCase.test_metadata_update_arua
# metadata api: refresh metadata
python3 -m unittest tests.test_metadata_api.MetadataApiRefreshTestCase
# metadata api: refresh aura metadata
python3 -m unittest tests.test_metadata_api.MetadataApiRefreshAuraTestCase
# metadata api: print attr
python3 -m unittest tests.test_metadata_api.MetadataApiAttrTestCase
# delete metadata
python3 -m unittest tests.test_metadata_api.MetadataApiDeleteTestCase
# test delete aura
python3 -m unittest tests.test_metadata_api.MetadataApiDeleteTestCase.test_metadata_delete_arua
# run testclass
python3 -m unittest tests.test_testclass.TestclassTestCase.test_run_test
# run retrieve apex coverage
python3 -m unittest tests.test_testclass.TestclassTestCase.test_retrieve_apex_coverage
# retrieve zip
python3 -m unittest tests.test_metadata_api.RetrieveApiTestCase
# package xml : retrieve from server
python3 -m unittest tests.test_package_xml.PackageXmlTestCase.test_package_xml_from_server
# package xml : build from local
python3 -m unittest tests.test_package_xml.PackageXmlTestCase.test_package_xml_from_dir
# open in browser
python3 -m unittest tests.test_browser.BrowserTestCase.test_open_src
python3 -m unittest tests.test_browser.BrowserTestCase.test_open_aura
# open in browser : open sobject
python3 -m unittest tests.test_browser.BrowserTestCase.test_open_account_sobject
python3 -m unittest tests.test_browser.BrowserTestCase.test_open_opp_sobject
sfdc file attribute
# file attr
# file attr
python3 -m unittest tests.test_metadata_api.FileAttrTestCase
result:
{
"name": "MyApexController",
"file_path": "project/sfdc-projcet1/src/classes",
"file_name": "MyApexController.cls",
"dir": "classes",
"p_dir": "src",
"extension": "cls",
"metadata_type": "ApexClass",
"metadata_folder": "classes",
"metadata_sub_folder": "",
"is_sfdc_file": true,
"is_src": true,
"is_lux": false,
"is_lux_root": false,
"is_lwc": false,
"is_lwc_root": false,
"lux_type": "",
"lux_name": "",
"file_key": "classes/MyApexController.cls"
}
{
"name": "HelloWorld",
"file_path": "project/sfdc-projcet1/src/aura/HelloWorld",
"file_name": "HelloWorld.cmp",
"dir": "HelloWorld",
"p_dir": "aura",
"extension": "cmp",
"metadata_type": "AuraDefinition",
"metadata_folder": "aura",
"metadata_sub_folder": "HelloWorld",
"is_sfdc_file": true,
"is_src": false,
"is_lux": true,
"is_lux_root": false,
"is_lwc": false,
"is_lwc_root": false,
"lux_type": "COMPONENT",
"lux_name": "HelloWorld",
"file_key": "aura/HelloWorld/HelloWorld.cmp"
}
package
python3 setup.py sdist
python3 setup.py bdist_wininst
py2exe build windows exe
py -3.4 -m venv .py34
.py34\Scripts\activate.bat
# python -m pip install --upgrade pip
pip install py2exe setuptools
pip install requests XlsxWriter
python -V
python setup.py py2exe