4 ms·
This may not be a popular opinion (or maybe it's the most popular opinion), but if I'm using pretty much any language for anything that is in development or in
by yebyen 9y ago
This may not be a popular opinion (or maybe it's the most popular opinion), but if I'm using pretty much any language for anything that is in development or in any way home-baked (so, it didn't itself come from a distro package)...
I always wind up setting up the runtime environment using some form of the "carefully, and by hand" strategy.
Every language that I use (and probably every language that I can think of) has one or more preferred, distro-agnostic ways to install the language SDK and runtimes on a per-user or per-app basis. Go has GOHOME and GOPATH. Ruby has RVM, chruby, rbenv, and bundler. Python has pip and virtualenv.
Pretty much all of these include some sort of 12factor-ish tools and best-practices advice like using a Gemfile for explicit dependencies and environment isolation.
For teams with a platform group or someone who is responsible to run upgrades, with custom apps that were developed for script or interpreted languages: this is also pretty much the only way to ensure that production apps are not automatically broken by some ham-handed apt upgrade, usually being done on a schedule according to protocol, with someone at the keyboard who has no knowledge of the specific applications running on the machine being upgraded.
We have channels for those folks to notify us of impending upgrades, but five times out of seven the timing couldn't be worse, or the notification wouldn't include specific notes about what packages will be changed, so we're left to our own "spidey-senses" and vigilance inside of dev environments to notice these issues before they hit prod...
More often than not though, the issue I've seen has been the reverse: developers would like to start their app with the newest release of the language runtime, to take advantage of the latest features as well as to minimize the pain of upgrading later, but the platform team prefers to use a Stable or Long-Term Support release that has an intolerably old version, and the devs wind up missing the new features and writing workarounds for the lowest common denominator (or worse, remaining ignorant on the pain or postponing the pain of upgrading until some unknown future date.)
- twic 9y agoIf you're lucky, this can be "carefully, but still automatically". Rust lets you specify an exact toolchain to download in a rust-toolchain file; rustup will then download the one you need. For a variety of JVM-based languages, SDKMAN! can install specific versions of the SDK and set them up in your shell; that makes it fairly easy to write build scripts which use a specific version. Where i work, we have packages in our oddball internal dependency management tool which contain the entire GCC toolchain, so i can make sure my C++ projects build with a consistent version. It would be great if tools like this existed for every language. Docker offers a semi-reasonable approach to this, too.
- yebyen 9y agoThe Docker approach is IMHO the most reasonable approach, but the fact is that "in a container" is still regarded as a bad word in many places. We're talking about containers but mostly still embargoed from using them for anything serious. I mostly work on Ruby with RVM, where you can specify the exact version of language runtime and every gem dependency in the Gemfile, or let most of the details be inferred by bundler into the Gemfile.lock, and your runtime environment will balk appropriately if it's apparently being asked to run with something other than what you've described there. It's not as concise as `rustup` but I feel like `rvm install ruby-{version}; bundle install` gets me about 97.5% of the way there, to "still automatically" as you've described, with the remaining 2.5% being the native extensions that may have those external library dependencies (which are not part of Ruby at all.)