dotmation 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: