You don't need no stinking projects [dub version]
Tags: dlang, d
Published: 2018-02-16 20:03:16

---
title: You don't need no stinking projects [dub version]
published: true
tags: dlang, d
description: Demonstrate the use of third party library dependency in a single-file D program that can be run as a script.
---

Let's say you want to build an application that you know will fit in a single file. Many of the scripting/automation programs fall in this category. However, the program depends on a third-party library. You think you may need to setup a "project", and you start thinking "maybe I can just use Python for this". But then still you are left with the task of (globally) installing the package using pip or creating a `virtualenv`. And if you have to "ship" this program, you are left with no choice but to ship with a dependency management tool (ie., `requirements.txt` or a `Pipfile`). With D, (specifically `dub`), you can have your cake and eat it too.

Show me the code!

```d
#!/usr/bin/env dub
/+ dub.sdl:
    name "allthepythons"
    dependency "d-glob" version="~>0.3.0"
+/

import std.stdio : stdout;
import glob : glob;

void main () {
  foreach (entry ; glob("/usr/local/bin/python*")) {
    stdout.writefln("%s", entry);
  }
}
```

In the above program, you are using a third-party library called [glob-d](https://code.dlang.org/packages/d-glob) (you might argue, "with python, you don't have use a third-party library for this, hah!". Bear with me here, this is after all a made-up example!).


The `#!/usr/bin/env dub` hashbang tells the shell to use D's `dub` [package manager](https://code.dlang.org/getting_started), to run the code that follows.

The comment section enclosed in `/+ +/` is a special section meant for `dub`, that informs what this single-file package is called (`allthepythons`) and what dependencies it has (`d-glob`). Dub supports two data definition languages by default -- [json](https://code.dlang.org/package-format?lang=json) and [sdl](https://code.dlang.org/package-format?lang=sdl). I used `sdl` here, because it is easy on the eyes.

Rest of the code is easy to understand, that needs no special explanation.

Running the script is straight-forward:

```bash
$ ./allthepythons.d

/usr/local/bin/python2
/usr/local/bin/python3
... truncated ...
```

This is *excellent* for developing, testing and scripting. However, what if you need to deploy a binary to a machine that a) does not have dub installed? and/or b) does not have an internet connection to automatically download packages from the internet? (for say, security considerations). Converting the above file to a binary is easy-peasy:

```bash
$ dub build --single allthepythons.d
Performing "debug" build using dmd for x86_64.
d-glob 0.3.0: target for configuration "default" is up to date.
allthepythons ~master: building configuration "application"...
Linking...
To force a rebuild of up-to-date targets, run again with --force.

```

You will end up with a binary named `allthepythons` that can then be deployed easily.


Note: In order to produce a "release" binary, add `--build=release` to the `dub build` command.

```bash
dub build --build=release --single allthepythons.d
```

Thanks to [Aravinda K](https://www.reddit.com/user/aravindavk) on Reddit for pointing it out!


*Viva la D!*

[source code on gist.github.com](https://gist.github.com/btbytes/608a52b705b403df73c13bfe2a8ca718)