The Salesforce CLI (command line interface) is the cornerstone of Salesforce development, and like any other tool, it evolves with time. This post is the second of a two-part blog series on sf
(v2), the new and improved Salesforce CLI. In Part 1, we took a look at what’s new with sf
(v2) and, in this final part, we’ll explore the new sf
-style commands and flag patterns and share how you can migrate from sfdx
-style commands and flags based on our experience with sample apps. While the migration may seem intimidating at first glance, we’ll share some tips on how to ease the transition.
Meet sf
-style commands
If you’ve been using the CLI for some time, you probably started noticing a number of warnings on the commands that you frequently use, such as this one:
These changes are the result of the ongoing work on the Salesforce CLI Unification that started several releases ago (more details in the first part of this series).
Since then, whenever you install the Salesforce CLI, you now get the two executables (sfdx
and sf
). You can use either of these executables as most commands are interoperable, but we recommend that you start using sf
in your daily work to prepare for the future.
Because sf
covers more than just core Platform development, it offers a new simplified command taxonomy that reflects a typical developer’s workflow rather than Salesforce brands, products, or features.
A practical example of this is the sf org create
command. With this new command, the intent is made clearer: you call the same command base with scratch
, sandbox
, shape
, snapshot
, or user
, whereas in sfdx
you had to use a mix of different commands (force:org:create
, force:user:create
) and flags (--type=scratch
or --type=sandbox
) for the same result.
Another neat feature of sf
is that it ships with more visual and interactive commands, such as the creation of orgs with the ability to resume long-running operations in case of time out.
Migrate to the sf
executable
Besides simply switching the name of the executable from sfdx
to sf
, there are a number of changes that apply to CLI commands when upgrading your projects. The Salesforce CLI documentation provides a good overview of these changes, but we’ll highlight the ones that impacted us during the upgrade of our sample apps.
Common sfdx
commands and their sf
equivalents
First of all, the force
topic has been removed from most commands, which is good news as it shortens commands. The other major change is that topics, commands, and subcommands, which were previously separated by colons as in sfdx force:org:list
, are now separated with spaces, such as in sf org list
.
Looking more closely at the commands that we use daily when working on sample apps, we applied the following changes:
Legacy sfdx Command | Equivalent sf Command | Migration Comments |
sfdx force:org:delete -p -u recipes |
sf org delete scratch -p -o recipes |
The scratch subcommand needs to be added.The target org flag changes from -u to -o . |
sfdx force:org:create -s -f config/project-scratch-def.json -d 30 -a recipes |
sf org create scratch -d -f config/project-scratch-def.json -y 30 -a recipes |
The scratch subcommand needs to be added.The “assign default org” flag changes from -s to -d .The scratch org duration flag changes from -d to -y . |
sfdx force:source:push |
sf project deploy start |
This is a significant change, but the new command works for all project formats (source or metadata). Previously, you needed distinct commands. |
sfdx force:user:permset:assign -n recipes |
sf org assign permset -n recipes |
The topic changes from user to org and the order of the sub commands changes. |
sfdx force:data:tree:import -p data/data-plan.json |
sf data import tree -p data/data-plan.json |
|
sfdx force:org:open -p lightning/n/Hello |
sf org open -p lightning/n/Hello |
|
sfdx force:apex:test:run -c -r human -w 20 |
sf apex test run -c -r human -w 20 |
If you’re looking for other commands, the CLI documentation provides a full list of sfdx commands with their sf equivalents. Whenever replacing a command, make sure you review its flags for changes, especially if you use the short-form (single character) flags (-o
instead of --target-org
for example). You can run any command with the -h
or --help
flag to get their description.
Automate some of the migration with regular expressions
ℹ️ Edit from July 27, 2023: instead of a regular expressions you can use a migration script as documented here.
ℹ️ Edit from August 3, 2023: you can refer to the sf-style command migration guide for additional tips.
When we looked into migrating our sample apps projects, we knew that we would need to automate some of the process as there were close to 1700 references to sfdx
in 200+ files. To get the most accurate results here, make sure you add a space after sfdx
in your search term and exclude the node_modules
folder from your search, like we did here:
Starting with a search is a good first step. It helps you realize that you’ll have to migrate your commands in a couple of places, such as:
- Continuous integration scripts
- Local development scripts
- Documentation
You can then go further by experimenting with a Regular Expression (RegEx) search and replace in VS Code. This approach is a quick way to kick off the migration. It works well for search, but it isn’t perfect for replacement as some commands require manual updates. In any case, always test the outcome of your changes before pushing them to production.
Start by running this RegEx search and replace:
Note the use of three capture groups enclosed by parentheses in the search expression and represented by dollar signs followed by a number in the replace expression. Capture groups allow you to dynamically retain certain values (words such as topics, commands, and subcommands in our case) while making changes in the rest of the line (replacing colon separators with spaces in our case).
If you’d like to learn more about this RegEx or others, I recommend that you check out regex101.com as it provides an explanation of the syntax and a playground for testing expressions.
Here’s an example of the input and output in VS Code of the above expression (don’t forget to activate RegEx mode as indicated by the red arrow):
You’ll note that this first round of search and replace isn’t perfect as you get some extra space characters in the replaced text. You can easily fix this by running a second RegEx search and replace operation like this:
Once you run this last RegEx, there are still a couple of manual changes that you’ll need to operate. As we saw earlier in the command equivalence table, here are the key things to keep in mind:
- Some commands use different topics and subcommands. For example,
sf user assign permset
is incorrect:user
needs to be replaced byorg
. - Some flags need to be changed. For example,
sf org create scratch -s -f config/project-scratch-def.json -d 30 -a recipes
is incorrect: the-d
flag needs to be replaced by-y
and-s
flag needs to be replaced by-d
.
Fortunately, most of these changes aren’t too hard to apply and you can migrate fairly quickly to the sf
-style commands. We’ll leave you with a GitHub diff view that summarizes all of the changes that were necessary to migrate one of our sample apps.
Closing words
That’s a wrap for this short overview of the migration from sfdx
-style commands to the sf
-style commands. You had a glimpse at the benefit of the sf
executable and its new syntax. We hope that you’ll benefit from our migration experience and our tips when upgrading your projects.
Resources
- Salesforce CLI Setup Guide
- Salesforce CLI Command Reference
- sf-style command migration guide
- Salesforce CLI GitHub repository for checking out the source code or the release notes, leaving feedback and, reporting issues
- A GitHub diff view showing how we migrated one of our sample apps
About the author
Philippe Ozil is a Principal Developer Advocate at Salesforce where he focuses on the Salesforce Platform. He writes technical content and speaks frequently at conferences. He is a full-stack developer and enjoys working on DevOps, robotics, and VR projects. Follow him on Twitter @PhilippeOzil or check his GitHub projects @pozil.