Show HN: We open sourced our new Mac developer setup script
github.com
github.com
The stuff that's specific to development -- go, node, npm, etc. -- sure that makes sense, but installing that stuff via brew is vastly inferior to versioning it as a dependency within your build system. And I'm not saying you have to use bazel or something. Pin your versions, install them by script in the context of your build tools and leave it at that.
I'd reckon the reason you don't see this sort of thing often is because it's not actually useful or necessary. I'd rather follow steps in a document somewhere so I can ignore the steps I don't care about and share steps I find useful.
It's like showing up to a job and them saying "hey we've preconfigured emacs for you."
I'm a professional and take pride in knowing my tools. I can set up my development environment myself. I use Nix where possible and tend to avoid homebrew. Half of these things I have in my dotfiles or nix configs already, as do most of my peers.
I'm sure others will find this useful, and there's certainly nothing harmful about this, but it's certainly not for me, and I'm certain there's a better way to go about handling all these things.
For sure! I can understand that. For people who don’t want to use the script, I also included a list of what is installed in the README. Experienced dev's can manually install and configure what they need.
We have many devs who are fresh out of university or used to windows, so not all are experts with the Linux/Mac command-line. This is helpful for them, and others who just want to start quick.
Update: clarifications
Removing an ideal opportunity to learn doesn't sound particularly helpful. In fact, it sounds like you want them to "get up to speed quickly" and "hit the ground running" rather than be onboarded in a way that makes them useful, long term members of the team.
This approach is practically the opposite of how I think you should treat a new graduate on your team. They're new to the company, the tools, the operating system, even to the world of just having a dev job in some cases. They need time to be able to learn how to work well. I get that you want to remove a barrier and make life easier, but overcoming that barrier yourself is useful, even if you need a bit of hand-holding to do it.
Whose idea was this? I can't help but think this is the work of a senior who doesn't want to mentor or help juniors, and they've automated their problem of being asked 'dumb' questions away. If someone brought this script to my company I would fight against its adoption.
Edit: I just saw this comment https://news.ycombinator.com/item?id=29535498. In your position I'd delete the script and work on updating your on-boarding documentation, because you're fixing the wrong problem, and also realise that 2 - 5 days to onboard in a new role is normal and perfectly acceptable. Just understanding a new codebase takes longer than that.
A script like this is also a reference, a known state, which is valuable, even necessary, all by itself regardless if you agree with what it does or the state it produces or the value of being forced to do it all wrong and discover and file off all the edges yourself over time.
Good god, that’s like wearing someone else’s dirty underwear.
If you're a BYOD place then sure, let people use their own tools, you have bigger fish to fry.
If you're the place where your auditors require you to deliver proof that all your developers have antivirus installed then it's a different story. The minute you need to take away local administration rights from developers, the value of a standard development environment is immense. No more complaints about not having local administration rights. Plus, the value of hey, my laptop just broke, I ran down to IT, they swapped me out, go back to my desk, log in, and bam, my environment is right like how I left it is huge.
Ultimately - professionals never blame their tools. The hammer handle might not have an ivory handle and tungsten head, but so what? This isn't what bottlenecks you in organizations. And if you really seethe at the thought of emacs being taken away from you, well, switch jobs. The vast majority of the engineering labor force doesn't even know what emacs is.
1) Say "I'm really sorry, but I cannot do my best work in this environment", and hand in their resignation.
2) Learn to work within the constraints given and find ways to be productive anyway.
3) Take on the responsibility of trying to work within the system and improve things.
4) Bitch and moan, get all passive aggressive, start working slower (to prove their point) and generally piss off their surroundings, spread negativity and tank morale.
The point is that you should always pick some combination of 1-3, rather than 4. However 4 is by far the easiest and makes most people feel better about themselves so that is the one they tend to go for. It is also by far the most unprofessional, and reflects rather badly on you.
Full disclosure: I may have done nr. 4 at some point in my career.
Option 1 is not always possible. Not everyone can just switch to another job at a whim, especially if that job fits in other categories quite well, e.g. good salary, very short commute, nice people.
Option 2 can be tried for a while, but if one knows he can't be as productive as he could have been given the choice of tools, motivation goes down quickly. I mean, why bother putting 10-50% more effort for the same output?
Option 3 is often unrealistic. Usually, the type of companies that doesn't give you a choice of choosing your tools is a company where trying to change something is almost impossible.
And we are left with Option 4. Except pissing of the surrounding, all other stuff is just what the company deserves. Also, no need to start working slower, that's what already happens because of the prescribed tools, and doing so intentionally is very bad, but as I said, also no need to put extra effort to compensate lost productivity.
I think this makes "is this worth using" an entirely different question.
OP's setup script is better than just a "here's your macbook, take some time to get your computer set up".
A tool like Nix is high-effort-high-reward. If everyone's familiar with Nix, it's surely better to use Nix than to use OP's setup script. If not, whether Nix is the better way to do things is arguable.
With Nix, you can programmatically describe an installation of packages (including how they're built). This then allows having multiple versions of the same package installed, easily patch (or vary build arguments) of package dependencies, an easy way to distribute or install these same sets of packages in whatever distribution of Linux (or on macOS), development shells which load the required build tools, a saner build language than Dockerfile's. With NixOS, the configuration of services can be managed from a single source.
I think for any particular task, it's more difficult to bother with Nix compared to just using some convenient solution. (e.g. using Dockerfiles to build Docker images, or using cloud-init to configure a VM setup). -- So, it's harder to say "is Nix better than <this> for <this problem>?".
Compared to other package managers: You could use Nix to install packages, in the same way you would with other package managers. An advantage to this is you'll get the same version of the package regardless of which distribution you use. (Whereas with, say, Ubuntu you might need to add a PPA to get versions as bleeding-edge as what Arch would offer).
Nix's tooling is also broader in scope:
e.g. with nix-shell, you can have a shell which has a Go-lang compiler (or whatever) in that shell, but without needing the Go-lang compiler installed on the computer. This is comparable to e.g. asdf, or to running your toolchain in a Docker container (like what VSCode Remote Containers offers). -- i.e. Nix can be useful for development.
NixOS takes the same Nix declarative language, and allows describing the configuration of the whole OS setup with it. Just as Terraform declares an orchestration of cloud infrastructure, NixOS allows declaring how the OS is setup. (Here, Nix is comparable to e.g. cloud-init or Ansible). -- i.e. Nix can be useful for deployment.
Even homebrew is a little too opinionated for me. If I could run some specific bits of Mac software on Linux I would never leave Ubuntu. apt is a joy to use by comparison to all this BS.
I rewrote the onboarding documentation of my team and asked myself if I should script the tooling installation. I came with the same conclusion and just gave a list of tools to absolutely install (with a suggestion of how to install it, but do as you please) and recommended tools and extensions (+ why they're cool). I think this approach is especially useful for newbies who don't necessarily know the tools or how to install them.
If anybody has an issue with their custom installation though, I redirect them to the onboarding recommendations.
But some people aren’t professionals. They may be hobbyists or people who just entered the field. And the barrier to entry is becoming higher and higher with the rising importance of devops. It’s very daunting to try to get into a new tech stack and follow the best practices without much guidance.
I had an intern building a Java project in minutes with zero prior exposure.
Vscode does practically everything out of the box and prompts you to install context appropriate plugins which do everything.
You should give your hires the respect they deserve and treat them like professionals letting them use their own tools. Just give them a mac and let them do their thing.
Give this script to a new hire and see if they run it without question or whether they actually read the script and pick and choose what they need or question what they don't understand.
This script helps new developers at my workplace setup their MacBook laptops quick, letting them hit the ground running.
Before this script, it could take 2-5 days to install and configure everything, as much of the knowledge needed was either scattered in old docs or passed down verbally from a few senior devs.
With this script, new developers can be ready in under 30 min.
I have tried to make this script simple and useful. You will want to customize the installation and configuration to match the tools and services you use at your company.
Note: it has not been tested on M1 Macs yet. I am still waiting on my M1 and will update when I receive it
There’s no need to chmod your script, just invoke it with sh.
https://justinmayer.com/posts/homebrew-python-is-not-for-you...
I tend to think somebody didn't do a .rb Formula which preserved this version dependency. It may be clumsy but it's fixable in brew as far as I understand it.
That it is. We still have a few projects running on legacy Google App Engine, and the teams working on those projects use the included Mac Python 2.
We are in the process of migrating everything to Go, so the python 2 dependency should be removed in the future.
[1] https://docs.docker.com/engine/reference/commandline/buildx/
My experience in running the odd docker container on a Mac has been that it was painfully slow compared to any Linux machine.
defaults write com.apple.finder ShowPathbar -bool true
This is handy. I could never figure out how to reliably use a Finder window to navigate to a specific directory so I resorted to running "open ." from the directory in the terminal.Moreover, I think I have more options to skip particular part / packages while also try to be idempotent as much as it can.
I found it highly amusing that we're taking similar approaches for a lot of things: a wrapper function for sudo and fetch, and OS detection (especially the appending WSL suffix part). Mine is not as idempotent as yours, and having a per-package definition is still in my TODO list, though.
I find myself constantly either in need of reinstalling the whole OS or setup my environment a lot, hence I need to make the setup flexible and various options to better reduce the time I spent manually install stuffs.
Using these scripts as a way to give "reproducible" build environments is just doomed.
a well loved and maintained ansible playbook for macs.
Just FYI
As mentioned in the comments, the script is supposed to cover fresh grads and Windows users with no prior Linux/macOS experience.
The experienced users having their own opinion about the configuration would still require time to find and configure company-specific conventions and settings they're not aware of. The common reaction is such opinionated scripts are avoided at any cost, so developers still spend time filtering the file(s) to find important bits. If the information is also in the documentation, it's ok - the script can be safely ignored. Otherwise, it can be annoying and leave a bad impression.
For the next version, I'd try to make it friendlier for both groups of users. I'd say being able to revisit what exactly is to be installed would enable more people, save time and energy. The experts would only get necessary business settings integrated (via the advanced mode), while beginners would have complete installation (via the basic mode). It was a pretty common approach with TUI installers back in the day.
Homebrew-wise, I'd replace separate brew commands with a Brewfile and 'brew bundle install'. It'd keep the package list isolated from the logic. Regarding the packages, I'd also put all version-sensitive software away from the direct Homebrew control. With programming languages, it'd be a version manager like 'asdf' and so on.
I haven't invested in a Nix configuration yet, since my small dotfiles repo works fine so far. There are obvious benefits, of course.
That said, relying on brew to set up the language runtimes is a sane option. I just don't think the script should go anywhere beyond that.
While developing it, I have run it a great number of times on my own computer (in addition to testing on clean MacOS install VMs) and it will only install what is missing. So, yep!
You might find it useful for a base for your own? up to you.
(Of course, the user will still have to get brew themselves most likely so the permissions are right, but everything else can be done on a system-wide level and be zero-touch for the end user.)
edit: Sorry if this sounded snarky, I didn't intend it to be. Everyone has to allocate resources somehow. If you ever have time for a weekend project, I'd look up the cloud version of JAMF ($3 per device per month) or Intune (approximately the same if you have Microsoft services). Couple days of work and you'll have a much easier end-user experience.
This script is also worth reviewing with colleagues, to avoid pitfalls and also as a way to share better techniques.
For one, I personally cannot trust the technical competence of a fellow developer if he/she cannot handle their setup him/herself. We're talking installing tools by clicking around, aren't we? The same argument holds true for a fellow plumber that has never worked with this pipe system in particular.
Second, there's much to discover by installing and setting up everything by oneself. It can give insights on how things are connected to each other tool wise which is the first step of getting familiar with a new environment in the first place anyways.
Not sure if you mean this literally, but I'd rather have a fellow developer who shows me an automated way to do (most of) this, meaning the devloper realized that switching to another machine would require figuring out and executing those same clicks again. It's like the discovery process you mention, but imo with deeper insight. Also because I've seen the other end of the 'oh I still need that thing let's point and click to install': co-workers needing multiple days to get their development environment setup. Or rather: thinking it's setup only to find out some days later the envoronment is so polluted only the correcct sequence of starting a shell and executing scripts leads to a build without errors.
Development domain names - some people used /etc/hosts, some people used pow, others used PassengerPane. For packages, a few people used Brew, some used MacPorts...
In the end we went with a standard setup where I implemented things like rvm (we had both Rails 2 and Rails 3 apps). And even created a CentOS setup script which was as similar as possible.
Sometimes the complexity is unavoidable - e.g. loading some large training data set or a complicated tool chain of some essential libraries - in which case you should automate away as much as possible in build scripts. Sometimes the setup complexity is due to poor maintenance - "we used Gulp 3 years ago, but switched to Webpack last year, and the frontend guys are trying out esbuild, but there's still stuff that's running under Webpack and we need Gulp for these couple old pages over there". Either way, there's no better way to crush the enthusiasm of a new hire than have them bogged down in your shitty install setup on their first day.
These setups are useful because:
- not everyone needs to start from scratch every time
- they share one’s known-how through their configuration
Even if I rarely use boilerplates and such, often they're good resources to see how a specific problem has been fixed.
Also if they're done well they lower the barrier of entry considerably. See create-react-app where you can start developing something serious in React without starting from an empty index.html and glue everything together.
The oldest commits on this script are 11 years old and nothing in the last year, which seems quite stable. At the same time I was able to ask an intern to just run it last week, and bam! they have everything they need installed.
One use for it that surprised me was hearing a colleague saying that he reinstalls his OS after every change of client and runs the setup script again so there’s no fear of IP theft but also no downtime from having an unconfigured machine.
http://github.com/pkrumins/install-computer/blob/master/inst...
This script installs all packages that I use, links all the dotfiles, all dockerfiles, all services, docker networks, setups all virtual hosts, and the new workstation is ready to use in 15 minutes. Before this script, it would take days to properly set a workstation up as I'd always forget something (missing file or configuration options).
We have a mixture of python, java, go, protobuf, and node. The only tools a new developer needs to install are bazelisk and nix. Everything else is fetched as needed during build/test.
How do you make your IDE happy about Bazel managing your external dependencies? I mean, autocomplete and stuff like that.
How do you manage dependencies for the fine-grained Bazel targets (like py_library)? Do you write them manually or using some language-specific tools like Gazelle? If you do use the tool, do you have anything in place to automate it?
Couple years ago I had a pretty bad experience with people complaining about having to execute Gazelle manually. In my ideal world view I'd want to add an import statement in code and just run `bazel build`. So I ended having a wrapper that would run Gazelle before running Bazel all the time, but it slowed thing down quite a bit, because it was doing a lot of unnecessary work.
[1]: https://direnv.net
For what it's worth, our venv stuff is at https://github.com/cedarai/rules_pyvenv
The trouble with shell scripts is that they generally require you to manage the state of the machine - whether or not something is installed, before I go install and configure it. Or, if it's already configured, what configs to leave in place, and what configs to reset.
With Chef, for instance, everything's declarative. I don't say "install this package"; rather, I say "this package should be installed". Nobody ever runs the setup script just once, since the dev environment is constantly changing, and all of those edge cases (maybe I last ran it on rev 3, or rev 7 - how do I get to rev 12?) become hard to manage.
That said, it's also surprisingly finicky. The scripts have to be regularly maintained or things keep changing out from under you and causing problems. Especially if you need to support more than one platform (i.e. macOs and a Linux say...).
Idempotency is the runtime behavior.
You can absolutely write idempotent program using imperative language (case in point: chef and its recipe can be expressed as machine code, which is a very imperative language, yet it is idempotent when you run it).
What is the current state of the art with python on Mac?
Python 2->3, brew vs core install and pyenv changes all seem to combine to make it a pain.
asdf as a generic "use this version of language/runtime in this directory/project" seems like it might be the future, but isn't quite the norm now.
Anyone experienced with Python on Mac have any informed opinions to share?
I use asdf just to avoid having pyenv + rbenv + nodenv + javaenv installed, and it works fine.
Homebrew has its own python installation, but I make sure to always use the one installed by asdf, they don't touch each other and everything works ok.
I make sure nothing uses the system python other than any system tools that do it without my knowledge.
You should ditch nvm for Volta. It’s insanely better
https://guide.macports.org/#installing.xcode
Any idea why that is? Is it out of date?