A C++ package manager that will take you to your happy place 🏝️
Clone or download
Latest commit 9107bfb Jan 23, 2019

README.md

Buckaroo

Buckaroo

The decentralized C++ package manager.

Why Buckaroo?

Package managers like Yarn and Cargo have shown how productive developers can be when they can easily integrate a large ecosystem of projects. Buckaroo fills this gap for C++.

The Buckaroo workflow looks like this:

# Create your project file
$ buckaroo init

# Install dependencies
$ buckaroo add github.com/buckaroo-pm/boost-thread@branch=master

# Run your code
$ buck run :my-app

Features

C++ has unique requirements, so Buckaroo is a highly sophisticated piece of software.

  • Pull dependencies directly from GitHub, BitBucket, GitLab, hosted Git and HTTP
  • Fully reproducible builds and dependency resolution
  • Completely decentralized - there is no central server or publishing process
  • Allows any build configuration (even on a package-by-package basis)
  • Private and public dependencies to avoid "dependency hell"
  • Multiple libraries per package, so tools like Lerna are unnecessary
  • Pull individual packages out of mono-repos
  • Full support for semantic versioning (but only when you want it!)
  • Live at head! Move fast by depending directly on Git branches, but in a controlled way
  • Blazing fast resolution using clever heuristics
  • Version equivalency checks to reduce dependency conflicts
  • TOML configuration files for convenient editing by computers and humans
  • Works offline (with a populated cache)
  • Enable Upgrade Bot to keep everything up-to-date with a single click

Key Commands

Init

$ buckaroo init

Create a Buckaroo manifest in the current working directory.

Resolve

$ buckaroo resolve

Generates a fresh lock-file from the existing manifest.

To resolve with an upgrading strategy:

$ buckaroo resolve --upgrade

Install

$ buckaroo install

Installs the packages as described in the current lock-file.

Add

$ buckaroo add <package>@<version>...

Adds the given package(s) to the current manifest, updates the lock-file and installs it to the packages folder.

If no satisfactory resolution can be found then nothing is changed.

Upgrade

$ buckaroo upgrade [ <package> ]

Upgrades the given package(s) to the highest version that meets the constraints in the manifest.

If no packages are specified, then all are upgraded.

Remove

$ buckaroo remove <package>...

Removes an existing package from the manifest, updates the lock-file and deletes it from the packages folder.

If no satisfactory resolution can be found then nothing is changed.

Version

$ buckaroo version

Displays the version of this installation of Buckaroo.

Installation

Portable (All Platforms)

Buckaroo is shipped as a self-contained executable, so all you need to do is download the bundle from the releases page.

For example:

$ wget https://github.com/LoopPerfect/buckaroo/releases/download/buckaroo-redux-alpha-6/buckaroo-linux -O buckaroo
$ chmod +x ./buckaroo
$ ./buckaroo

Buckaroo uses Buck as a packaging format, so to build packages you will also need to install that.

Quick Start

  1. Install Buckaroo and Buck
  2. Run $ buckaroo quickstart
  3. Run the generated app:
$ buck run :app
Parsing buck files: finished in 0.7 sec (100%)
Building: finished in 1.0 sec (100%) 6/6 jobs, 6 updated
  Total time: 1.9 sec
Hello, world.
  1. Add a dependency:
$ buckaroo add github.com/buckaroo-pm/ericniebler-range-v3@branch=master
  1. Now you can use range-v3. Update main.cpp to:
#include <iostream>
#include <vector>
#include <range/v3/all.hpp>

int main() {
  auto const xs = std::vector<int>({ 1, 2, 3, 4, 5 });
  auto const ys = xs
    | ranges::view::transform([](auto x) { return x * x; })
    | ranges::to_vector;

  for (auto const& i : ys) {
    std::cout << i << std::endl;
  }

  return 0;
}

🚨 WARNING

If your C++ compiler does not default to C++ 14, then you will need to add this to your .buckconfig file:

[cxx]
  cxxflags = -std=c++14

Version Constraints DSL

When adding a dependency on a package, you must specify a constraint on the version. Since Buckaroo can work directly on Git, this is a little different to other package managers:

  • v1, 1, 1.0.0, 1.0.0 take only semantic version 1.0.0
  • >= 1.2 take only semantic versions >= 1.2.0
  • ^1.2 works as in NPM
  • ~1.2 works as in NPM
  • branch=master take only commits on branch master
  • tag=some-tag take only commits at tag some-tag
  • revision=dc16c91af2519b6129a33bd6e1675ebf73739103 take only revision dc16c91...
  • any(branch=master tag=abc 1.2.3) take versions that satisfy at least one of:
    • branch=master
    • tag=abc
    • 1.2.3
  • all(branch=master branch=develop) take versions that satisfy all of:
    • branch=master
    • branch=develop
  • !tag=abc take any version that does not satisfy tag=abc

As you might expect, these building blocks can be combined to write complex expressions:

  • all(!branch=master any(tag=abc tag=def 1.0.0))
  • all(>=1.0.0 !any(1.0.0 1.3.4 revision=dc16c91af2519b6129a33bd6e1675ebf73739103))

Official Packages

Since Buckaroo works directly from Git, we don't know how many packages are in the wild!

However, we have a collection of official packages over at Buckaroo PM.

If you cannot find the package you need, create an issue over on the wishlist and we will take a look!

Creating a Package

Creating a Buckaroo package is really easy!

You will need to create a few files:

  • BUCK containing a build rule (example)
  • buckaroo.toml containing targets = [ "<some-build-rule>" ] (example)

Push these to GitHub.

Now, you can install your package as follows:

$ buckaroo add github.com/<org>/<project>@branch=master

You can also look at our demo package or the many official packages.

Buckaroo Macros

Buckaroo will install some macros for use in your build scripts. If you have used quickstart, then you do not need to set this up.

However, if you need something more custom, this is how they work:

# Load the macros
load('//:buckaroo_macros.bzl', 'buckaroo_cell', 'buckaroo_deps', 'buckaroo_deps_from_package')

# Or just load the one you need
# load('//:buckaroo_macros.bzl', 'buckaroo_deps')

# buckaroo_deps gives you all list of all dependencies in buckaroo.toml
# This is the function you will use most of the time.
all_deps = buckaroo_deps()
# [ 'buckaroo.github.buckaroo-pm.hello//:hello' ]

# buckaroo_cell gives you the cell name for a give package
hello_cell = buckaroo_cell('github.com/buckaroo-pm/hello')
# 'buckaroo.github.buckaroo-pm.hello'

# buckaroo_deps_from_package gives you all deps for a given package
# Unlike most package managers, Buckaroo supports multiple projects per package!
hello_deps = buckaroo_deps_from_package('github.com/buckaroo-pm/hello')
# [ 'buckaroo.github.buckaroo-pm.hello//:hello' ]

To .gitignore or not to .gitignore?

A general purpose .gitignore for Buckaroo projects is:

.buckd
buck-out
.buckconfig.local
.buckconfig.d
buckaroo
buckaroo_macros.bzl

You should always check-in you buckaroo.lock.toml!

This file gives you reproducible installations of your dependencies every time you build.