I recently started playing with a tool called Yeoman — it excited me to see that I can automate certain tasks on my file system, but also integrate with other common CLI (Command Line Interface) web tools.
Being a fan of SFDX — Salesforce Developer Experience CLI tool for managing your salesforce project, I decided to automate a few of my repetitive tasks for any custom feature I would develop on the Salesforce Lightning platform.
My Goals were mainly to reduce some manual repetitive tasks between the different projects I’m working on. In addition, I wanted to have some extra configuration steps that would allow me to leverage the SFDX commands more than I was doing before and to add some more flavour to the process.
Maybe some readers are like me, but every time I needed to use an SFDX command, I found myself either typing
—-help as part of my command or going first to the commands docs site.
sfdx --help: will show an example command usage, all available options, commands and related topics.
sfdx force:doc:commands:display: will show all sfdx commands
Once there, spending some time looking for the right command path and then starting to type flag by flag (options) based on my needs for every step and for every given project… it takes some time and some mistakes are made on this journey.
Ahhhh..🤦♂️ 🤧 … quickly
ctrl c to abort !!
So later on.. I started to remember some of the basic commands with some pre-defined flags, but still some commands are pretty long and my memory kept on failing me.
I guess some creativity also comes from being a bit of a lazy developer and a freak of automation, but making things more efficient is also part of my day to day job so I was trying to find a better way.
This led me to explore a bit more of what I can achieve with some old school terminal tricks and maybe doing it in a much simpler and shorter routine or essentially to make this workflow a bit more efficient.
Source a Bash file:
Cool trick I find really useful is that I can create a .bash_profile file in my project and source it — Inside I will write a few scripts and aliases for my commands for this specific project or may store a few common generic aliases across all my projects in
~.bash_profile. (will store the file in
~/Users/<username>/.bash_profile and not in the specific project folder)
touch .bash_profile: This will create your bash file inside your current folder so you can add your alias and functions.
source .bash_profile: This command will use this file as a source for your bash scripts instead of the ~root bash file.
This will allow to make the commands shorter and much easier for me to use or remember.
Those aliases can also be joined by using
&& or written as a function.
Bash scripts are powerful and really helpful if you really want to automate the whole process into a single liner command.
Shell/Bash syntax was a bit weird for me at first, but after a few plays you kinda get the hang of it.
The only thing is that when I was trying to achieve a bit more complex logic and a bit more friendly interface I found myself looking further for other solutions.
That’s where Yeoman came to the rescue…
Yeoman helps you to kickstart new projects, prescribing best practices and tools to help you stay productive.
Without going into the documentation too deeply, Yeoman brings together 3 powerful concepts :
- yo scaffolding tool — Scaffolds out a new application, writing your build configuration files etc.
- A build system — Common node.js plugins like grunt or gulp are in use and they can help you build, preview and test your code.
- node package manager (npm) — which helps you install common code dependencies.
This is done using yeoman generators — which are available and published as npm packages themselves and provide a wizard like process that runs in your Terminal.
I quickly figured out that in order to build your own tailored workflow, you need to create your own generator. You can do so by using the Generator for generator .
Generators are yeoman ‘plugins’ that act as the building blocks to create your workflow.
- Assuming you have SFDX but if not —
npm install sfdx-cli --global
- Install yeoman :
npm install -g yo
- Install Generator :
npm install -g yo generator-generator
- Run your first
Once done answering all questions, your new custom generator will be created and ready to be configured to your needs.
The initial skeleton generator holds multiple dependencies, that honestly I did not invest too much time to understand them all.
Step into your package.json file and review what you wish to leave or change. In order to make this example simple I removed and changed a few of the dependencies to what I will use in my examples.
My chosen dependencies (third party npm libraries), will give a bit more spark to your generator :
- chalk — Adds colourful text for input/output on the screen.
- shelljs — Unix shell commands on top of the Node.js API…
- ora — Provides an elegant terminal spinner.
- yosay — Ascii image to give some credit to yeoman this one is “Like cowsay, but less cow”.
Worth mentioning on this note, a few of those already available inside Yeoman :
- Inquirer.js — Provides the command line interface and allows you to validate and conditionally prompt questions
- mem-fs — Simple way of accessing your file-system
After setting your dependencies and project description — you are ready to start configuring your workflow. Step inside
I would suggest at this point to read a bit about the running context, which is described with the run loop — ‘ a queue system with priority support ‘ — a fancy way for saying that when
yo is invoked, the methods will run one after the other by their name and in their designed sequence.
The gist is that — those are the available priorities (in running order) — I included some of my notes beside them as I was reading through the official yeoman documentation:
initializing- This is where the process starts (after your constructor builds the app). This step can be useful to check for project status and for example to get your SFDX org list or use certain schema definition commands to extract as defaults for your follow up questions or tasks.
prompting- Where you prompt users for options (where you’d call
this.prompt()) — Try to add some dynamic options to complement the standard SFDX commands, validate user inputs and conditionally display questions that will drive your workflow.
configuring- Saving configurations and configure the project — That’s where we can also set or create any SFDX configuration settings, User definitions etc.
default- If the method name doesn’t match a priority, it will be pushed to this group.
writing- This is where we write files. We can use ES6 templates to copy and populate them with User inputs. This can be really helpful for any project, org, metadata or data definition file we wish to work with.
conflicts- Where conflicts are handled (used internally).
install- Where installations are run — We can use this step to install any app-exchange packages as dependencies or to clone Git repositories.
end- Called last, cleanup, say good bye, etc…
Ok makes sense… In my basic examples I don’t really use the entire sequence, it’s optional, but it’s really useful to master this priority and use it wisely while you start configuring the different steps of your workflow.
Once you start connecting sub-generators to each other — when invoked, each sub-generator will start its own run loop inside the parent priority context. It can get confusing at times, but you can always control your function call order using the
Let’s see some examples
hello world generator with
yoto say ‘Hello world’ , use chalk to give some colour and utilize shelljs to invoke SFDX command.
hello world example, but now let’s make it smarter :
When initializing with SFDX org list with the
--jsonparameter, we can do some smart stuff in background like Write and Read all connected orgs on your dev hub, which allows us to assign them as defaults to our workflow or simply show/hide some questions.
The below example will also add a spinner animation — Useful trick when starting to invoke commands and performing some operations in file system —
ora add some nice frames to spinners and allow messages to show the current stage of the process.
Prompt the user for questions:
Start to look at the optional flags of the commands as questions and have visibility logic around when to display or how to validate each question.
Implement visibility logic into your workflow questions:
Possible Input type values:
input, number, confirm, list, rawlist, expand, checkbox, password , editor.
Copy Template and write files with user inputs:
This example shows a workflow where we generate a new scratch org, but we use a new definition file that was created out of a template which is populated with the User answers as input parameters.
Template of a scratch org definition:
This will allow you to add some extra functionality on top of the Standard SFDX command by adding the ability to specify the Features and Settings that should be available in your scratch org, while you are still running a single command.
Running SFDX Commands with shelljs
Composing a workflow with sub-generators:
This is where the magic begins… Orchestrate and connect your sub-generators together to support a stream lined workflow.
composeWithaccepts a generator path and an optional object for input parameters.
These snippets should give you a quick overview of how to configure your generator methods and integrate with SFDX commands to do the work for you on the different parts of the generator lifecycle.
The objectives here were to find a way to automate my day to day workflows — This tool definitely proved itself worthy for many of the tasks I would perform as a developer.
I hope to follow up in the future with a few more articles that will show some more real examples of how to leverage Yeoman to build more automation into the day to day developer workflows.
For now, you can check out my sample repository which will help you create your SFDX project and manage your org using a Yeoman generator.
This Generator is stored locally — so simply clone the repository follow the instruction on github and type one word :
yo dx— Main menu
yo dx:project—Create new project
yo dx:org—Create new scratch org
yo dx:manage— Few more org commands
Yo u are ready to Start
yo your workflows !