Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Prevent repeat dotfile edits and a more pleasant UX #82

Closed
wants to merge 4 commits into from

3 participants

@adarsh

Updates

  • Remove check for SSH key before copying. This shouldn't fail unless the previous keygen step fails, in which case this doesn't matter
  • Check for existing dotfile changes before repeating them. Ensures idempotency of the script. Applies to Homebrew path priority change and rbenv init call.

UX

  • Add intro and pause at beginning (e.g. 'hit return to start')
  • Clearer description of browser-opening step. Browser opening can surprise people. This gives you some context.
  • Add trailing echo's to separate output
  • Add pause and instructions for setting up dbs at boot

  • Give a 'hit return to continue' to give users time to read

  • Instruct them on how to set up DBs to start at boot
Adarsh Pandit and others added some commits
Adarsh Pandit Prevent repeat dotfile edits and a more pleasant UX
Updates
-------

* Remove check for SSH key before copying. This shouldn't fail unless the previous keygen step fails, in which case this doesn't matter
* Check for existing dotfile changes before repeating them. Ensures idempotency of the script. Applies to Homebrew path priority change and rbenv init call.

UX
--

* Add intro and pause at beginning (e.g. 'hit return to start')
* Clearer description of browser-opening step. Browser opening can surprise people. This gives you some context.
* Add trailing echo's to separate output
* Add pause and instructions for setting up dbs at boot

* Give a 'hit return to continue' to give users time to read
* Instruct them on how to set up DBs to start at boot
fff8403
@croaky croaky Restrict changes to idempotency
* [Avoid captive user interfaces][1].
* [Don't be chatty][2].
* Move `exec $SHELL -l` line to spot recommended by [rbenv README][3].

[1]: http://goo.gl/cocdC
[2]: http://goo.gl/mL7hn
[3]: https://github.com/sstephenson/rbenv/
89272c9
@croaky
Owner

@adarshpandit Thanks for the PR. I really like the changes to make it idempotent. Also good call on the SSH check.

I pushed a follow-up commit to this branch that:

  • Removes the extra echos.
  • Does not print anything to stdout.
  • Removes the captive user interface changes.
  • Adds a line about idempotence to the README.
  • Removes the printed instructions about Postgres and Redis.

I provided links in the commit explaining why I don't want the script to be chatty or create a captive user interface.

I'd rather see the Postgres and Redis commands just run, rather than printed as instructions. A goal of the script is to be a one-liner. If there are commands from those brew infos that we should bring in, those would be good separate PRs.

Take a look at the current diff and let me know what you think.

@Kerrick

Moved the logging/stdout part of this post to #83.

I completely agree with avoiding a captive user interface in most situations. However, I totally get why @adarshpandit added them in the first place--if you're not actively watching the text stream by, you can totally miss the fact that your clipboard was modified and the reason the browser just opened. In fact, in your follow-up commit, those are completely omitted.

In fact, an argument could be made that a captive UI is a good thing in this situation, because the script (being run in the terminal) is modifying your clipboard, potentially overwriting something important. It's a good idea to warn the user before that happens so they can paste the information somewhere.

Perhaps a good compromise could be to move the SSH key generation/copying and the GitHub opening to the end, mention them to the user, and halt the script only for the clipboard alteration?

@Kerrick
read -p "Press any key to start: " -n 1
@Kerrick

In the previous read instance you ended with :, but in this you end with . instead. Also, "press" vs "hit" and "any key" vs "return." It's a tiny thing, but consistent micro-copy is pleasant for the user. :)

Agree regarding consistency. Will wait to see which direction this PR shakes out before making final edits.

@croaky
Owner

However, I totally get why @adarshpandit added them in the first place--if you're not actively watching the text stream by, you can totally miss the fact that your clipboard was modified and the reason the browser just opened.

Definitely. Taking another approach, I've removed the "copy SSH key to clipboard" bit in 3876ff5.

I opened a separate issue for logging the information here:

#83

Definitely interested in more opinions about status indicators printing out vs. just logging.

@adarsh

Typo: 'Install'

Owner

Thanks. Fixed in 1320f76.

@adarsh

Very interesting approach and well worth the discussion. I prefer the version I submitted because I find it much easier to use and understand. Removing all standard output feels like a pretty big change, hence the lengthy discussion below.

The script installs and modifies many programs and libraries for you. I think it's important to know specifically what it does (and maybe why). For example, you might try to alter your path and wonder why it's been changed in the way it has (or even how it got changed, if you didn't know laptop did it for you). I'd bet more than a minority of users run the script without reading it - I know I've run scripts without reading them all the way through.

The references to UNIX philosophy are very interesting. One downside to Captive User Interfaces noted is parsing the prompted response. In this case, we're not parsing responses, only pausing for the user to read about the big changes we're making to their environment.

To me, this script doesn't feel as much like a "UNIX program", like grep or ack as much as it does a "script" or "macro". I might have the wrong idea completely about UNIX but it definitely feels like a different beast. Silver Searcher feels closer to the UNIX family than this does.

Now that may mean it should be made to be more like a UNIX program (closer to your edits) or that scripts like this which replicate repetitive command-line statements fall under some different concept. I'm not sure I have the answer for that.

Practically, I would think not seeing progress/output would make me wonder if the script was working at all. This script has stalled/failed on me a number of times and knowing where is important as I debug. I could see using this on a friend's computer and have them look at me and ask if it was running.

The underlying programs, the OS X environment, and user customization are all sources of instability and change. I can't say this script works 100% of the time given the uncontrollable shiftiness I mentioned. As such, I'd like a lot more detail on what fails and how far along we've gotten before it does. @croaky I'm curious to know if you've noticed this brittleness as well.

Also worth noting, the successfully method, which should give nice errors on failure, doesn't always exit the script upon failures. I'm guessing not all of those methods return the right success code, but that's just a guess.

I kind of liked having the script copy my key and open the browser, but maybe I'm in the minority. If it's kept, I still think it's worth warning the user before opening a browser.

Anyhow, I'm not big on the changes and agree with @Kerrick for the most part, although I'd prefer seeing std out progress over an output logfile, especially if it's run repeatedly. I think the output serves as a learning tool as well - I first learned about Redis from this script. That being said, I'm curious to hear other thoughts about these changes.

At the very least, I've already learned a ton through this discussion and now I'm ordering a copy of "The UNIX Philosophy".

@adarsh

Not sure if this is too late, but a change this big might be best in a separate PR, so this one would be "Improve what we already have" while the new one would be "Remove all stdout". Just a thought

@croaky croaky was assigned
@croaky
Owner

a change this big might be best in a separate PR

Agree these should be broken out. Going to separate them and try one other approach to output.

@croaky
Owner

Removing all standard output feels like a pretty big change

My earlier change didn't remove all standard output, although I see that's how I phrased it. So, my apologies. All I was doing was removing the custom output, not the output from the scripts themselves, which print quite a bit. I don't think that was serving much of a purpose and I think the arguments about users thinking the script is hanging are valid.

So, I extracted the pieces from our commits into smaller PRs:

And added a new one, Print commands as they execute, to add a bit more context to the output.

I don't think I want to add the reads right now for fear of users thinking the script is done. As a compromise, I added a little bit of extra documentation encouraging the user to read the script before running it: 70bcd8f

Let me know what you think and thanks for all the ideas, the pull request, and comments.

@croaky croaky closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 5, 2013
  1. Prevent repeat dotfile edits and a more pleasant UX

    Adarsh Pandit authored
    Updates
    -------
    
    * Remove check for SSH key before copying. This shouldn't fail unless the previous keygen step fails, in which case this doesn't matter
    * Check for existing dotfile changes before repeating them. Ensures idempotency of the script. Applies to Homebrew path priority change and rbenv init call.
    
    UX
    --
    
    * Add intro and pause at beginning (e.g. 'hit return to start')
    * Clearer description of browser-opening step. Browser opening can surprise people. This gives you some context.
    * Add trailing echo's to separate output
    * Add pause and instructions for setting up dbs at boot
    
    * Give a 'hit return to continue' to give users time to read
    * Instruct them on how to set up DBs to start at boot
Commits on Apr 6, 2013
  1. @croaky

    Restrict changes to idempotency

    croaky authored
    * [Avoid captive user interfaces][1].
    * [Don't be chatty][2].
    * Move `exec $SHELL -l` line to spot recommended by [rbenv README][3].
    
    [1]: http://goo.gl/cocdC
    [2]: http://goo.gl/mL7hn
    [3]: https://github.com/sstephenson/rbenv/
Commits on Apr 7, 2013
  1. @croaky
Commits on Apr 9, 2013
  1. @croaky

    Fix typo

    croaky authored
This page is out of date. Refresh to see the latest.
Showing with 75 additions and 67 deletions.
  1. +75 −67 mac
View
142 mac
@@ -4,94 +4,102 @@ successfully() {
$* || (echo "failed" 1>&2 && exit 1)
}
-echo "Checking for SSH key, generating one if it doesn't exist ..."
- [[ -f ~/.ssh/id_rsa.pub ]] || ssh-keygen -t rsa
-
-echo "Copying public key to clipboard. Paste it into your Github account ..."
- [[ -f ~/.ssh/id_rsa.pub ]] && cat ~/.ssh/id_rsa.pub | pbcopy
- successfully open https://github.com/account/ssh
-
-echo "Fixing permissions ..."
- successfully sudo mkdir -p /usr/local
- successfully sudo chown -R `whoami` /usr/local
-
-echo "Installing Homebrew, a good OS X package manager ..."
- successfully ruby <(curl -fsS https://raw.github.com/mxcl/homebrew/go)
- successfully brew update
-
-echo "Putting Homebrew location earlier in PATH ..."
- successfully echo "
-# recommended by brew doctor
-export PATH='/usr/local/bin:$PATH'" >> ~/.zshenv
+if ! [ -f ~/.ssh/id_rsa.pub ]; then
+ # Generate SSH key.
+ ssh-keygen -t rsa
+fi
+
+# Fix permissions.
+successfully sudo mkdir -p /usr/local
+successfully sudo chown -R `whoami` /usr/local
+
+# Install Homebrew, a good OS X package manager.
+successfully ruby <(curl -fsS https://raw.github.com/mxcl/homebrew/go)
+successfully brew update
+
+if ! grep -qs "recommended by brew doctor" ~/.zshenv; then
+ # Put Homebrew location earlier in PATH.
+ successfully echo '
+ # recommended by brew doctor
+ export PATH="/usr/local/bin:$PATH"' >> ~/.zshenv
successfully source ~/.zshenv
+fi
-echo "Installing GNU Compiler Collection and dependencies ..."
- successfully brew tap homebrew/dupes
- successfully brew install autoconf automake apple-gcc42
+# Install GNU Compiler Collection and dependencies.
+successfully brew tap homebrew/dupes
+successfully brew install autoconf automake apple-gcc42
-echo "Installing system libraries recommended for Ruby ..."
- successfully brew install gdbm libffi libksba libyaml
+# Install system libraries recommended for Ruby.
+successfully brew install gdbm libffi libksba libyaml
-echo "Installing Postgres, a good open source relational database ..."
- successfully brew install postgres --no-python
- successfully initdb /usr/local/var/postgres -E utf8
+# Install Postgres, a good open source relational database.
+successfully brew install postgres --no-python
+successfully initdb /usr/local/var/postgres -E utf8
-echo "Installing Redis, a good key-value database ..."
- successfully brew install redis
+# Install Redis, a good key-value database.
+successfully brew install redis
-echo "Installing The Silver Searcher (better than ack or grep) for searching the contents of files ..."
- successfully brew install the_silver_searcher
+# Install Silver Searcher (better than ack or grep) to search the contents of
+# files.
+successfully brew install the_silver_searcher
-echo "Installing ctags, for indexing files for vim tab completion of methods, classes, variables ..."
- successfully brew install ctags
+# Install ctags to index files for vim tab completion of methods, classes,
+# variables.
+successfully brew install ctags
-echo "Installing tmux, for saving project state and switching between projects ..."
- successfully brew install tmux
+# Install tmux, for saving project state and switching between projects.
+successfully brew install tmux
-echo "Installing reattach-to-user-namespace, for copy-paste and RubyMotion compatibility with tmux ..."
- successfully brew install reattach-to-user-namespace
+# Install reattach-to-user-namespace for copy-paste with tmux.
+successfully brew install reattach-to-user-namespace
-echo "Installing ImageMagick, for cropping and re-sizing images ..."
- successfully brew install imagemagick
+# Install ImageMagick to crop and resize images.
+successfully brew install imagemagick
-echo "Installing QT, used by Capybara Webkit for headless Javascript integration testing ..."
- successfully brew install qt
+# Install QT, used by Capybara Webkit for headless Javascript integration
+# testing.
+successfully brew install qt
-echo "Installing watch, used to execute a program periodically and show the output ..."
- successfully brew install watch
+# Install watch, used to execute a program periodically and show the output.
+successfully brew install watch
-echo "Installing rbenv for changing Ruby versions ..."
- successfully brew install rbenv
+# Install rbenv for changing Ruby versions.
+successfully brew install rbenv
+
+if ! [ grep -qs "rbenv init" ~/.zlogin ]; then
+ # Set up rbenv to be used by default in ZSH sessions.
successfully echo 'eval "$(rbenv init -)"' >> ~/.zlogin
- successfully source ~/.zlogin
-echo "Installing rbenv-gem-rehash so the shell automatically picks up binaries after installing gems with binaries..."
- successfully brew install rbenv-gem-rehash
+ # Restart the shell to apply changes.
+ exec $SHELL -l
+fi
-echo "Installing ruby-build for installing Rubies ..."
- successfully brew install ruby-build
+# Install rbenv-gem-rehash so the shell picks up binaries after installing gems
+# with binaries.
+successfully brew install rbenv-gem-rehash
-echo "Installing Ruby 1.9.3-p392 ..."
- CC=gcc-4.2 successfully rbenv install 1.9.3-p392
+# Install ruby-build for installing Rubies.
+successfully brew install ruby-build
-echo "Setting Ruby 1.9.3-p392 as global default Ruby ..."
- successfully rbenv global 1.9.3-p392
- successfully rbenv shell 1.9.3-p392
+# Install Ruby 1.9.3-p392.
+CC=gcc-4.2 successfully rbenv install 1.9.3-p392
-echo "Update to latest Rubygems version ..."
- successfully gem update --system
+# Set Ruby 1.9.3-p392 as global default Ruby.
+successfully rbenv global 1.9.3-p392
+successfully rbenv shell 1.9.3-p392
-echo "Installing critical Ruby gems for Rails development ..."
- successfully gem install bundler foreman pg rails thin --no-document
+# Update to latest Rubygems version.
+successfully gem update --system
-echo "Installing GitHub CLI client ..."
- successfully gem install hub --no-document
+# Install critical Ruby gems for Rails development.
+successfully gem install bundler foreman pg rails thin --no-document
-echo "Installing Heroku CLI client ..."
- successfully brew install heroku-toolbelt
+# Install GitHub CLI client.
+successfully gem install hub --no-document
-echo "Installing the heroku-config plugin for pulling config variables locally to be used as ENV variables ..."
- successfully heroku plugins:install git://github.com/ddollar/heroku-config.git
+# Install Heroku CLI client.
+successfully brew install heroku-toolbelt
-echo "Your shell will now restart in order for changes to apply."
- exec $SHELL -l
+# Install the heroku-config plugin for pulling config variables locally to be
+# used as ENV variables.
+successfully heroku plugins:install git://github.com/ddollar/heroku-config.git
Something went wrong with that request. Please try again.