An except from “Lisp: Good News, Bad News, How to Win Big.” (section 2.1, much more readable than that PDF version, and allows for easy copy and paste).
What makes a great design:
- Simplicity: easy to understand or explain
- Correctness: error-free or accurate
- Consistency: does not contain a contradiction
- Completeness: solves a hard problem
He calls this the “right thing” which implies that he is right, pretty interesting.
The worse-is-better philosophy is only slightly different
So, definitely not a simple philosophy already.
The MIT guy then muttered that sometimes it takes a tough man to make a tender chicken, but the New Jersey guy didn’t understand (I’m not sure I do either).
Probably my favorite part of this whole essay, being tender is not easy, it’s tough.
Anyway, pretty interesting essay but seems to:
- Not be simple to understand
- Is neither accurate nor free of errors
- Contains contradictions: explaining how to be simple in a complicated way
- Doesn’t solve a hard problem: it makes it more complicated
I would recommend reading instead:
- Paul Grahams’s essays
- “Hackers and Painters” (essay and book)
- “The Cathedral and the Bazaar”
- “How To Become A Hacker”
- “PEP 20 – The Zen of Python”
- “The Rails Doctrine”
- Also: Another review from Coding Horror, e.g. Jeff Atwood
So, I’m gonna start from this ruby script quickly hacked up and pasted in a gist :).
Gem::Specification.new do |s| s.name = 'safe-bundle-update' s.version = '0.0.1' s.date = '2017-02-28' s.summary = 'Update gems one by one, running tests and commiting changes' s.description = '`bundle update` updates all your gems, this safely updates yours gems one by one' s.authors = ['Dorian Marié'] s.email = '[email protected]' s.files = ['lib/safe-bundle-update.rb', 'bin/safe-bundle-update'] s.homepage = 'https://github.com/Dorian/safe-bundle-update' s.license = 'MIT' end
lib/safe-bundle-update.rb with just enough to make it work (short version):
class SafeBundleUpdate def self.start(*commands) puts commands.join(' ') end end
Make a bin directory with your executable script:
mkdir bin touch bin/safe-bundle-update chmod +x bin/safe-bundle-update
Use your gem in this executable:
#!/usr/bin/env ruby require 'safe-bundle-update' SafeBundleUpdate.start(*ARGV)
Some manual testing for now:
cp Gemfile.lock.old Gemfile.lock; bundle install; ruby -Ilib bin/safe-bundle-update "echo 1"
Some actual testing :) :
# Rakefile require 'rake/testtask' Rake::TestTask.new do |t| t.libs << 'test' end desc 'Run tests' task default: :test
# test/test_safe-bundle-update.rb require 'minitest/autorun' require 'safe-bundle-update' class SafeBundleUpdateTest < Minitest::Test def test_empty assert_nil(SafeBundleUpdate.start("echo 1")) end end
rake to run it.
Pushing that to rubygems:
gem build safe-bundle-update.gemspec gem install safe-bundle-update-0.0.1.gem gem push safe-bundle-update-0.0.1.gem
And that’s it:
So, I’m there with my Rails app, a lot of gems are outdated (like ~50% of them) and of course everybody on the internet is like: “Just run
bundle install you fool”. Except that running
bundle install updates every single outdated gems and breaks my build in many ways. And I’m not the kind of person who want to keep outdated fixed versions around.
So, why not just update the gems one by one:
- Take the first listed, update that:
bundle update great-gem
- Make sure everything is working with:
rspec spec/featuresfor instance
- If it’s all good, commit that gem update
- Otherwise skip this gem and go to the next one
Sounds simple right? And yes it works very well.
Then this happens:
So, let’s do something even better, an open-source gem ;)
if ( ++p == pe ) // ☁️ 💔
Technically any Cloudflare-controlled domain could be affected but those are the ones that had public leaked data even after the disclosure:
Found in the wild: 29
Found in the wild by other people: 1
- Install gpg1:
brew install gpg1
- Set the encoding as utf-8:
vim ~/.gnupg/gpg.confthen uncomment
- Check if you already have GPG keys installed
gpg --list-secret-keys --keyid-format LONG
- If not, generate a new one:
- Get the public key:
gpg --armor --export ABCDEF
- Paste that on https://github.com/settings/keys
- Configure git to always sign commits with this key:
git config --global gpg.program gpg1
git config --global commit.gpgsign true
git config --global user.signingkey ABCDEF
- Get gpgtools to store passphrase in MacOS:
brew cask install gpgtools(requires sudo access)
- Open “GPG Keychain”, select key, “change passphrase”, “store in keychain”
- Commit like usual:
git commit ...
git merge ...
git pull ...