We are going to talk a bit about how a small amount of scripting can improve your workflow. In this case our little script is for Windows Terminal.
Topics
- Overview
- Example
- Conclusion
Overview
Scripting is how you fine tune your workflow to your needs. Maybe you are always running the same commands, or maybe it’s a hassle to change between projects. In this example, I am going to use a real scenario that I had and how I addressed it with very little effort.
But I already have my own tools to optimize my flow and I love it how it is, then this is not for you. Keep up the great work!! The goal is just to expand what is possible in order for you to get more autonomous on improving your flow.
In this tutorial we will use powershell core and windows terminal, there are a million other tools, but these are what I am currently using in my work flow.
Important: Scripting is a double edged knife. It is there to improve your work flow and to abstract complexity, but there’s always a danger in abstracting complexity and losing control on the actions that you are doing. Also, be very mindful that you are using what exists and being more efficient, not trying to create a parallel solutions to problems everyone has. The goals is not create another “magic solution”.
Example
In my use case, I was tired of shifting between different local environments on my team. In my team, I have to boot the start the gui, the host, the message bus, a simulator application and an automation manager just to run the tests!!! 😩 Then, after all that I was always shifting between tabs on the console, because sometimes I was focusing on one component then on another. So I set about creating a workspace, that had to be predictable, easy to use and easy to switch between projects and I had very little time (no one gives you a sprint to improve your workflow, maybe they should 😜)
First I read the doc Windows Terminal. So, now I knew that splitting tabs and creating new tabs was super easy! Next step what do I actual care about, because that has to have a tab just for it. I work mostly with Connect IoT, so for sure the Automation Manager
deserves a tab, then the host, the rest I don’t care and doesn’t give that great logging anyhow.
Powershell Profile
Profiles are a powerful tool to add things that you want to always exist in the context of your shell. Specific functions or variables that you always want accessible The sky is the limit
.
Finding your profile, run a powershell console:
$PROFILE | Select-Object *
But I don’t have any:
if (!(Test-Path -Path $PROFILE)) {
New-Item -ItemType File -Path $PROFILE -Force
}
In the text editor of your choice, i.e notepad ++ open the profile and let’s start cracking.
Customizing the Profiler
First thing I did was starting with one project (let’s call it project X). I declared the paths that I thought were more or less constant as constants on the top of profile:
$env:REPOS = "C:\cmf\repos\DS\__PROJECT__"
$env:AM = "C:\Users\jroque\Downloads\ActiveTestManager"
$env:VF = "C:\cmf\repos\DS\Library\src\VirtualFactory"
$env:BIZ_LOCAL = "\LocalEnvironment\BusinessTier"
$env:MB_LOCAL = "\LocalEnvironment\MessageBusGateway"
$env:HTML_LOCAL = "\Features\Cmf.Custom.__PROJECT__\Cmf.Custom.__PROJECT__.HTML"
Then I set about creating a function:
Function StartProject($Root, $Project, $DB) {
wsl -- sudo service docker start
If (docker ps --filter 'expose=1433' --format '{{.ID}}') {
docker stop (docker ps --filter 'expose=1433' --format '{{.ID}}')
}
docker start $DB
Write-Host $env:REPOS
Write-Host $Root
Write-Host $env:REPOS.replace("__PROJECT__", $Root)
$Biz = Join-Path -Path $env:REPOS.replace("__PROJECT__", $Root) -ChildPath $env:BIZ_LOCAL;
$MB = Join-Path -Path $env:REPOS.replace("__PROJECT__", $Root) -ChildPath $env:MB_LOCAL;
$Html = Join-Path -Path $env:REPOS.replace("__PROJECT__", $Root) -ChildPath $env:HTML_LOCAL.replace("__PROJECT__", $Project);
$AM = Join-Path -Path $env:AM -ChildPath "\scripts";
wt --maximized --title "Local Env" -d $Biz pwsh -c .\Cmf.Foundation.Services.HostService.exe `; split-pane -d $Html pwsh -c ng serve `; split-pane -H -d $MB pwsh -c .\Cmf.MessageBus.Gateway.exe `; new-tab --title "VirtualFactory" -d $env:VF pwsh -c npm run start `; new-tab --title "Automation Manager" -d $AM pwsh -c .\StartConsole.bat
}
A function is something that if registered on the profile can then be executed after the shell is opened. My function has three parts, one just to find the paths of all the components I need to boot up and another to use the windows terminal CLI.
First I check if there is any docker container running that is occupying the default DB port. I am doing this as my components require the database to be up.
In the windows terminal CLI I am saying that I want launch a new terminal with the path to business and to execute the command .\Cmf.Foundation.Services.HostService.exe
. Then I want to split the pane in the path of Html and run ng serve
, the split the splitted panel horizontally in the path of the MessageBus and run .\Cmf.MessageBus.Gateway.exe
. Then I want a new tab for a simulator called Virtual Factory
and lastly another new tab for the automation manager.
I created a small function that the only thing that it does, is inform the user of what exists and asks for a choice. This function will orchestrate the project to start:
Function StartLocalEnv {
# Define menu options
$options = @{
'Active' = 'Active'
'Baseline' = 'Baseline'
}
Write-Host "Select one of the supported Local Envs:"
# Display menu to the user
foreach ($key in $options.Keys) {
Write-Host "$($options[$key])"
}
# Get user input
$choice = Read-Host "Select one of the options"
# Process user choice
if ($options.ContainsKey($choice)) {
Write-Host "You selected $($options[$choice])"
switch ($choice) {
"Active" {
StartProject "Active" "Active" "ACTIVE_v1-DB"
}
"Baseline" {
StartProject "Baseline" "Baseline" "Template_v2-DB"
}
default {
Write-Host "Invalid choice. Please select a valid option."
}
}
} else {
Write-Host "Invalid choice. Please select a valid option."
}
}
Now let’s see it work.
Notice also that it is resilient, I can kill the console and start it again and it will keep the same context.
Conclusion
I know what you’re thinking, but it’s still missing so much. The goal here is to show the sandbox, now you need to tweak it and do what works best for you.
Author
Hello, my name is Olivério Sousa ✌️
I am a TechLead at Deployment Services.
Skills: Tech Leading
Author
Hello 👏 , my name is João Roque ✌️
I’ve been working for some years at Critical Manufacturing. I split my time working in the IoT Team and working with the project’s teams. You can visit me at https://j-roque.com/ or check me at LinkedIn
Skills: Connect IoT / DevOps