Turret: Multi-Language Package Manager

The Problem

How do you combine multiple components into a larger project?

I often need to include a few standalone projects in a new website. For example, I might want to include my PHP framework, an image uploading tool, and a CSS library.

The naive approach would be to manually copy each component into the new project. Let's imagine for a moment that we did that.

Now let's flash forward a few months and pretend that we've added some exciting new features to a component. We could, once again, manually copy over the files and carry over any customizations made for this specific site.

Now imagine doing that for several components on several websites. It might take hours and it leaves a lot of room for human error.

There's got to be a better way!

In modern software development, we prefer using dependency managers to automate this kind of work. For example, the npm package manager can manage JavaScript projects. Composer handles the PHP development space. And Bundler can manage the gems in a Ruby project.

Unfortunately, each of these is designed to work with one specific language. Also, each of these managers requires that our dependency be included in their list of available packages.

What if our project is using multiple languages? What if our language doesn't have a package manager? What if the dependencies we need are only available on our local server?

This what Turret aims to address.

Using turret

Turret can be installed in a directory by copying the script from github:

$ wget https://raw.githubusercontent.com/moonbench/turret/master/trt.sh


Start a new project

Initialize a new project workspace:

$ ./trt.sh -i

This will create a .trt config file and two diretories: dev and stable. The intention being that dev will act as our primary workspace and stable will always contain the most recent clean snapshot.

Add dependencies

Dependencies can be added to our project by editing .trt/repos. Add a line for each project you want included:

/home/username/path/to/some/project/stable
/home/username/path/to/another/project/stable

This will copy the files of the dependency into the root of our dev directory.

Alternatively, we can instruct Turret to copy the files to a different location with:

/home/username/path/to/some/project/stable > foo/bar

This will copy the files into dev/foo/bar instead of dev.

Upgrade dependencies

Once our dependencies have been added we can upgrade them at anytime with:

$ ./trt.sh -u

This will first ensure that we have a safe rollback point. Then it will copy in the latest versions of each dependency.

If we just want to upgrade a specific dependency we can use:

$ ./trt.sh -u name

Project snapshots

Turret can create snapshots to make upgrades less scary.

Stable Version

The stable version is a copy of the code that isn't affected by work in the dev directory. It's a place where we can keep the latest, working, version of the project. A stable version an be created or updated by running:

$ ./trt.sh -s

This will synchronize the current contents of the dev directory into the stable directory.

Archives

We can keep historical versions of the project too. These can be useful for regression testing or to provide legacy versions to other projects. An archive version can be made by running:

$ ./trt.sh -a

This will copy the current stable version into a new folder under the archives directory. By default it will be named with a datestamp. We can also manually specify the archive's name at the end of the command:

$ ./trt -a 1.0.0
Published: October 14, 2017

Categories: infrastructure