There's no one OS that's best for all purposes, so I avoid tying my work to any one platform. Unfortunately for me, almost everything about computers is still platform-specific. The obvious case is applications: even though essentially every home computer can run x86 code, no common subset of APIs, ABIs, and executable formats have become standard. Even more disappointing is how platform-specific basic user-level operations are: the simplest computing tasks (copy a file, run a program, create an archive, etc.) are all platform-specific as well.
A common solution for scripted tasks is to use a build system. I won't pick on any particular build
system, but I haven't encountered any that make even basic things easy. Consider a simple task: copying a
file to an output directory. What I want to write is something like
copy source destination.
Instead, many systems still require platform-specific commands (e.g. choosing to invoke
xcopy from the build script), plus a hierarchy of rules to make the operation fit into a
None of these systems make my hobby work more enjoyable, as I simply want to run a sequence of operations, halting if any fail. Whether typing individual commands or scripting a massive server deployment, I don't want to manually translate commands for each platform. I'd rather have a simple interface with a fraction of the functionality, but have it be consistent everywhere I work.
Thankfully, the standard libraries provided with most modern languages provide this abstraction already; they're just not exposed in a simple shell/scripting manner. A very thin wrapper over these APIs makes for a fine scripting environment.
The first application I make in any language is a simple command runner —
commands it supports are unabashedly simple (
delete etc.), but they're
consistent on every platform. No need for build hierarchies, and no
files in each project root. Furthermore, the interpreter is written in the same language as all my other
code, so it's guaranteed to work on any platform my code can target, without a need to install python or
java just to run a script.
There's not much technically interesting here;
run simply reads lines of text and passes them to
the appropriate standard library function. This simplicity makes adding new commands trivial. In fact, I'd
bet it's faster to add
case "copy": std::fs::copy(...) than it is to search stackoverflow
for how to write build-system rules to copy a file in a platform-independent manner.
Overall, it's nothing special, but I encourage you to try skipping the usual suspects when setting up builds
for hobby work. It takes surprisingly little work, and maybe, together, we can prevent another
build.bat from coming into existence.
⌨771 l ⌨100 s ⌨135 ⏎ ␤ ⎙11 a.txt⏎ ␤demo⏎ ␤ ⌨884 c ⌨67 a ⌨151 t ⌨87 ⌨109 . ⌨52 / ⌨97 d ⌨124 e ⌨57 m ⌨52 o ⌨359 ⏎ ␤ ⎙18 copy a.txt b.txt⏎ ␤ ⌨1133 r ⌨92 u ⌨146 n ⌨77 ⌨223 . ⌨65 / ⌨77 d ⌨141 e ⌨75 m ⌨60 o ⌨394 ⏎ ␤ ⎙18 ⌨1021 l ⌨78 s ⌨209 ⏎ ␤ ⎙18 a.txt⏎ ␤b.txt⏎ ␤demo⏎ ␤ ␃