homesick 1.0.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc68ba4de11dcb178297a225d07adff5c405da50
4
- data.tar.gz: 0f91eaf463e96a84458c6e663512edec02ccf249
3
+ metadata.gz: bcecddd4148681735ac7cb0126a5d46ce51274ff
4
+ data.tar.gz: c4102a683c881383d3836e8604ee21f5780cc996
5
5
  SHA512:
6
- metadata.gz: d17b812e2934ff6b30c15f6275a624fb58b82388f7e615846c3df9092af51cbcbec879e7bf7b843de1323dedd172bd0a5b43b49e998730306741e0f499ae4d3d
7
- data.tar.gz: 020f491019da376ed5a825f9d23706501b1d7255a2c33c8fc21cf4bd3a8135edc8dc33dde84be6dd66166f71fecd1d732c8089c6b65be8ded7d6b0b5d44592b5
6
+ metadata.gz: 0d1ade2b0417f4e5d829a330c1d6e45d2ffd41f16182abc354206365858c9a60b83430acb68c1b4184bf19233fbbb34e6464d58935f6230d3119693a793e94e9
7
+ data.tar.gz: 07c13eaed62b4f906df29b020c993c6a6809ba1d7eaa613d9c176c7d2c27b0e440d1371a32b315974b4795ba70f49ff83215456cd5c30d1d034b03a610fed6d5
@@ -0,0 +1,19 @@
1
+ # TODO: Eval is required for the .homesickrc feature. This should eventually be
2
+ # removed if the feature is implemented in a more secure way.
3
+ Eval:
4
+ Enabled: false
5
+
6
+ # TODO: The following settings disable reports about issues that can be fixed
7
+ # through refactoring. Remove these as offenses are removed from the code base.
8
+
9
+ ClassLength:
10
+ Enabled: false
11
+
12
+ CyclomaticComplexity:
13
+ Max: 13
14
+
15
+ LineLength:
16
+ Enabled: false
17
+
18
+ MethodLength:
19
+ Max: 36
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.1.0
3
4
  - 2.0.0
4
5
  - 1.9.3
@@ -1,3 +1,7 @@
1
+ #1.1.0
2
+ * Added exec and exec_all commands to run commands inside one or all clones castles.
3
+ * Code refactoring.
4
+
1
5
  #1.0.0
2
6
  * Removed support for Ruby 1.8.7
3
7
  * Added a version command
data/Gemfile CHANGED
@@ -13,8 +13,8 @@ group :development do
13
13
  gem "guard-rspec"
14
14
  gem "rb-readline", "~> 0.5.0"
15
15
  gem "jeweler", ">= 1.6.2"
16
- gem "rcov", :platforms => :mri_18
17
- gem "simplecov", :platforms => :mri_19
16
+ #gem "simplecov"
17
+ gem 'coveralls', require: false
18
18
  gem "test_construct"
19
19
  gem "capture-output", "~> 1.0.0"
20
20
  if RbConfig::CONFIG['host_os'] =~ /linux|freebsd|openbsd|sunos|solaris/
@@ -3,7 +3,9 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/homesick.png)](http://badge.fury.io/rb/homesick)
4
4
  [![Build Status](https://travis-ci.org/technicalpickles/homesick.png?branch=master)](https://travis-ci.org/technicalpickles/homesick)
5
5
  [![Dependency Status](https://gemnasium.com/technicalpickles/homesick.png)](https://gemnasium.com/technicalpickles/homesick)
6
+ [![Coverage Status](https://coveralls.io/repos/technicalpickles/homesick/badge.png)](https://coveralls.io/r/technicalpickles/homesick)
6
7
  [![Code Climate](https://codeclimate.com/github/technicalpickles/homesick.png)](https://codeclimate.com/github/technicalpickles/homesick)
8
+ [![Gitter chat](https://badges.gitter.im/technicalpickles/homesick.png)](https://gitter.im/technicalpickles/homesick)
7
9
 
8
10
  Your home directory is your castle. Don't leave your dotfiles behind.
9
11
 
@@ -64,6 +66,14 @@ To open your default editor in the root of a castle (the $EDITOR environment var
64
66
 
65
67
  homesick open CASTLE
66
68
 
69
+ To execute a shell command inside the root directory of a given castle:
70
+
71
+ homesick exec CASTLE COMMAND
72
+
73
+ To execute a shell command inside the root directory of every cloned castle:
74
+
75
+ homesick exec_all COMMAND
76
+
67
77
  Not sure what else homesick has up its sleeve? There's always the built in help:
68
78
 
69
79
  homesick help
@@ -156,6 +166,7 @@ Homesick is tested on the following Ruby versions:
156
166
 
157
167
  * 1.9.3
158
168
  * 2.0.0
169
+ * 2.1.0
159
170
 
160
171
  ## Note on Patches/Pull Requests
161
172
 
@@ -6,4 +6,4 @@ $LOAD_PATH.unshift lib.to_s
6
6
 
7
7
  require 'homesick'
8
8
 
9
- Homesick.start
9
+ Homesick::CLI.start
@@ -2,15 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: homesick 1.0.0 ruby lib
5
+ # stub: homesick 1.1.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "homesick"
9
- s.version = "1.0.0"
9
+ s.version = "1.1.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
12
13
  s.authors = ["Joshua Nichols", "Yusuke Murata"]
13
- s.date = "2014-01-16"
14
+ s.date = "2014-04-29"
14
15
  s.description = "\n Your home directory is your castle. Don't leave your dotfiles behind.\n \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 "
15
16
  s.email = ["josh@technicalpickles.com", "info@muratayusuke.com"]
16
17
  s.executables = ["homesick"]
@@ -22,6 +23,7 @@ Gem::Specification.new do |s|
22
23
  s.files = [
23
24
  ".document",
24
25
  ".rspec",
26
+ ".rubocop.yml",
25
27
  ".travis.yml",
26
28
  "ChangeLog.markdown",
27
29
  "Gemfile",
@@ -32,17 +34,19 @@ Gem::Specification.new do |s|
32
34
  "bin/homesick",
33
35
  "homesick.gemspec",
34
36
  "lib/homesick.rb",
35
- "lib/homesick/actions.rb",
37
+ "lib/homesick/actions/file_actions.rb",
38
+ "lib/homesick/actions/git_actions.rb",
39
+ "lib/homesick/cli.rb",
36
40
  "lib/homesick/shell.rb",
41
+ "lib/homesick/utils.rb",
37
42
  "lib/homesick/version.rb",
38
- "spec/homesick_spec.rb",
43
+ "spec/homesick_cli_spec.rb",
39
44
  "spec/spec.opts",
40
45
  "spec/spec_helper.rb"
41
46
  ]
42
47
  s.homepage = "http://github.com/technicalpickles/homesick"
43
48
  s.licenses = ["MIT"]
44
- s.require_paths = ["lib"]
45
- s.rubygems_version = "2.1.11"
49
+ s.rubygems_version = "2.2.2"
46
50
  s.summary = "Your home directory is your castle. Don't leave your dotfiles behind."
47
51
 
48
52
  if s.respond_to? :specification_version then
@@ -56,11 +60,9 @@ Gem::Specification.new do |s|
56
60
  s.add_development_dependency(%q<guard-rspec>, [">= 0"])
57
61
  s.add_development_dependency(%q<rb-readline>, ["~> 0.5.0"])
58
62
  s.add_development_dependency(%q<jeweler>, [">= 1.6.2"])
59
- s.add_development_dependency(%q<rcov>, [">= 0"])
60
- s.add_development_dependency(%q<simplecov>, [">= 0"])
63
+ s.add_development_dependency(%q<coveralls>, [">= 0"])
61
64
  s.add_development_dependency(%q<test_construct>, [">= 0"])
62
65
  s.add_development_dependency(%q<capture-output>, ["~> 1.0.0"])
63
- s.add_development_dependency(%q<libnotify>, [">= 0"])
64
66
  s.add_development_dependency(%q<rubocop>, [">= 0"])
65
67
  else
66
68
  s.add_dependency(%q<thor>, [">= 0.14.0"])
@@ -70,11 +72,9 @@ Gem::Specification.new do |s|
70
72
  s.add_dependency(%q<guard-rspec>, [">= 0"])
71
73
  s.add_dependency(%q<rb-readline>, ["~> 0.5.0"])
72
74
  s.add_dependency(%q<jeweler>, [">= 1.6.2"])
73
- s.add_dependency(%q<rcov>, [">= 0"])
74
- s.add_dependency(%q<simplecov>, [">= 0"])
75
+ s.add_dependency(%q<coveralls>, [">= 0"])
75
76
  s.add_dependency(%q<test_construct>, [">= 0"])
76
77
  s.add_dependency(%q<capture-output>, ["~> 1.0.0"])
77
- s.add_dependency(%q<libnotify>, [">= 0"])
78
78
  s.add_dependency(%q<rubocop>, [">= 0"])
79
79
  end
80
80
  else
@@ -85,11 +85,9 @@ Gem::Specification.new do |s|
85
85
  s.add_dependency(%q<guard-rspec>, [">= 0"])
86
86
  s.add_dependency(%q<rb-readline>, ["~> 0.5.0"])
87
87
  s.add_dependency(%q<jeweler>, [">= 1.6.2"])
88
- s.add_dependency(%q<rcov>, [">= 0"])
89
- s.add_dependency(%q<simplecov>, [">= 0"])
88
+ s.add_dependency(%q<coveralls>, [">= 0"])
90
89
  s.add_dependency(%q<test_construct>, [">= 0"])
91
90
  s.add_dependency(%q<capture-output>, ["~> 1.0.0"])
92
- s.add_dependency(%q<libnotify>, [">= 0"])
93
91
  s.add_dependency(%q<rubocop>, [">= 0"])
94
92
  end
95
93
  end
@@ -1,450 +1,15 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'thor'
3
-
4
- class Homesick < Thor
5
- autoload :Shell, 'homesick/shell'
6
- autoload :Actions, 'homesick/actions'
7
- autoload :Version, 'homesick/version'
8
-
9
- include Thor::Actions
10
- include Homesick::Actions
11
- include Homesick::Version
12
-
13
- add_runtime_options!
14
-
2
+ require 'homesick/shell'
3
+ require 'homesick/actions/file_actions'
4
+ require 'homesick/actions/git_actions'
5
+ require 'homesick/version'
6
+ require 'homesick/utils'
7
+ require 'homesick/cli'
8
+
9
+ # Homesick's top-level module
10
+ module Homesick
15
11
  GITHUB_NAME_REPO_PATTERN = /\A([A-Za-z0-9_-]+\/[A-Za-z0-9_-]+)\Z/
16
12
  SUBDIR_FILENAME = '.homesick_subdir'
17
13
 
18
14
  DEFAULT_CASTLE_NAME = 'dotfiles'
19
-
20
- map '-v' => :version
21
- map '--version' => :version
22
-
23
- def initialize(args = [], options = {}, config = {})
24
- super
25
- self.shell = Homesick::Shell.new
26
- end
27
-
28
- desc 'clone URI', 'Clone +uri+ as a castle for homesick'
29
- def clone(uri)
30
- inside repos_dir do
31
- destination = nil
32
- if File.exist?(uri)
33
- uri = Pathname.new(uri).expand_path
34
- if uri.to_s.start_with?(repos_dir.to_s)
35
- raise "Castle already cloned to #{uri}"
36
- end
37
-
38
- destination = uri.basename
39
-
40
- ln_s uri, destination
41
- elsif uri =~ GITHUB_NAME_REPO_PATTERN
42
- destination = Pathname.new(uri).basename
43
- git_clone "https://github.com/#{$1}.git", :destination => destination
44
- elsif uri =~ /%r([^%r]*?)(\.git)?\Z/
45
- destination = Pathname.new($1)
46
- git_clone uri
47
- elsif uri =~ /[^:]+:([^:]+)(\.git)?\Z/
48
- destination = Pathname.new($1)
49
- git_clone uri
50
- else
51
- raise "Unknown URI format: #{uri}"
52
- end
53
-
54
- if destination.join('.gitmodules').exist?
55
- inside destination do
56
- git_submodule_init
57
- git_submodule_update
58
- end
59
- end
60
-
61
- rc(destination)
62
- end
63
- end
64
-
65
- desc 'rc CASTLE', 'Run the .homesickrc for the specified castle'
66
- def rc(name = DEFAULT_CASTLE_NAME)
67
- inside repos_dir do
68
- destination = Pathname.new(name)
69
- homesickrc = destination.join('.homesickrc').expand_path
70
- if homesickrc.exist?
71
- proceed = shell.yes?("#{name} has a .homesickrc. Proceed with evaling it? (This could be destructive)")
72
- if proceed
73
- shell.say_status 'eval', homesickrc
74
- inside destination do
75
- eval homesickrc.read, binding, homesickrc.expand_path.to_s
76
- end
77
- else
78
- shell.say_status 'eval skip', "not evaling #{homesickrc}, #{destination} may need manual configuration", :blue
79
- end
80
- end
81
- end
82
- end
83
-
84
- desc 'pull CASTLE', 'Update the specified castle'
85
- method_option :all, :type => :boolean, :default => false, :required => false, :desc => 'Update all cloned castles'
86
- def pull(name = DEFAULT_CASTLE_NAME)
87
- if options[:all]
88
- inside_each_castle do |castle|
89
- shell.say castle.to_s.gsub(repos_dir.to_s + '/', '') + ':'
90
- update_castle castle
91
- end
92
- else
93
- update_castle name
94
- end
95
-
96
- end
97
-
98
- desc 'commit CASTLE MESSAGE', "Commit the specified castle's changes"
99
- def commit(name = DEFAULT_CASTLE_NAME, message = nil)
100
- commit_castle name, message
101
-
102
- end
103
-
104
- desc 'push CASTLE', 'Push the specified castle'
105
- def push(name = DEFAULT_CASTLE_NAME)
106
- push_castle name
107
- end
108
-
109
- desc 'unlink CASTLE', 'Unsymlinks all dotfiles from the specified castle'
110
- def unlink(name = DEFAULT_CASTLE_NAME)
111
- check_castle_existance(name, 'symlink')
112
-
113
- inside castle_dir(name) do
114
- subdirs = subdirs(name)
115
-
116
- # unlink files
117
- unsymlink_each(name, castle_dir(name), subdirs)
118
-
119
- # unlink files in subdirs
120
- subdirs.each do |subdir|
121
- unsymlink_each(name, subdir, subdirs)
122
- end
123
- end
124
- end
125
-
126
- desc 'symlink CASTLE', 'Symlinks all dotfiles from the specified castle'
127
- method_option :force, :default => false, :desc => 'Overwrite existing conflicting symlinks without prompting.'
128
- def symlink(name = DEFAULT_CASTLE_NAME)
129
- check_castle_existance(name, 'symlink')
130
-
131
- inside castle_dir(name) do
132
- subdirs = subdirs(name)
133
-
134
- # link files
135
- symlink_each(name, castle_dir(name), subdirs)
136
-
137
- # link files in subdirs
138
- subdirs.each do |subdir|
139
- symlink_each(name, subdir, subdirs)
140
- end
141
- end
142
- end
143
-
144
- desc 'track FILE CASTLE', 'add a file to a castle'
145
- def track(file, castle = DEFAULT_CASTLE_NAME)
146
- castle = Pathname.new(castle)
147
- file = Pathname.new(file.chomp('/'))
148
- check_castle_existance(castle, 'track')
149
-
150
- absolute_path = file.expand_path
151
- relative_dir = absolute_path.relative_path_from(home_dir).dirname
152
- castle_path = Pathname.new(castle_dir(castle)).join(relative_dir)
153
- FileUtils.mkdir_p castle_path
154
-
155
- # Are we already tracking this or anything inside it?
156
- target = Pathname.new(castle_path.join(file.basename))
157
- if target.exist?
158
- if absolute_path.directory?
159
- move_dir_contents(target, absolute_path)
160
- absolute_path.rmtree
161
- subdir_remove(castle, relative_dir + file.basename)
162
-
163
- elsif more_recent? absolute_path, target
164
- target.delete
165
- mv absolute_path, castle_path
166
- else
167
- shell.say_status(:track, "#{target} already exists, and is more recent than #{file}. Run 'homesick SYMLINK CASTLE' to create symlinks.", :blue) unless options[:quiet]
168
- end
169
- else
170
- mv absolute_path, castle_path
171
- end
172
-
173
- inside home_dir do
174
- absolute_path = castle_path + file.basename
175
- home_path = home_dir + relative_dir + file.basename
176
- ln_s absolute_path, home_path
177
- end
178
-
179
- inside castle_path do
180
- git_add absolute_path
181
- end
182
-
183
- # are we tracking something nested? Add the parent dir to the manifest
184
- subdir_add(castle, relative_dir) unless relative_dir.eql?(Pathname.new('.'))
185
- end
186
-
187
- desc 'list', 'List cloned castles'
188
- def list
189
- inside_each_castle do |castle|
190
- say_status castle.relative_path_from(repos_dir).to_s, `git config remote.origin.url`.chomp, :cyan
191
- end
192
- end
193
-
194
- desc 'status CASTLE', 'Shows the git status of a castle'
195
- def status(castle = DEFAULT_CASTLE_NAME)
196
- check_castle_existance(castle, 'status')
197
- inside repos_dir.join(castle) do
198
- git_status
199
- end
200
- end
201
-
202
- desc 'diff CASTLE', 'Shows the git diff of uncommitted changes in a castle'
203
- def diff(castle = DEFAULT_CASTLE_NAME)
204
- check_castle_existance(castle, 'diff')
205
- inside repos_dir.join(castle) do
206
- git_diff
207
- end
208
- end
209
-
210
- desc 'show_path CASTLE', 'Prints the path of a castle'
211
- def show_path(castle = DEFAULT_CASTLE_NAME)
212
- check_castle_existance(castle, 'show_path')
213
- say repos_dir.join(castle)
214
- end
215
-
216
- desc 'generate PATH', 'generate a homesick-ready git repo at PATH'
217
- def generate(castle)
218
- castle = Pathname.new(castle).expand_path
219
-
220
- github_user = `git config github.user`.chomp
221
- github_user = nil if github_user == ''
222
- github_repo = castle.basename
223
-
224
- empty_directory castle
225
- inside castle do
226
- git_init
227
- if github_user
228
- url = "git@github.com:#{github_user}/#{github_repo}.git"
229
- git_remote_add 'origin', url
230
- end
231
-
232
- empty_directory 'home'
233
- end
234
- end
235
-
236
- desc "destroy CASTLE", "Delete all symlinks and remove the cloned repository"
237
- def destroy(name)
238
- check_castle_existance name, "destroy"
239
-
240
- if shell.yes?("This will destroy your castle irreversible! Are you sure?")
241
- unlink(name)
242
- rm_rf repos_dir.join(name)
243
- end
244
-
245
- end
246
-
247
- desc "cd CASTLE", "Open a new shell in the root of the given castle"
248
- def cd(castle = DEFAULT_CASTLE_NAME)
249
- check_castle_existance castle, "cd"
250
- castle_dir = repos_dir.join(castle)
251
- say_status "cd #{castle_dir.realpath}", "Opening a new shell in castle '#{castle}'. To return to the original one exit from the new shell.", :green
252
- inside castle_dir do
253
- system(ENV['SHELL'])
254
- end
255
- end
256
-
257
- desc "open CASTLE", "Open your default editor in the root of the given castle"
258
- def open(castle = DEFAULT_CASTLE_NAME)
259
- if ! ENV['EDITOR']
260
- say_status :error,"The $EDITOR environment variable must be set to use this command", :red
261
-
262
- exit(1)
263
- end
264
- check_castle_existance castle, "open"
265
- castle_dir = repos_dir.join(castle)
266
- say_status "#{ENV['EDITOR']} #{castle_dir.realpath}", "Opening the root directory of castle '#{castle}' in editor '#{ENV['EDITOR']}'.", :green
267
- inside castle_dir do
268
- system(ENV['EDITOR'])
269
- end
270
- end
271
-
272
- desc 'version', 'Display the current version of homesick'
273
- def version
274
- say Homesick::Version::STRING
275
- end
276
-
277
- protected
278
-
279
- def home_dir
280
- @home_dir ||= Pathname.new(ENV['HOME'] || '~').expand_path
281
- end
282
-
283
- def repos_dir
284
- @repos_dir ||= home_dir.join('.homesick', 'repos').expand_path
285
- end
286
-
287
- def castle_dir(name)
288
- repos_dir.join(name, 'home')
289
- end
290
-
291
- def check_castle_existance(name, action)
292
- unless castle_dir(name).exist?
293
- say_status :error, "Could not #{action} #{name}, expected #{castle_dir(name)} exist and contain dotfiles", :red
294
-
295
- exit(1)
296
- end
297
- end
298
-
299
- def all_castles
300
- dirs = Pathname.glob("#{repos_dir}/**/.git", File::FNM_DOTMATCH)
301
- # reject paths that lie inside another castle, like git submodules
302
- return dirs.reject do |dir|
303
- dirs.any? do |other|
304
- dir != other && dir.fnmatch(other.parent.join('*').to_s)
305
- end
306
- end
307
- end
308
-
309
- def inside_each_castle(&block)
310
- all_castles.each do |git_dir|
311
- castle = git_dir.dirname
312
- Dir.chdir castle do # so we can call git config from the right contxt
313
- yield castle
314
- end
315
- end
316
- end
317
-
318
- def update_castle(castle)
319
- check_castle_existance(castle, 'pull')
320
- inside repos_dir.join(castle) do
321
- git_pull
322
- git_submodule_init
323
- git_submodule_update
324
- end
325
- end
326
-
327
- def commit_castle(castle, message)
328
- check_castle_existance(castle, 'commit')
329
- inside repos_dir.join(castle) do
330
- git_commit_all :message => message
331
- end
332
- end
333
-
334
- def push_castle(castle)
335
- check_castle_existance(castle, 'push')
336
- inside repos_dir.join(castle) do
337
- git_push
338
- end
339
- end
340
-
341
- def subdir_file(castle)
342
- repos_dir.join(castle, SUBDIR_FILENAME)
343
- end
344
-
345
- def subdirs(castle)
346
- subdir_filepath = subdir_file(castle)
347
- subdirs = []
348
- if subdir_filepath.exist?
349
- subdir_filepath.readlines.each do |subdir|
350
- subdirs.push(subdir.chomp)
351
- end
352
- end
353
- subdirs
354
- end
355
-
356
- def subdir_add(castle, path)
357
- subdir_filepath = subdir_file(castle)
358
- File.open(subdir_filepath, 'a+') do |subdir|
359
- subdir.puts path unless subdir.readlines.reduce(false) do |memo, line|
360
- line.eql?("#{path.to_s}\n") || memo
361
- end
362
- end
363
-
364
- inside castle_dir(castle) do
365
- git_add subdir_filepath
366
- end
367
- end
368
-
369
- def subdir_remove(castle, path)
370
- subdir_filepath = subdir_file(castle)
371
- if subdir_filepath.exist?
372
- lines = IO.readlines(subdir_filepath).delete_if { |line| line == "#{path}\n" }
373
- File.open(subdir_filepath, 'w') { |manfile| manfile.puts lines }
374
- end
375
-
376
- inside castle_dir(castle) do
377
- git_add subdir_filepath
378
- end
379
- end
380
-
381
- def move_dir_contents(target, dir_path)
382
- child_files = dir_path.children
383
- child_files.each do |child|
384
-
385
- target_path = target.join(child.basename)
386
- if target_path.exist?
387
- if more_recent?(child, target_path) && target.file?
388
- target_path.delete
389
- mv child, target
390
- end
391
- next
392
- end
393
-
394
- mv child, target
395
- end
396
- end
397
-
398
- def more_recent?(first, second)
399
- first_p = Pathname.new(first)
400
- second_p = Pathname.new(second)
401
- first_p.mtime > second_p.mtime && !first_p.symlink?
402
- end
403
-
404
- def each_file(castle, basedir, subdirs)
405
- absolute_basedir = Pathname.new(basedir).expand_path
406
- inside basedir do
407
- files = Pathname.glob('{.*,*}').reject{ |a| ['.', '..'].include?(a.to_s) }
408
- files.each do |path|
409
- absolute_path = path.expand_path
410
- castle_home = castle_dir(castle)
411
-
412
- # make ignore dirs
413
- ignore_dirs = []
414
- subdirs.each do |subdir|
415
- # ignore all parent of each line in subdir file
416
- Pathname.new(subdir).ascend do |p|
417
- ignore_dirs.push(p)
418
- end
419
- end
420
-
421
- # ignore dirs written in subdir file
422
- matched = false
423
- ignore_dirs.uniq.each do |ignore_dir|
424
- if absolute_path == castle_home.join(ignore_dir)
425
- matched = true
426
- break
427
- end
428
- end
429
- next if matched
430
-
431
- relative_dir = absolute_basedir.relative_path_from(castle_home)
432
- home_path = home_dir.join(relative_dir).join(path)
433
-
434
- yield(absolute_path, home_path)
435
- end
436
- end
437
- end
438
-
439
- def unsymlink_each(castle, basedir, subdirs)
440
- each_file(castle, basedir, subdirs) do |absolute_path, home_path|
441
- rm_link home_path
442
- end
443
- end
444
-
445
- def symlink_each(castle, basedir, subdirs)
446
- each_file(castle, basedir, subdirs) do |absolute_path, home_path|
447
- ln_s absolute_path, home_path
448
- end
449
- end
450
15
  end