A tool for developing Node.js and Python projects
dotrun
makes use of snap confinement to provide a predictable sandbox for running Node and Python projects.
Features:
- Make use of standard
package.json
script entrypoints:dotrun
runsyarn run start
within the snap confinementdotrun foo
runsyarn run foo
within the snap confinement
- Detect changes in
package.json
and only runyarn install
when needed - Detect changes in
requirements.txt
and only runpip3 install
when needed - Run scripts using environment variables from
.env
and.env.local
files - Keep python dependencies in
.venv
in the project folder for easy access
Usage
$ dotrun # Install dependencies and run the `start` script from package.json
$ dotrun clean # Delete `node_modules`, `.venv`, `.dotrun.json`, and run `yarn run clean`
$ dotrun install # Force install node and python dependencies
$ dotrun exec # Start a shell inside the dotrun environment
$ dotrun exec {command} # Run {command} inside the dotrun environment
$ dotrun {script-name} # Install dependencies and run `yarn run {script-name}`
$ dotrun -s {script} # Run {script} but skip installing dependencies
$ dotrun --env FOO=bar {script} # Run {script} with FOO environment variable
Installation
Ubuntu
sudo snap install dotrun
sudo snap connect dotrun:dot-npmrc
sudo snap connect dotrun:dot-yarnrc
Note: The dotrun:dot-npmrc
and dotrun:dot-yarnrc
plugs gives the snap access to read the ~/.npmrc
and ~/.yarnrc
files in your home directory. This is only necessary if you have these files on your system, but if they do exist, the snap will fail to run yarn
unless it's given access.
MacOS
On MacOS, dotrun
should be installed and run inside a multipass VM, using sudo snap install dotrun
as above. Any server running within the multipass VM will then be available at the VM's IP address, which can be obtained from multipass list
.
Given that file access over a virtual network share is incredibly slow in MacOS, it is recommended to keep your project files inside the multipass VM directly and then share them with your host system from there if you want to open them in a graphical editor.
See @hatched's guide for how to achieve this setup.
Converting existing projects
On the whole, our existing projects should run out of the box with:
dotrun build
dotrun serve
A caveat to this for our Python website projects is that dotrun
will only work with Gunicorn >= 20.0.0
. To achieve this, our projects should upgrade to using at least version 0.4.3
of flask-base.
Updating projects
To fully support it you should do the following:
- For Python projects, ensure Talisker is at
0.16.0
or greater inrequirements.txt
- Add
.dotrun.json
and.venv
to.gitignore
- Create a
start
script inpackage.json
to do everything needed to set up local development. E.g.:"start": "concurrently --raw 'yarn run watch' 'yarn run serve'"
- The above command makes use of concurrently - you might want to consider this
- Older versions of Gunicorn are incompatible with strict confinement so we need Gunicorn >= 20
- The update landed in Talisker but at the time of writing hasn't made it into a new version
- If there's no new version of Talisker, simply add
gunicorn==20.0.4
to the bottom ofrequirements.txt
These steps can be completed without effecting the old ./run
script, which should continue working.
However, once you're ready to completely switch over to dotrun
, simply go ahead and remove the run
script.
Testing
The test
folder contains a bunch of tests, written in Python, against the dotrun
binary, using example projects in the test/fixtures
folder.
These tests can be run against the current codebase in a couple of different ways:
Testing the python module
This is the quickest way to test the code, but it's not as complete as it won't find error that might relate to the snap confinement.
python3 -m venv .venv # Create a python environment for testing
source .venv/bin/activate
pip3 install -e . # Install the dotrun module as a python package
python3 -m unittest discover --start-directory tests # Run the tests against the installed python package
Testing the snap
To do a complete test, it's wise to build the snap from the current codebase and then test the snap itself.
If you have multipass installed, you can do this using multipass for confinement pretty simply:
scripts/test-snap-using-multipass
This runs the same tests in the tests
directory against an actual snap installed into multipass.
Automated tests of pull requests
The "PR" action builds the snap and runs the tests
, similar to the "multipass" solution above. This will run against every pull request.