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!
#!/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 (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, 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 and 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:
$ ./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:
$ 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.
dub build --build=release --single allthepythons.d
Thanks to Aravinda K on Reddit for pointing it out!
Viva la D!
Top comments (2)
Nice. I must say I forgot fub supports this so I've often created a entire fub project
You can do this in Swift using swift-sh: github.com/mxcl/swift-sh