Skip to content

Orbit Package Manager for D backup

jacob-carlborg edited this page Jul 12, 2011 · 1 revision

This is the ideas I have for a package manager for D.

Orb - is responsible for downloading and installing D packages, deals with packages
Dake - is responsible for tracking and building dependencies, deals with single files

These tools can work individually on their own but work much better together. Note that Ruby (used for the config/spec files, see below) is embedded in the tools. There is no runtime dependency on Ruby.

Use case:

A user (developer) is developing application A that depends the libraries DWT and SQLite. Application A has a dakefile (config file for the dake tool) looking something like this:

# a.dakefile
flags << -L-lz -Jresources # some build flags for the compiler
orb "dwt", "0.5.3"
orb "sqlite" # any version

To download and install the necessary dependencies the users runs:

orb install dwt -v 0.5.3 and orb install sqlite

Or simpler, using the dake tool:

dake orb install

The above command will read the .dakefile in the current directory and automatically install packages needed of the correct version. Then the user just runs dake build which will build the project and include the necessary imports paths and link with the necessary libraries.

Orb packages

An orb package is just a regular zip file with the ".orb" extension. It contains a folder with all the sources necessary to build that package. It also contains a file containing meta info, like which packages it depends on.

Versions

You can specify what version you want to use/install of an orb package in several ways, this example shows this using a dakefile:

# b.dakefile
orb "dwt", "0.5.3" # specifies an exact version
orb "sqlite" # uses the latest version
orb "orange", "> 0.0.1" # uses any version greater than "0.0.1", basically any comparsion operator is allowed here
orb "derelict, "~> 0.3.4" # uses any version above "0.3.4" that is "0.x.y", i.e. won't use any "1.x.y" version

It's recommended that all packages following this version scheme:

A version consist of three parts: major.minor.build.

Build is incremented when a implementation detail changes that doesn't affect the API. For example, an array is replaced with a linked list.

Minor is incremented when a non-braking API change is introduced. For example, a new function is added.

Major is incremented when an API braking change is introduced, For example, a function is removed.

If the above is followed then you can easily specify that you want to use the latest version of a package without braking your own code when a new version of the package is available. The syntax used for this is (in a dakefile):

orb "derelict, "~> 0.3.4"

Orbspec

Is an orb specification that's used to build an orb package. It looks like this:

# orange.orbspec
# name "orange" # inferred from the name of the orbspec
version "1.0.0"
author "Jacob Carlborg"
type :library
files << ["a.d", "b.di"] # an array of source files

To build a package of this specification the user just runs:

orb build orange

Which will create the orb package "orange.orb". The user can then upload the package to the central repository using orb upload orange. Instead of using an orbspec the user could just use a .dakefile (which already contains all the necessary information), like this:

dake orb build and then orb upload orange.

Central repository

The central repository is just a simple HTTP web server or a local directory. The web server stores all the packages and meta info. When the user installs a package it requires just one request to the server to get the meta info, the tool then figures out what other packages the package to be installed depends on and downloads them if necessary.

SCM integration

If a repository at github, bitbucket, dsource or similar has a .orbspec file in the root directory this repository can be used as an orb package, like this:

# a.dakefile
flags << -L-lz -Jresources # some build flags for the compiler
orb "dwt", :git => "git://github.com/jacob-carlborg/dwt.git"
orb "sqlite" # any version

Now running dake orb install, the tool will clone the git repository, read the dwt.specfile, build the library and then install it.

Specifying packages in D files

Instead of using a dakefile one could specify the orb packages in D files using pragmas (or similar):

// a.d
pragma(orb, "dwt", "0.5.3");
pragma(orb, "sqlite");

If the compiler knows about the "orb" pragma it could provide a flag "-orb" and when used will output all orb packages, including the version. Then the "dake" and/or the "orb" tool can use this information to install the necessary packages.

Spec and Config Files

The dakefile and the orbspec file is written in Ruby. Why?

  • Because I think it's on of the best language available to create good looking DSL's
  • When the files are written in a complete language you have great flexibility and can take full advantage of Ruby
  • There's no need to create a parser for a new config/spec format

Integration with DVM

I plan to integrate this with DVM (https://bitbucket.org/doob/dvm) as well. This will allow a different versions of DMD to have different packages installed, if possible the packages will be shared among the DMD versions.

Clone this wiki locally