homesick 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,41 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # jeweler generated
12
+ pkg
13
+
14
+ .bundle
15
+
16
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
17
+ #
18
+ # * Create a file at ~/.gitignore
19
+ # * Include files you want ignored
20
+ # * Run: git config --global core.excludesfile ~/.gitignore
21
+ #
22
+ # After doing this, these files will be ignored in all your git projects,
23
+ # saving you from having to 'pollute' every project you touch with them
24
+ #
25
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
26
+ #
27
+ # For MacOS:
28
+ #
29
+ .DS_Store
30
+ #
31
+ # For TextMate
32
+ #*.tmproj
33
+ #tmtags
34
+ #
35
+ # For emacs:
36
+ *~
37
+ \#*
38
+ .\#*
39
+ #
40
+ # For vim:
41
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ # Add dependencies required to use your gem here.
2
+ group :runtime do
3
+ #gem 'bundler', '>= 0.9.5'
4
+ gem "thor"
5
+ end
6
+
7
+ # Add dependencies to develop your gem here.
8
+ # Include everything needed to run rake, tests, features, etc.
9
+ group :development do
10
+ gem "rake"
11
+ gem "rspec", ">= 1.2.9"
12
+ gem "bundler", ">= 0.9.5"
13
+ gem "jeweler", ">= 1.4.0"
14
+ gem "rcov", ">= 0"
15
+ gem "devver-construct"
16
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Joshua Nichols
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,43 @@
1
+ = homesick
2
+
3
+ A man's home (directory) is his castle, so don't leave home with out it.
4
+
5
+ Homesick is sorta like rip, but for dotfiles. It uses git to clone a repository containing dotfiles, and saves them in ~/.homesick. It then allows you to symlink all the dotfiles into place with a single command.
6
+
7
+ We call a repository that is compatible with homesick to be a 'castle'. To act as a castle, a repository must be organized like so:
8
+
9
+ * Contains a 'home' directory
10
+ * 'home' contains any number of files and directories that begin with '.'
11
+ * Optionally has a README file
12
+
13
+ To get started, install homesick first:
14
+
15
+ gem install homesick
16
+
17
+ Next, you use the homesick command to clone a castle:
18
+
19
+ homesick clone git://github.com/technicalpickles/pickled-vim.git
20
+
21
+ Alternatively, if it's on github, there's a slightly shorter way:
22
+
23
+ homesick clone technicalpickles/pickled-vim
24
+
25
+ With the castle cloned, you can now link its contents into your home dir:
26
+
27
+ homesick link pickled-vim
28
+
29
+ If you're not sure what castles you have around, you can easily list them:
30
+
31
+ homesick list
32
+
33
+ == Note on Patches/Pull Requests
34
+
35
+ * Fork the project.
36
+ * Make your feature addition or bug fix.
37
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
38
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
39
+ * Send me a pull request. Bonus points for topic branches.
40
+
41
+ == Copyright
42
+
43
+ Copyright (c) 2010 Joshua Nichols. See LICENSE for details.
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:runtime, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.name = "homesick"
15
+ gem.summary = %Q{A man's home is his castle. Never leave your dotfiles behind.}
16
+ gem.description = %Q{
17
+ A man’s home (directory) is his castle, so don’t leave home with out it.
18
+
19
+ Homesick is sorta like rip, but for dotfiles. It uses git to clone a repository containing dotfiles, and saves them in ~/.homesick. It then allows you to symlink all the dotfiles into place with a single command.
20
+
21
+ }
22
+ gem.email = "josh@technicalpickles.com"
23
+ gem.homepage = "http://github.com/technicalpickles/homesick"
24
+ gem.authors = ["Joshua Nichols"]
25
+ gem.version = "0.1.0"
26
+ # Have dependencies? Add them to Gemfile
27
+
28
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
29
+ end
30
+ Jeweler::GemcutterTasks.new
31
+
32
+
33
+ require 'spec/rake/spectask'
34
+ Spec::Rake::SpecTask.new(:spec) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.spec_files = FileList['spec/**/*_spec.rb']
37
+ end
38
+
39
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
40
+ spec.libs << 'lib' << 'spec'
41
+ spec.pattern = 'spec/**/*_spec.rb'
42
+ spec.rcov = true
43
+ end
44
+
45
+ task :default => :spec
46
+
47
+ require 'rake/rdoctask'
48
+ Rake::RDocTask.new do |rdoc|
49
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "homesick #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
56
+
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+ lib = Pathname.new(__FILE__).dirname.join('..', 'lib').expand_path
5
+ $LOAD_PATH.unshift.unshift lib.to_s unless $LOAD_PATH.include?(lib.to_s)
6
+
7
+ require 'homesick'
8
+
9
+ Homesick.start
@@ -0,0 +1,60 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{homesick}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Joshua Nichols"]
12
+ s.date = %q{2010-03-10}
13
+ s.default_executable = %q{homesick}
14
+ s.description = %q{
15
+ A man’s home (directory) is his castle, so don’t leave home with out it.
16
+
17
+ Homesick is sorta like rip, but for dotfiles. It uses git to clone a repository containing dotfiles, and saves them in ~/.homesick. It then allows you to symlink all the dotfiles into place with a single command.
18
+
19
+ }
20
+ s.email = %q{josh@technicalpickles.com}
21
+ s.executables = ["homesick"]
22
+ s.extra_rdoc_files = [
23
+ "LICENSE",
24
+ "README.rdoc"
25
+ ]
26
+ s.files = [
27
+ ".document",
28
+ ".gitignore",
29
+ "Gemfile",
30
+ "LICENSE",
31
+ "README.rdoc",
32
+ "Rakefile",
33
+ "bin/homesick",
34
+ "homesick.gemspec",
35
+ "lib/homesick.rb",
36
+ "spec/homesick/homesick_spec.rb",
37
+ "spec/spec.opts",
38
+ "spec/spec_helper.rb"
39
+ ]
40
+ s.homepage = %q{http://github.com/technicalpickles/homesick}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.6}
44
+ s.summary = %q{A man's home is his castle. Never leave your dotfiles behind.}
45
+ s.test_files = [
46
+ "spec/homesick/homesick_spec.rb",
47
+ "spec/spec_helper.rb"
48
+ ]
49
+
50
+ if s.respond_to? :specification_version then
51
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
52
+ s.specification_version = 3
53
+
54
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
55
+ else
56
+ end
57
+ else
58
+ end
59
+ end
60
+
@@ -0,0 +1,130 @@
1
+ require 'thor'
2
+
3
+ class Homesick < Thor
4
+ include Thor::Actions
5
+
6
+ # Hack in support for diffing symlinks
7
+ class Shell < Thor::Shell::Color
8
+
9
+ def show_diff(destination, content)
10
+ destination = Pathname.new(destination)
11
+
12
+ if destination.symlink?
13
+ say "- #{destination.readlink}", :red, true
14
+ say "+ #{content.expand_path}", :green, true
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ def initialize(args=[], options={}, config={})
23
+ super
24
+ self.shell = Homesick::Shell.new
25
+ end
26
+
27
+ GIT_URI_PATTERN = /^git:\/\//
28
+ GITHUB_NAME_REPO_PATTERN = /([A-Za-z_-]+)\/([A-Za-z_-]+)/
29
+
30
+ desc "clone URI", "Clone +uri+ as a castle for homesick"
31
+ def clone(uri)
32
+ empty_directory repos_dir, :verbose => false
33
+ inside repos_dir do
34
+ if uri =~ GIT_URI_PATTERN
35
+ git_clone uri
36
+ elsif uri =~ GITHUB_NAME_REPO_PATTERN
37
+ git_clone "git://github.com/#{$1}/#{$2}.git", "#{$1}_#{$2}"
38
+ end
39
+ end
40
+ end
41
+
42
+ desc "link NAME", "Symlinks all dotfiles from the specified castle"
43
+ def link(home)
44
+ inside castle_dir(home) do
45
+ files = Pathname.glob('.*')[2..-1] # skip . and .., ie the first two
46
+ files.each do |path|
47
+ absolute_path = path.expand_path
48
+
49
+ inside user_dir do
50
+ adjusted_path = (user_dir + path).basename
51
+
52
+ symlink absolute_path, adjusted_path
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ desc "list", "List cloned castles"
59
+ def list
60
+ inside repos_dir do
61
+ Pathname.glob('*') do |home|
62
+ puts home
63
+ end
64
+ end
65
+ end
66
+
67
+
68
+ no_tasks do
69
+ # class method, so it's convenient to stub out during tests
70
+ def self.user_dir
71
+ @user_dir ||= Pathname.new('~').expand_path
72
+ end
73
+
74
+ def self.repos_dir
75
+ @repos_dir ||= Pathname.new('~/.homesick/repos').expand_path
76
+ end
77
+
78
+ def repos_dir
79
+ self.class.repos_dir
80
+ end
81
+ end
82
+
83
+ protected
84
+
85
+ # TODO move this to be more like thor's template, empty_directory, etc
86
+ def git_clone(repo, config = {})
87
+ config ||= {}
88
+ destination = config[:destination] || begin
89
+ repo =~ /([^\/]+)\.git$/
90
+ $1
91
+ end
92
+
93
+ destination = Pathname.new(destination) unless destination.kind_of?(Pathname)
94
+
95
+ if ! destination.directory?
96
+ say_status 'git clone', "#{repo} to #{destination.expand_path}", :green if config.fetch(:verbose, true)
97
+ system "git clone #{repo} #{destination}" unless options[:pretend]
98
+ else
99
+ say_status :exist, destination.expand_path, :blue
100
+ end
101
+ end
102
+
103
+ def symlink(source, destination, config = {})
104
+ destination = Pathname.new(destination)
105
+
106
+ if destination.symlink?
107
+ if destination.readlink == source
108
+ say_status :identical, destination.expand_path, :blue
109
+ else
110
+ say_status :conflict, "#{destination} exists and points to #{destination.readlink}", :red
111
+
112
+ if shell.file_collision(destination) { source }
113
+ system "ln -sf #{source} #{destination}"
114
+ end
115
+ end
116
+ else
117
+ say_status :symlink, "#{source.expand_path} to #{destination.expand_path}", :green
118
+ system "ln -s #{source} #{destination}"
119
+ end
120
+ end
121
+
122
+ def user_dir
123
+ self.class.user_dir
124
+ end
125
+
126
+ def castle_dir(name)
127
+ repos_dir.join(name, 'home')
128
+ end
129
+
130
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Homesick" do
4
+ before do
5
+ @homesick = Homesick.new
6
+ end
7
+
8
+ it "should clone any git repo" do
9
+ @homesick.should_receive(:git_clone).with('git://github.com/technicalpickles/pickled-vim.git')
10
+
11
+ @homesick.clone "git://github.com/technicalpickles/pickled-vim.git"
12
+ end
13
+
14
+ it "should clone a github repo" do
15
+ @homesick.should_receive(:git_clone).with('git://github.com/wfarr/dotfiles.git', 'wfarr_dotfiles')
16
+
17
+ @homesick.clone "wfarr/dotfiles"
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'homesick'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+ require 'construct'
7
+
8
+ Spec::Runner.configure do |config|
9
+ config.include Construct::Helpers
10
+
11
+ config.before do
12
+ @user_dir = create_construct
13
+ Homesick.stub!(:user_dir).and_return(@user_dir)
14
+ end
15
+
16
+ config.after do
17
+ @user_dir.destroy!
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: homesick
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Joshua Nichols
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-10 00:00:00 -05:00
18
+ default_executable: homesick
19
+ dependencies: []
20
+
21
+ description: "\n A man\xE2\x80\x99s home (directory) is his castle, so don\xE2\x80\x99t leave home with out it.\n\n Homesick is sorta like rip, but for dotfiles. It uses git to clone a repository containing dotfiles, and saves them in ~/.homesick. It then allows you to symlink all the dotfiles into place with a single command. \n\n "
22
+ email: josh@technicalpickles.com
23
+ executables:
24
+ - homesick
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - LICENSE
29
+ - README.rdoc
30
+ files:
31
+ - .document
32
+ - .gitignore
33
+ - Gemfile
34
+ - LICENSE
35
+ - README.rdoc
36
+ - Rakefile
37
+ - bin/homesick
38
+ - homesick.gemspec
39
+ - lib/homesick.rb
40
+ - spec/homesick/homesick_spec.rb
41
+ - spec/spec.opts
42
+ - spec/spec_helper.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/technicalpickles/homesick
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.6
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: A man's home is his castle. Never leave your dotfiles behind.
73
+ test_files:
74
+ - spec/homesick/homesick_spec.rb
75
+ - spec/spec_helper.rb