Set up a dotnet core development environment with VS Code, MacPorts, and Docker
June 26, 2020 Leave a comment
Install and configure MacPorts
While a package manager is not strictly necessary to get a dotnet core development environment up and running, it is extremely useful to have a single tool to update utilities rather than manually discovering the need to update and manually downloading them. It’s also useful to set up a consistent command line environment with Linux. You can use my step-by-step guide to set up MacPorts.
To sum up:
- Install MacPorts
- Set up paths in
/etc/paths
and/etc/manpaths
- Set up
/etc/shells
- Install Linux-flavor core tools
sudo port install bash bash-completion coreutils findutils grep gnutar gawk wget
- Set up
~/.bash_profile
and~/.bashrc
Install mono and mssql-tools
The intellisense engine for C# dotnet core projects in VSCode on Mac and Linux doesn’t use the dotnet core compilers, it uses mono
. Microsoft has also provided ports of the SQL Server tools, sqlcmd
and bcp
Visual Studio for Mac also depends on mono
. If you have and use Visual Studio for Mac, you don’t need to install mono here. On the other hand, if you have an abandoned installation of Visual Studio for Mac you may want to remove it and start over. I have instructions for uninstalling Visual Studio for Mac at the end of this document.
sudo port install mono mssql-tools
Install dotnet core SDK
MacPorts does not manage installs of the dotnet core SDKs, but Microsoft does offer scripts to install and uninstall. I created a simple shell script to combine these together to maintain the 2.1 and 3.1 LTS SDKs.
To sum up, install two scripts from Microsoft and one from me into /usr/local/bin
:
curl -sSL https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/uninstall/dotnet-uninstall-pkgs.sh \ | sudo tee /usr/local/bin/dotnet-uninstall-pkgs > /dev/null sudo chmod +x /usr/local/bin/dotnet-uninstall-pkgs curl -sSL https://dot.net/v1/dotnet-install.sh \ | sudo tee /usr/local/bin/dotnet-install > /dev/null chmod +x /usr/local/bin/dotnet-install curl -sSL https://gist.github.com/breiter/aef0c0acbeb24cabe0fa16c7ecfdb88c/raw/b4e9de4b20141b0a05aadd03d5842752104b1475/dotnet-upgrade-sdks.sh \ | sudo tee /usr/local/bin/dotnet-upgrade-sdks > /dev/null chmod +x /usr/local/bin/dotnet-upgrade-sdks
Once those three scripts are in place, you can install or upgrade the dotnet 2.1 LTS and dotnet 3.1 LTS SDKs to the latest versions. If you have previous versions of the dotnet SDKs installed, the script will remove them cleanly.
sudo dotnet-upgrade-sdks
After the script completes, you should have two dotnet core SDKs.
$ dotnet --list-sdks 2.1.804 [/usr/local/share/dotnet/sdk] 3.1.301 [/usr/local/share/dotnet/sdk]
Install dotnet global tools
The dotnet
command is extensible. Commands added to dotnet
are called “tools” which can be installed in a project or globally for your account. There are a large number of tools available, but two key ones are the dotnet-ef and libman tools.
The dotnet-ef tool is the Entity Framework core tool for generating and managing migrations. The libman tool is for managing javascript library packages in an aspnet core project as a replacement for bower which is becoming unmaintained and isn’t tied up with nodejs.
dotnet tool install --global dotnet-ef dotnet tool install --global libman
Unfortunately dotnet tool
doesn’t have any command for update-all, but it is straightforward to pipe output the list
command to the update
command.
#!/bin/sh | |
# list global tools installed | |
# select tool <PACKAGE_ID> | |
# execute `dotnet tool update --global <PACKAGE_ID>` | |
dotnet tool list --global | awk 'NR > 2 {print $1}' | xargs -L1 dotnet tool update --global |
curl -sSL https://gist.githubusercontent.com/breiter/ffef5d134e87667bd8bdd5c561b9641e/raw/f83700ed67de6765223376d17c9823f23d1ce502/dotnet-tool-update-all.sh \ | sudo tee /usr/local/bin/dotnet-tool-update-all > /dev/null
You can now ensure your global tools are current:
dotnet-tool-update-all
bash-completion for dotnet
You can set up tab completions for dotnet
In order for this to work you have to have installed bash-completion, which should have been part of your MacPorts setup.
sudo port install bash bash-completion
code ~/.bashrc
if [ -f /opt/local/etc/profile.d/bash_completion.sh ]; then . /opt/local/etc/profile.d/bash_completion.sh fi _dotnet_bash_complete() { local word=${COMP_WORDS[COMP_CWORD]} local completions completions="$(dotnet complete --position "${COMP_POINT}" "${COMP_LINE}" 2>/dev/null)" if [ $? -ne 0 ]; then completions="" fi COMPREPLY=( $(compgen -W "$completions" -- "$word") ) } #enable command-line completiong for dotnet complete -f -F _dotnet_bash_complete dotnet
Install VSCode
Download and install VSCode from code.visualstudio.com. Once you install it, VSCode is self-updating.
The first time you launch VSCode, you need to manually install the code
command.
cmd + shift + p
type “install code” and select the “Install ‘code’ command in PATH” option.
What this does is create a symbolic link to the code
command inside the app bundle for VSCode to /usr/local/bin/code
.
$ ls -l `which code` lrwxr-xr-x 1 breiter wheel 68 Jun 27 2017 /usr/local/bin/code -> '/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code'
Or alternatively, you could do this old-school by hand:
ln -s /usr/local/bin/code '/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code'
At this point, I would recommend that you install a handful of extensions to make C# and aspnet core intellisense and debugging work.
VSCode extensions you really need
# C# XML comments code --install-extension k--kato.docomment # CSS support in HTML (and Razor) documents code --install-extension ecmel.vscode-html-css # C# language and debugging support (from Microsoft) code --install-extension ms-dotnettools.csharp
Some additional nice VSCode extensions
# bookmarks code --install-extension alefragnani.Bookmarks # aligment code --install-extension annsk.alignment # gitlens code --install-extension eamodio.gitlens # Docker code --install-extension ms-azuretools.vscode-docker # SQL Tools (nice client for various DB engines) code --install-extension mtxr.sqltools # Spell check in code code --install-extension streetsidesoftware.code-spell-checker # syntax and intellisense for .csproj files code --install-extension tintoy.msbuild-project-tools
Install Azure Data Studio
Azure Data Studio is the open source, cross-platform, spiritual successor to Query Analyzer. It’s a dedicated SQL Server (and PostgreSQL) client based on a fork of VSCode that is much more lightweight than SQL Server Enterprise Studio. Download Azure Data Studio from GitHub
Recommended extensions:
- Admin Pack for SQL Server
- PostgreSQL
Install Docker for Mac
In order to run SQL Server on Mac, you need Docker for Mac. I also find it more convenient to run PostgreSQL in Docker than on the base OS. In addition, you need Docker to build and run Docker images and push them to a repository. VMWare Fusion 11.5.5 has implemented a dockerd
runtime and there are other virtualization methods to get Docker running on Mac but by far the most straightforward is Docker Desktop for Mac.
Docker Desktop for Mac integrates with the macOS Hypervisor.framework using an enhanced fork of the bhyve hypervisor from FreeBSD called (HyperKit)[https://github.com/moby/hyperkit] that maintained by Docker as part of the Moby project. It works very well.
Download and install the “stable” version from docker.com.
Install an HTTP protocol debugger
- Charles proxy is a cross-platform HTTP protocol debugger built on Java that works on Windows, macOS, and Linux.
- Proxyman is a new macOS native HTTP protocol debugger.
- Fiddler is the de facto standard free HTTP protocol debugger on Windows built on .NET Windows Forms. Telerik has a rebuilt “Fiddler Everywhere” that is rebuilt to be cross-platform in beta.
- mitmproxy is a command-line, open source HTTP debugger built on python. It works but is more difficult to use than the commercial ones above.
sudo port install py-mitmproxy
- Wireshark is the de facto standard TCP/IP protocol analyzer.
sudo port install wireshark3 +qt
I haven’t tried Proxyman or Fiddler Everywhere. I have used mitmproxy and I would recommend paying for one of the GUI options. I use Charles and Wireshark regularly.
Visual Diff/Merge
I confess that I have a bit of a collection of these tools going. My general purpose favorite is Beyond Compare from Scooter Software. I also have Kaleidoscope and Sublime Merge.
I use smerge
to browse git repos and to resolve merge conflicts in git. Sublime Merge is wicked fast, if somewhat inscrutable.
I use Kaleidoscope primarily for the git difftool
command because it loads a multi-file diff into a set of tabs rather whereas Beyond Compare will load each file in a window sequentially, popping a new code diff window after you close the previous one.
diff and merge settings from my global ~/.gitconfig
[diff] tool = Kaleidoscope [difftool] prompt=false [merge] tool = smerge [mergetool] prompt=false keepBackup = false [diff "tool.bc3"] trustExitCode = true [merge "tool.bc3"] trustExitCode = true [difftool "smerge"] cmd = smerge mergetool --no-wait \"$LOCAL\" \"$REMOTE\" -o \"$MERGED\" trustExitCode = true [mergetool "smerge"] cmd = smerge mergetool \"$BASE\" \"$LOCAL\" \"$REMOTE\" -o \"$MERGED\" trustExitCode = true [difftool "Kaleidoscope"] cmd = ksdiff --partial-changeset --relative-path \"$MERGED\" -- \"$LOCAL\" \"$REMOTE\" [mergetool "Kaleidoscope"] cmd = ksdiff --merge --output \"$MERGED\" --base \"$BASE\" -- \"$LOCAL\" --snapshot \"$REMOTE\" --snapshot trustExitCode = true
BONUS: Cloud service clients
AWS and Azure have CLI interfaces to automate actions respectively: aws
and az
. Both are based on python3.
Install AWS command-line client
sudo port install py-awscli
Edit ~/.bashrc
and add aws cli completions after initializing bash completion.
#enable command-line completion for aws complete -C aws_completer aws
Install Azure command-line client
For some reason, the Azure team is all in on Homebrew for macOS they are sitting on an open community request for a .pkg package and have closed a request to add MacPorts package.
The only viable option outside of Homebrew is to use a Docker container or their shell script installer for Linux.
The CLI requires the following software:
– Python 3.6.x, 3.7.x or 3.8.x.
– libffi
– OpenSSL 1.0.2
Make sure you have the pre-requisites.
$ port installed|egrep '^\s+(libffi|python3|openssl)' libffi @3.2.1_0 (active) openssl @1.1.1g_0 (active) python3_select @0.0_1 (active) python38 @3.8.3_0 (active)
Also, I’ve looked at the script and it assumes that GNU coreutils are in the path. You need to have set up a Linux-style environment with MacPorts with coreutils
in path replacing the BSD versions shipped from Apple for this to work. It might work if you ust have the md5sha1sum
package installed instead, but keep in mind this script was designed for Linux + GNU environment.
curl -L https://aka.ms/InstallAzureCli | bash
Follow the prompts. It should all work. The script from Microsoft will install or update az
.
I saved this as /usr/local/bin/install-azure-cli
.
curl -sSL https://gist.github.com/breiter/e436c0604b58a1f38be2329209405571/raw/d693886818d11bb1cade02637ababc1849925c6e/install-azure-cli.sh \ | sudo tee /usr/local/bin/install-azure-cli > /dev/null sudo chmod +x /usr/local/bin/install-azure-cli
BONUS: Configure postifx smtp relay
It should not strictly necessary, but I often find that it useful to have a local MTA that works. Follow my guide to set up postfix in macOS to accept mail on your local machine port 25 and relay it through a smart host such as SES, GMail, or Outlook.com.
BONUS: Clean uninstall of Visual Studio for Mac and Mono.framework
uninstall-vsmac script
Uninstall Visual Studio for Mac.
#!/bin/sh | |
# Uninstall Visual Studio for Mac | |
echo "Uninstalling Visual Studio for Mac..." | |
sudo rm -rf "/Applications/Visual Studio.app" | |
rm -rf ~/Library/Caches/VisualStudio | |
rm -rf ~/Library/Preferences/VisualStudio | |
rm -rf ~/Library/Preferences/Visual\ Studio | |
rm -rf ~/Library/Logs/VisualStudio | |
rm -rf ~/Library/VisualStudio | |
rm -rf ~/Library/Preferences/Xamarin/ | |
rm -rf ~/Library/Application\ Support/VisualStudio | |
rm -rf ~/Library/Application\ Support/VisualStudio/7.0/LocalInstall/Addins/ | |
# Uninstall Xamarin.Android | |
echo "Uninstalling Xamarin.Android..." | |
sudo rm -rf /Developer/MonoDroid | |
rm -rf ~/Library/MonoAndroid | |
sudo pkgutil --forget com.xamarin.android.pkg | |
sudo rm -rf /Library/Frameworks/Xamarin.Android.framework | |
# Uninstall Xamarin.iOS | |
echo "Uninstalling Xamarin.iOS..." | |
rm -rf ~/Library/MonoTouch | |
sudo rm -rf /Library/Frameworks/Xamarin.iOS.framework | |
sudo rm -rf /Developer/MonoTouch | |
sudo pkgutil --forget com.xamarin.monotouch.pkg | |
sudo pkgutil --forget com.xamarin.xamarin-ios-build-host.pkg | |
# Uninstall Xamarin.Mac | |
echo "Uninstalling Xamarin.Mac..." | |
sudo rm -rf /Library/Frameworks/Xamarin.Mac.framework | |
rm -rf ~/Library/Xamarin.Mac | |
# Uninstall Workbooks and Inspector | |
echo "Uninstalling Workbooks and Inspector..." | |
sudo /Library/Frameworks/Xamarin.Interactive.framework/Versions/Current/uninstall | |
# Uninstall the Visual Studio for Mac Installer | |
echo "Uninstalling the Visual Studio for Mac Installer..." | |
rm -rf ~/Library/Caches/XamarinInstaller/ | |
rm -rf ~/Library/Caches/VisualStudioInstaller/ | |
rm -rf ~/Library/Logs/XamarinInstaller/ | |
rm -rf ~/Library/Logs/VisualStudioInstaller/ | |
# Uninstall the Xamarin Profiler | |
echo "Uninstalling the Xamarin Profiler..." | |
sudo rm -rf "/Applications/Xamarin Profiler.app" | |
echo "Finished Uninstallation process." |
uninstall-mono script
Uninstall mono
installed by the .pkg Mono installer.
#!/bin/sh | |
sudo rm -rf /Library/Frameworks/Mono.framework | |
sudo pkgutil --forget com.xamarin.mono-MDK.pkg | |
sudo rm -rf /etc/paths.d/mono-commands |