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 +1 -1
- data/dotmation.gemspec +3 -2
- data/lib/dotmation.rb +3 -3
- data/lib/dotmation/repo.rb +99 -76
- data/spec/dotmation/repo_spec.rb +48 -0
- data/spec/dotmation_spec.rb +41 -5
- data/spec/testfiles/Dropbox/special_stash/dot-fonts/somefile.ttf +0 -0
- data/spec/testfiles/config +4 -5
- metadata +4 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/dotmation.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "dotmation"
|
8
|
-
s.version = "0.0.
|
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-
|
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"
|
data/lib/dotmation.rb
CHANGED
@@ -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
|
66
|
+
def link!(opts={})
|
67
|
+
repos.each {|repo| repo.link!(opts) }
|
68
68
|
end
|
69
69
|
|
70
70
|
def update_github_repos!
|
data/lib/dotmation/repo.rb
CHANGED
@@ -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
|
data/spec/dotmation/repo_spec.rb
CHANGED
@@ -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')
|
data/spec/dotmation_spec.rb
CHANGED
@@ -34,30 +34,66 @@ describe Dotmation do
|
|
34
34
|
|
35
35
|
end
|
36
36
|
|
37
|
-
describe '
|
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.
|
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
|
-
|
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
|
|
File without changes
|
data/spec/testfiles/config
CHANGED
@@ -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 '
|
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", "
|
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.
|
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-
|
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:
|
134
|
+
hash: -3068326634373493455
|
134
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
136
|
none: false
|
136
137
|
requirements:
|