dotmation 0.0.1 → 0.0.2

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "dotmation"
8
- s.version = "0.0.1"
8
+ s.version = "0.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John T. Prince"]
12
- s.date = "2013-05-09"
12
+ s.date = "2013-05-16"
13
13
  s.description = "ruby dsl/config to softlink dotfiles that is somewhat github aware"
14
14
  s.email = "jtprince@gmail.com"
15
15
  s.executables = ["dotmation"]
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
32
32
  "spec/dotmation/repo_spec.rb",
33
33
  "spec/dotmation_spec.rb",
34
34
  "spec/spec_helper.rb",
35
+ "spec/testfiles/Dropbox/special_stash/dot-fonts/somefile.ttf",
35
36
  "spec/testfiles/config"
36
37
  ]
37
38
  s.homepage = "http://github.com/jtprince/dotmation"
@@ -60,11 +60,11 @@ class Dotmation
60
60
  unless opts[:no_update_github]
61
61
  update_github_repos!
62
62
  end
63
- link!
63
+ link!(opts)
64
64
  end
65
65
 
66
- def link!
67
- repos.each(&:link!)
66
+ def link!(opts={})
67
+ repos.each {|repo| repo.link!(opts) }
68
68
  end
69
69
 
70
70
  def update_github_repos!
@@ -1,6 +1,9 @@
1
1
  require 'fileutils'
2
2
 
3
3
  class Dotmation
4
+ class TryingToSoftLinkOverExistingDir < Exception
5
+ end
6
+
4
7
  module Repo
5
8
  Sys = FileUtils
6
9
 
@@ -25,6 +28,102 @@ class Dotmation
25
28
  self.class.to_s.downcase.split('::').last.to_sym
26
29
  end
27
30
 
31
+ # makes sure the directory exists. If it is a file, deletes the file
32
+ # and makes a directory
33
+ def ensure_dir(dir)
34
+ if File.exist?(dir)
35
+ unless File.directory?(dir)
36
+ File.rm_f(dir)
37
+ ensure_dir(dir)
38
+ end
39
+ else
40
+ Sys.mkpath(dir)
41
+ end
42
+ true
43
+ end
44
+
45
+ def no_trailing_slash(dir)
46
+ (dir[-1] == '/') ? dir[0...-1] : dir
47
+ end
48
+
49
+ # returns true if defined and there is a trailing slash
50
+ def link_to_reside_under_dir?(dir)
51
+ dir && (dir[-1] == '/')
52
+ end
53
+
54
+ def ensure_underdir( link )
55
+ dir = File.dirname(link)
56
+ Sys.mkpath(dir)
57
+ end
58
+
59
+ # path/file => .file
60
+ # path/.file => .file
61
+ # path/to/file => .file
62
+ # file => .file
63
+ # .file => .file
64
+ def base_dot(file_path)
65
+ base = file_path.split('/').last
66
+ (base[0] == '.') ? base[0] : ('.' + base)
67
+ end
68
+
69
+ # clears @link upon all successul linkages
70
+ def link!(opts={})
71
+ opts[:home] ||= ENV['HOME']
72
+ opts[:config_home] ||= Dotmation::CONFIG_HOME
73
+ [:home, :config_home].each {|sym| opts[sym] = no_trailing_slash(opts[sym]) }
74
+
75
+ ensure_dir( opts[:config_home] )
76
+ ensure_dir( opts[:home] )
77
+
78
+ real_base_dir = self.respond_to?(:cache_dir) ? cache_dir : File.expand_path(opts[:home])
79
+
80
+ Dir.chdir(real_base_dir) do
81
+ Dir.chdir(self.path) do
82
+ @links.each do |link|
83
+ has_slashes = link.linkname && link.linkname.include?("/")
84
+ link_to_reside_under_dir = link_to_reside_under_dir?(link.linkname)
85
+ symlink =
86
+ case link.methd
87
+ when :cfg
88
+ File.join( opts[:config_home], link.linkname || '' )
89
+ when :dot
90
+ if link.linkname
91
+ File.join( opts[:home], link.linkname )
92
+ else
93
+ File.join( opts[:home], (link.file[0]=='.') ? link.file : base_dot(link.file) )
94
+ end
95
+ when :ln
96
+ if link.linkname
97
+ File.join( opts[:home], link.linkname )
98
+ else
99
+ File.join( opts[:home], link.file )
100
+ end
101
+ end
102
+
103
+ if link.linkname && link.linkname.include?('/')
104
+ ensure_underdir( symlink )
105
+ end
106
+ ensure_dir( symlink ) if link_to_reside_under_dir
107
+ if File.exist?(symlink)
108
+ if File.directory?(symlink) && !link_to_reside_under_dir && !File.symlink?(symlink) && has_slashes
109
+ raise Dotmation::TryingToSoftLinkOverExistingDir, "a real directory already exists where you are trying to place a softlink, delete it before proceeding or trail the symlink with a slash in your config file to put the link under it: #{symlink}"
110
+ elsif !File.directory?(symlink) && !File.symlink?(symlink)
111
+ File.unlink(symlink)
112
+ end
113
+ end
114
+ file_to_link = File.expand_path(link.file)
115
+ #puts "TO LINK AN D SYMLINK:"
116
+ #p File.exist?(file_to_link)
117
+ #p file_to_link
118
+ #p symlink
119
+ Sys.ln_sf(file_to_link, symlink)
120
+ end
121
+ # clear all the links
122
+ @links.clear
123
+ end
124
+ end
125
+ end
126
+
28
127
  class Local
29
128
  include Repo
30
129
  end
@@ -53,82 +152,6 @@ class Dotmation
53
152
  path_parts[2..-1].join('/')
54
153
  end
55
154
 
56
- # makes sure the directory exists. If it is a file, deletes the file
57
- # and makes a directory
58
- def ensure_dir(dir)
59
- if File.exist?(dir)
60
- unless File.directory?(dir)
61
- File.rm_f(dir)
62
- ensure_dir(dir)
63
- end
64
- else
65
- Sys.mkpath(dir)
66
- end
67
- true
68
- end
69
-
70
- def no_trailing_slash(dir)
71
- (dir[-1] == '/') ? dir[0...-1] : dir
72
- end
73
-
74
- # returns true if defined and there is a trailing slash
75
- def target_is_dir?(dir)
76
- dir && (dir[-1] == '/')
77
- end
78
-
79
- def ensure_underdir( link )
80
- dir = File.dirname(link)
81
- Sys.mkpath(dir)
82
- end
83
-
84
- def link!(opts={})
85
- opts[:home] ||= ENV['HOME']
86
- opts[:config_home] ||= Dotmation::CONFIG_HOME
87
- [:home, :config_home].each {|sym| opts[sym] = no_trailing_slash(opts[sym]) }
88
-
89
- ensure_dir( opts[:config_home] )
90
- ensure_dir( opts[:home] )
91
-
92
- Dir.chdir(cache_dir) do
93
- Dir.chdir(self.path) do
94
- @links.each do |link|
95
- target_is_dir = target_is_dir?(link.linkname)
96
- symlink =
97
- case link.methd
98
- when :cfg
99
- File.join( opts[:config_home], link.linkname || '' )
100
- when :dot
101
- if link.linkname
102
- File.join( opts[:home], link.linkname )
103
- else
104
- File.join( opts[:home], (link.file[0]=='.') ? link.file : ".#{link.file}" )
105
- end
106
- when :ln
107
- if link.linkname
108
- File.join( opts[:home], link.linkname )
109
- else
110
- File.join( opts[:home], link.file )
111
- end
112
- end
113
-
114
- if link.linkname && link.linkname.include?('/')
115
- ensure_underdir( symlink )
116
- end
117
- ensure_dir( symlink ) if target_is_dir
118
- if File.exist?(symlink) && !File.directory?(symlink)
119
- File.unlink(symlink)
120
- end
121
- file_to_link = File.expand_path(link.file)
122
- #puts "TO LINK AN D SYMLINK:"
123
- #p File.exist?(file_to_link)
124
- #p file_to_link
125
- #p symlink
126
- Sys.ln_sf(file_to_link, symlink)
127
- end
128
- end
129
- end
130
- end
131
-
132
155
  end
133
156
  end
134
157
  end
@@ -13,6 +13,10 @@ describe Dotmation::Repo do
13
13
  @internal_git_dir = @cache_dir + '/user/project'
14
14
  FileUtils.mkpath @internal_git_dir
15
15
  @file = @internal_git_dir + "/myfile"
16
+ @dir = @internal_git_dir + "/somedir"
17
+ @internal_file = @dir + "/internal"
18
+ FileUtils.mkpath( @dir )
19
+ File.write(@internal_file, 'it is internal')
16
20
  File.write(@file, 'hiya')
17
21
  end
18
22
 
@@ -36,6 +40,50 @@ describe Dotmation::Repo do
36
40
  FileUtils.rm_rf cfg_dir
37
41
  end
38
42
 
43
+ specify 'can make links relative to folder inside dir' do
44
+ cfg_dir = File.expand_path(TESTFILES + '/tmp_cfg')
45
+
46
+ repo = Dotmation::Repo::Github.new('user/project/somedir')
47
+
48
+ repo.cache_dir = @cache_dir
49
+
50
+ repo.links << Dotmation::Repo::Link.new(:cfg, "internal")
51
+ repo.links << Dotmation::Repo::Link.new(:cfg, ".")
52
+ # this will ln the directory under: creating/a/path/somedir
53
+ repo.links << Dotmation::Repo::Link.new(:cfg, ".", "creating/a/path/")
54
+
55
+ repo.link!(config_home: cfg_dir)
56
+
57
+ %w(internal somedir creating/a/path/somedir).each do |linkname|
58
+ link = cfg_dir + '/' + linkname
59
+ File.symlink?(link).should be_true
60
+ end
61
+ File.directory?(cfg_dir + '/' + 'creating/a/path').should be_true
62
+ File.directory?(cfg_dir + '/' + 'somedir').should be_true
63
+ IO.read(cfg_dir + '/' + 'internal').should == 'it is internal'
64
+
65
+ FileUtils.rm_rf cfg_dir
66
+ end
67
+
68
+ specify 'links as the directory if none exists but will not overwrite if a dir does' do
69
+ cfg_dir = File.expand_path(TESTFILES + '/tmp_cfg')
70
+
71
+ repo = Dotmation::Repo::Github.new('user/project/somedir')
72
+
73
+ repo.cache_dir = @cache_dir
74
+
75
+ # this will ln the directory under: creating/a/path/somedir
76
+ repo.links << Dotmation::Repo::Link.new(:cfg, ".", "creating/a/path")
77
+ repo.links << Dotmation::Repo::Link.new(:cfg, ".", "creating/a")
78
+
79
+ expect { repo.link!(config_home: cfg_dir) }.to raise_error(Dotmation::TryingToSoftLinkOverExistingDir)
80
+
81
+ File.symlink?(cfg_dir + '/' + 'creating/a/path').should be_true
82
+ File.symlink?(cfg_dir + '/' + 'creating/a').should be_false
83
+
84
+ FileUtils.rm_rf cfg_dir
85
+ end
86
+
39
87
  specify 'dot makes proper links to home dir' do
40
88
  home_dir = File.expand_path(TESTFILES + '/tmp_home')
41
89
  repo = Dotmation::Repo::Github.new('user/project')
@@ -34,30 +34,66 @@ describe Dotmation do
34
34
 
35
35
  end
36
36
 
37
- describe 'an update' do
37
+ describe 'updating with local files' do
38
+ before do
39
+ cfg = <<MESSAGE
40
+ local "Dropbox/special_stash" do
41
+ dot "dot-fonts", "fonts"
42
+ end
43
+ MESSAGE
44
+ HERE!
45
+ @dotmation = Dotmation.new()
46
+ end
47
+ end
48
+
49
+ describe 'a real update', :pending => 'only run occasionally -- requires internet' do
38
50
  #describe 'an update', :pending => 'only run occasionally -- requires internet' do
39
51
  let(:dotmation) { Dotmation.new(@config) }
40
52
 
41
53
  before(:all) do
42
54
  @tmprepos_dir = TESTFILES + "/tmprepos"
55
+ @fake_home = TESTFILES + '/fake_home'
56
+ FileUtils.mkpath @fake_home
57
+ @fake_config_home = TESTFILES + '/fake_home/config'
58
+ FileUtils.mkpath @fake_config_home
59
+ @orig_home = ENV['HOME']
60
+ ENV['HOME'] = @fake_home
43
61
  end
44
62
 
45
63
  # turn on when you want to test github download
46
64
  it 'downloads github repos' do
47
- dotmation.update
65
+ dotmation.update( home: @fake_home, config_home: @fake_config_home )
48
66
  ["jtprince/dotfiles", "robbyrussell/oh-my-zsh"].each do |path|
67
+ # The repos are all there
49
68
  base = @tmprepos_dir + "/" + path
50
69
  git_file = base + "/.git"
51
- File.exist?( git_file ).should be_true
70
+ File.directory?( git_file ).should be_true
71
+ end
72
+
73
+ # the links are all there
74
+ %w(dotmation dunstrc zsh i3/config).each do |f|
75
+ link = @fake_config_home + '/' + f
76
+ File.symlink?(link).should be_true
77
+ File.exist?(link).should be_true
78
+ case f
79
+ when 'dotmation', 'zsh'
80
+ File.directory?(link).should be_true
81
+ end
52
82
  end
83
+
84
+ File.exist?(@fake_home + '/' + '.fonts')
85
+ File.symlink?(@fake_home + '/' + '.fonts')
53
86
  end
54
87
 
55
- it 'updates existing repos' do
88
+ xit 'updates existing repos' do
56
89
  dotmation.update
57
90
  end
58
91
 
59
92
  after(:all) do
60
- FileUtils.rm_rf(@tmprepos_dir) if File.directory?(@tmprepos_dir)
93
+ #FileUtils.rm_rf(@tmprepos_dir) if File.directory?(@tmprepos_dir)
94
+ #FileUtils.rm_rf(@fake_home)
95
+ #FileUtils.rm_rf(@fake_config_home)
96
+ ENV['HOME'] = @orig_home
61
97
  end
62
98
  end
63
99
 
@@ -9,19 +9,18 @@ github "jtprince/dotfiles/config" do # stored in ~/dotrepos/jtprince/dotfile
9
9
 
10
10
  dot 'Xresources' # symlink ~/.Xresources
11
11
  dot 'Xresources', '.Xdefaults' # symlink ~/.Xdefaults -> Xresources
12
+ # same as this:
13
+ # dot 'Xresources', 'Xdefaults' # symlink ~/.Xdefaults -> Xresources
12
14
  dot 'zsh/zshenv' # symlink ~/.zshenv
13
15
  end
14
16
 
15
17
  github "jtprince/dotfiles" do
16
- ln 'bin'
17
- ln 'bin', '~/local/'
18
- ln 'bin', '~/local/bin' # same as directly above
19
- ln 'bin', '~/local' # would link to local if not exist or local/bin if local existed
18
+ ln 'config/irbrc', '~/local/'
20
19
  end
21
20
 
22
21
  # always interpreted from $HOME
23
22
  local "Dropbox/special_stash" do
24
- dot "dot-fonts", ".fonts"
23
+ dot "dot-fonts", "fonts" # ~/.fonts
25
24
  end
26
25
 
27
26
  github "robbyrussell/oh-my-zsh" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotmation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-09 00:00:00.000000000 Z
12
+ date: 2013-05-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -114,6 +114,7 @@ files:
114
114
  - spec/dotmation/repo_spec.rb
115
115
  - spec/dotmation_spec.rb
116
116
  - spec/spec_helper.rb
117
+ - spec/testfiles/Dropbox/special_stash/dot-fonts/somefile.ttf
117
118
  - spec/testfiles/config
118
119
  homepage: http://github.com/jtprince/dotmation
119
120
  licenses:
@@ -130,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
130
131
  version: '0'
131
132
  segments:
132
133
  - 0
133
- hash: 2585038009321147917
134
+ hash: -3068326634373493455
134
135
  required_rubygems_version: !ruby/object:Gem::Requirement
135
136
  none: false
136
137
  requirements: