gitenv 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +110 -1
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/gitenv.gemspec +4 -4
- data/lib/gitenv.rb +1 -1
- data/lib/gitenv/action.rb +11 -5
- data/lib/gitenv/config.rb +7 -3
- data/lib/gitenv/context.rb +30 -9
- data/lib/gitenv/controller.rb +134 -15
- data/lib/gitenv/copy.rb +60 -4
- data/lib/gitenv/symlink.rb +33 -34
- data/lib/program.rb +9 -2
- metadata +4 -4
data/README.md
CHANGED
@@ -1,6 +1,115 @@
|
|
1
1
|
# gitenv
|
2
2
|
|
3
|
-
|
3
|
+
Creates symlinks to your configuration files in a git repository (<a href="https://github.com/AlphaHydrae/env">like mine</a>).
|
4
|
+
|
5
|
+
Run gitenv without arguments to check the symlink configuration. First-time users will be prompted to enter the path to their environment repository so gitenv can set up its own config file.
|
6
|
+
|
7
|
+
#=> gitenv
|
8
|
+
|
9
|
+
~/.gemrc -> ~/projects/env/.gemrc ok
|
10
|
+
~/.gitconfig -> ~/projects/env/.gitconfig not yet set up
|
11
|
+
~/.zshrc -> ~/projects/env/.zshrc not yet set up
|
12
|
+
|
13
|
+
Then run it with **update** to set up the missing symlinks.
|
14
|
+
|
15
|
+
#=> gitenv update
|
16
|
+
|
17
|
+
~/.gemrc -> ~/projects/env/.gemrc ok
|
18
|
+
~/.gitconfig -> ~/projects/env/.gitconfig ok
|
19
|
+
~/.zshrc -> ~/projects/env/.zshrc ok
|
20
|
+
|
21
|
+
Read on for <a href="#configuration">more advanced options</a>.
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
gem install gitenv
|
26
|
+
|
27
|
+
<a name="configuration"></a>
|
28
|
+
## Configuration
|
29
|
+
|
30
|
+
If your repository is more complex than a bunch of dot files or you want to put the links somewhere other than in your home folder, you will have to customize your configuration file. Gitenv prompts you to create one the first time you run it. It looks for `~/.gitenv.rb` by default. You can override this with the `-c, --config` option or by setting the `GITENV_CONFIG` environment variable.
|
31
|
+
|
32
|
+
The following sections demonstrate the various options you can customize in the configuration file.
|
33
|
+
|
34
|
+
### Repository
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# Path to your environment repository.
|
38
|
+
repo '~/projects/env'
|
39
|
+
|
40
|
+
# Note that you can also set the GITENV_REPO environment variable.
|
41
|
+
```
|
42
|
+
|
43
|
+
### Symlinks
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
# This will create symlinks in your home folder to all dot files (e.g. .vimrc, .gitconfig) in the repository.
|
47
|
+
symlink dot_files
|
48
|
+
|
49
|
+
# This creates symlinks for all files, not just dot files.
|
50
|
+
symlink all_files
|
51
|
+
|
52
|
+
# You can also create symlinks one at a time.
|
53
|
+
symlink '.zshrc'
|
54
|
+
symlink 'my_config_file'
|
55
|
+
|
56
|
+
# If you want the name of link to be different than that of the file, use the :as option.
|
57
|
+
symlink 'zshconfig', :as => '.zshconfig'
|
58
|
+
```
|
59
|
+
|
60
|
+
### Sub-folders in the repository
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
# If your configuration file or files are in a sub-folder, use #from to tell gitenv where to find them.
|
64
|
+
from 'subfolder' do
|
65
|
+
symlink dot_files
|
66
|
+
end
|
67
|
+
|
68
|
+
# The following syntax is also available.
|
69
|
+
symlink('.zshrc').from('zsh')
|
70
|
+
symlink(all_files).from('a/b/c')
|
71
|
+
|
72
|
+
# You can chain several #from calls to traverse hierarchies.
|
73
|
+
from 'a' do
|
74
|
+
from 'b' do
|
75
|
+
from 'c' do
|
76
|
+
# Symlink all dot files in a/b/c in your repository.
|
77
|
+
symlink dot_files
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
### Change the destination
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
# If you want to put the symlinks somewhere other than in your home folder, use #to.
|
87
|
+
to 'links' do
|
88
|
+
symlink dot_files
|
89
|
+
end
|
90
|
+
|
91
|
+
# The following syntax is also available.
|
92
|
+
symlink('.zshrc').to('links')
|
93
|
+
symlink(all_files).to('a/b/c')
|
94
|
+
|
95
|
+
# Paths are relative to your home folder. If you need an absolute path, use #to_abs.
|
96
|
+
symlink('my_config_file').to_abs('/opt/config')
|
97
|
+
```
|
98
|
+
|
99
|
+
### Copy files
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
# Gitenv can also copy files instead of creating symlinks.
|
103
|
+
copy dot_files
|
104
|
+
|
105
|
+
# Path modifiers work the same as for symlinks.
|
106
|
+
copy(dot_files).from('zsh')
|
107
|
+
copy('my_config_file').to('configs')
|
108
|
+
```
|
109
|
+
|
110
|
+
### Symlinks or copies in system directories
|
111
|
+
|
112
|
+
Just use `sudo`. Gitenv will happily set up your symlinks. You might have to add the `-E` switch to keep gitenv in the PATH.
|
4
113
|
|
5
114
|
## License (MIT)
|
6
115
|
|
data/Rakefile
CHANGED
@@ -17,8 +17,8 @@ Jeweler::Tasks.new do |gem|
|
|
17
17
|
gem.name = "gitenv"
|
18
18
|
gem.homepage = "http://github.com/AlphaHydrae/gitenv"
|
19
19
|
gem.license = "MIT"
|
20
|
-
gem.summary = %Q{
|
21
|
-
gem.description = %Q{
|
20
|
+
gem.summary = %Q{Symlink manager for git repositories with configuration files.}
|
21
|
+
gem.description = %Q{Gitenv sets up symlinks to your configuration files in a git repository.}
|
22
22
|
gem.email = "hydrae.alpha@gmail.com"
|
23
23
|
gem.authors = ["AlphaHydrae"]
|
24
24
|
# dependencies defined in Gemfile
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.5
|
data/gitenv.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "gitenv"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["AlphaHydrae"]
|
12
|
-
s.date = "2012-09-
|
13
|
-
s.description = "
|
12
|
+
s.date = "2012-09-24"
|
13
|
+
s.description = "Gitenv sets up symlinks to your configuration files in a git repository."
|
14
14
|
s.email = "hydrae.alpha@gmail.com"
|
15
15
|
s.executables = ["gitenv"]
|
16
16
|
s.extra_rdoc_files = [
|
@@ -50,7 +50,7 @@ Gem::Specification.new do |s|
|
|
50
50
|
s.licenses = ["MIT"]
|
51
51
|
s.require_paths = ["lib"]
|
52
52
|
s.rubygems_version = "1.8.24"
|
53
|
-
s.summary = "
|
53
|
+
s.summary = "Symlink manager for git repositories with configuration files."
|
54
54
|
|
55
55
|
if s.respond_to? :specification_version then
|
56
56
|
s.specification_version = 3
|
data/lib/gitenv.rb
CHANGED
data/lib/gitenv/action.rb
CHANGED
@@ -4,14 +4,20 @@ module Gitenv
|
|
4
4
|
class Action
|
5
5
|
include Context
|
6
6
|
|
7
|
-
def initialize config, type, files
|
8
|
-
@type, @files = type, files
|
7
|
+
def initialize config, type, files, options
|
8
|
+
@type, @files, @options = type, files, options
|
9
9
|
copy! config
|
10
10
|
end
|
11
11
|
|
12
|
-
def each &block
|
13
|
-
@files.each
|
14
|
-
block.call @type.new(self, f)
|
12
|
+
def each options = {}, &block
|
13
|
+
@files.each from_path do |f|
|
14
|
+
block.call @type.new(self, f, @options.merge(options))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def each_file &block
|
19
|
+
@files.each from_path do |f|
|
20
|
+
block.call File.join(from_path, f)
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
data/lib/gitenv/config.rb
CHANGED
@@ -5,7 +5,7 @@ module Gitenv
|
|
5
5
|
include Context
|
6
6
|
|
7
7
|
attr_reader :actions
|
8
|
-
|
8
|
+
attr_accessor :repository
|
9
9
|
attr_reader :home
|
10
10
|
|
11
11
|
def initialize home
|
@@ -17,8 +17,12 @@ module Gitenv
|
|
17
17
|
@repository = File.expand_path path
|
18
18
|
end
|
19
19
|
|
20
|
-
def symlink file
|
21
|
-
Action.new(self, Symlink, enumerator(file)).tap{ |a| @actions << a }
|
20
|
+
def symlink file, options = {}
|
21
|
+
Action.new(self, Symlink, enumerator(file), options).tap{ |a| @actions << a }
|
22
|
+
end
|
23
|
+
|
24
|
+
def copy file, options = {}
|
25
|
+
Action.new(self, Copy, enumerator(file), options).tap{ |a| @actions << a }
|
22
26
|
end
|
23
27
|
|
24
28
|
def all_files
|
data/lib/gitenv/context.rb
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
module Gitenv
|
3
3
|
|
4
4
|
module Context
|
5
|
-
attr_accessor :
|
6
|
-
attr_accessor :from_paths, :to_paths
|
5
|
+
attr_accessor :from_paths, :to_paths, :absolute
|
7
6
|
|
8
7
|
def from path, &block
|
9
8
|
(@from_paths ||= []) << path
|
@@ -11,10 +10,11 @@ module Gitenv
|
|
11
10
|
instance_eval &block
|
12
11
|
@from_paths.pop
|
13
12
|
end
|
13
|
+
self
|
14
14
|
end
|
15
15
|
|
16
16
|
def from_path
|
17
|
-
@from_paths ? File.join(
|
17
|
+
@from_paths ? File.join(*([ @config.repository, @from_paths ].flatten)) : @config.repository
|
18
18
|
end
|
19
19
|
|
20
20
|
def to path, &block
|
@@ -23,17 +23,38 @@ module Gitenv
|
|
23
23
|
instance_eval &block
|
24
24
|
@to_paths.pop
|
25
25
|
end
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_abs path, &block
|
30
|
+
previous = @to_paths
|
31
|
+
@to_paths = [ path ]
|
32
|
+
@absolute = true
|
33
|
+
if block
|
34
|
+
instance_eval &block
|
35
|
+
@to_paths = previous
|
36
|
+
@absolute = false
|
37
|
+
end
|
38
|
+
self
|
26
39
|
end
|
27
40
|
|
28
41
|
def to_path
|
29
|
-
@to_paths ? File.join(
|
42
|
+
@to_paths ? File.join(*(@absolute ? @to_paths : [ @config.home, @to_paths ]).flatten) : @config.home
|
43
|
+
end
|
44
|
+
|
45
|
+
def copy! config
|
46
|
+
self.from_paths = config.from_paths ? config.from_paths.dup : []
|
47
|
+
self.to_paths = config.to_paths ? config.to_paths.dup : []
|
48
|
+
self.absolute = config.absolute
|
49
|
+
@config = config
|
50
|
+
end
|
51
|
+
|
52
|
+
def home
|
53
|
+
@config.home
|
30
54
|
end
|
31
55
|
|
32
|
-
def
|
33
|
-
|
34
|
-
self.to_paths = source.to_paths ? source.to_paths.dup : []
|
35
|
-
self.repository = source.repository
|
36
|
-
self.home = source.home
|
56
|
+
def repository
|
57
|
+
@config.repository
|
37
58
|
end
|
38
59
|
end
|
39
60
|
end
|
data/lib/gitenv/controller.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'readline'
|
1
2
|
|
2
3
|
module Gitenv
|
3
4
|
|
@@ -13,10 +14,30 @@ module Gitenv
|
|
13
14
|
end
|
14
15
|
|
15
16
|
def run
|
17
|
+
|
18
|
+
check_config_file!
|
19
|
+
|
20
|
+
if !File.exists?(config_file) and !repository
|
21
|
+
create_config_file!
|
22
|
+
end
|
23
|
+
|
16
24
|
load_config_file!
|
25
|
+
|
26
|
+
@config.repository = repository
|
27
|
+
check_repository!
|
28
|
+
|
29
|
+
# load dot files by default
|
30
|
+
if @config.actions.empty?
|
31
|
+
@config.symlink @config.dot_files
|
32
|
+
end
|
33
|
+
|
34
|
+
check_files!
|
35
|
+
|
36
|
+
longest = 0
|
37
|
+
@config.actions.each{ |a| a.each{ |impl| longest = impl.description.length if impl.description.length > longest } }
|
38
|
+
|
17
39
|
@config.actions.each do |a|
|
18
|
-
a.each do |impl|
|
19
|
-
impl.build!
|
40
|
+
a.each :justify => longest + 3 do |impl|
|
20
41
|
impl.update! if @action == :update
|
21
42
|
puts impl
|
22
43
|
end
|
@@ -25,25 +46,123 @@ module Gitenv
|
|
25
46
|
|
26
47
|
private
|
27
48
|
|
49
|
+
def create_config_file!
|
50
|
+
|
51
|
+
file = config_file
|
52
|
+
unless agree "You have no configuration file (#{file}); do you wish to create one? (y/n) "
|
53
|
+
puts
|
54
|
+
abort "To use gitenv, you must either create a configuration file\nor specify an environment repository with the -r, --repo option."
|
55
|
+
end
|
56
|
+
|
57
|
+
repo = @options.repo || ENV['GITENV_REPO']
|
58
|
+
unless repo
|
59
|
+
Readline.completion_append_character = '/'
|
60
|
+
Readline.completion_proc = Proc.new do |str|
|
61
|
+
Dir[str+'*'].grep /^#{Regexp.escape(str)}/
|
62
|
+
end
|
63
|
+
begin
|
64
|
+
repo = Readline.readline('Type the path to your environment repository: ', true)
|
65
|
+
rescue Interrupt
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
if !repo or repo.strip.empty?
|
71
|
+
puts; abort "You must specify an environment repository."
|
72
|
+
elsif !File.directory?(File.expand_path(repo))
|
73
|
+
puts; abort "No such directory #{repo}."
|
74
|
+
end
|
75
|
+
|
76
|
+
config = String.new.tap do |s|
|
77
|
+
s << %|\n# Path to your environment repository.|
|
78
|
+
s << %|\nrepo "#{repo}"\n|
|
79
|
+
s << %|\n# Create symlinks in your home folder.|
|
80
|
+
s << %|\nsymlink dot_files\n\n|
|
81
|
+
end
|
82
|
+
|
83
|
+
File.open(file, 'w'){ |f| f.write config }
|
84
|
+
|
85
|
+
puts
|
86
|
+
puts Paint["Successfully wrote configuration to #{file}", :green]
|
87
|
+
puts
|
88
|
+
end
|
89
|
+
|
90
|
+
def repository
|
91
|
+
@options.repo || @config.repository || ENV['GITENV_REPO']
|
92
|
+
end
|
93
|
+
|
94
|
+
def config_file
|
95
|
+
if @options.config
|
96
|
+
File.expand_path @options.config
|
97
|
+
elsif ENV['GITENV_CONFIG']
|
98
|
+
File.expand_path ENV['GITENV_CONFIG']
|
99
|
+
else
|
100
|
+
File.join @home, '.gitenv.rb'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
28
104
|
def load_config_file!
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
105
|
+
file = config_file
|
106
|
+
return unless File.exists? file
|
107
|
+
contents = File.open(file, 'r').read
|
108
|
+
@config.instance_eval contents, file
|
109
|
+
end
|
110
|
+
|
111
|
+
def check_files!
|
112
|
+
problems = []
|
113
|
+
@config.actions.each do |a|
|
114
|
+
a.each_file do |f|
|
115
|
+
if !File.exists?(f)
|
116
|
+
problems << { :file => f, :msg => "does not exist" }
|
117
|
+
elsif !File.file?(f)
|
118
|
+
problems << { :file => f, :msg => "is not a file" }
|
119
|
+
elsif !File.readable?(f)
|
120
|
+
problems << { :file => f, :msg => "is not readable" }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
return unless problems.any?
|
126
|
+
|
127
|
+
msg = "There are problems with the following files in your repository:"
|
128
|
+
problems.each do |p|
|
129
|
+
msg << "\n #{p[:file]} #{p[:msg]}"
|
130
|
+
end
|
131
|
+
abort msg
|
132
|
+
end
|
133
|
+
|
134
|
+
def check_config_file!
|
135
|
+
file = config_file
|
136
|
+
return if !File.exists?(file)
|
137
|
+
if !File.file?(file)
|
138
|
+
abort "#{file} is not a file. It cannot be used as a configuration file."
|
139
|
+
elsif !File.readable?(file)
|
140
|
+
abort "#{file} is not readable. It cannot be used as a configuration file."
|
39
141
|
end
|
142
|
+
end
|
40
143
|
|
41
|
-
|
42
|
-
|
144
|
+
def check_repository!
|
145
|
+
if !@config.repository
|
146
|
+
msg = "You have not specified an environment repository."
|
147
|
+
msg << "\nYou must either use the -r, --repo option or create"
|
148
|
+
msg << "\na configuration file (~/.gitenv.rb by default) with"
|
149
|
+
msg << "\nthe repo setting."
|
150
|
+
abort msg
|
151
|
+
end
|
152
|
+
return if File.directory? @config.repository
|
153
|
+
notice = File.exists?(@config.repository) ? 'is not a directory' : 'does not exist'
|
154
|
+
from = if @options.repo
|
155
|
+
"--repo #{@options.repo}"
|
156
|
+
elsif ENV['GITENV_REPO']
|
157
|
+
"$GITENV_REPO = #{ENV['GITENV_REPO']}"
|
158
|
+
else
|
159
|
+
%/repo "#{@config.repository}"/
|
160
|
+
end
|
161
|
+
abort "The repository you have specified #{notice}.\n (#{from})"
|
43
162
|
end
|
44
163
|
|
45
164
|
def abort msg, code = 1
|
46
|
-
warn
|
165
|
+
warn Paint[msg, :red]
|
47
166
|
exit code
|
48
167
|
end
|
49
168
|
end
|
data/lib/gitenv/copy.rb
CHANGED
@@ -1,12 +1,68 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'fileutils'
|
3
|
+
require 'digest/sha1'
|
1
4
|
|
2
5
|
module Gitenv
|
3
6
|
|
4
7
|
class Copy
|
5
|
-
include Context
|
6
8
|
|
7
|
-
def initialize config, file
|
8
|
-
@config, @file = config, file
|
9
|
-
|
9
|
+
def initialize config, file, options = {}
|
10
|
+
@config, @file, @options = config, file, options
|
11
|
+
end
|
12
|
+
|
13
|
+
def update!
|
14
|
+
if File.exists?(target) && !File.exists?(target_copy)
|
15
|
+
FileUtils.mv target, target_copy
|
16
|
+
end
|
17
|
+
if !File.exists?(target)
|
18
|
+
FileUtils.copy source, target
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
color, mark, msg = status
|
24
|
+
justification = @options[:justify] ? ' ' * (@options[:justify] - description.length) : ''
|
25
|
+
%/ #{Paint[mark, color]} #{Paint[target, :cyan]} << #{source}#{justification}#{Paint[msg, color]}/
|
26
|
+
end
|
27
|
+
|
28
|
+
def description
|
29
|
+
"#{target} << #{source}"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def status
|
35
|
+
if !File.exists?(target)
|
36
|
+
[ :blue, "✗", "is not set up; update will create the copy" ]
|
37
|
+
elsif digest(source) == digest(target)
|
38
|
+
[ :green, "✓", "ok" ]
|
39
|
+
elsif File.exists?(target_copy)
|
40
|
+
[ :red, "✗", "already exists with backup copy" ]
|
41
|
+
else
|
42
|
+
[ :blue, "✗", "already exists; update will backup the file and create the copy" ]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def target
|
47
|
+
@target ||= File.join(*[ @config.to_path, target_name].compact)
|
48
|
+
end
|
49
|
+
|
50
|
+
def target_copy
|
51
|
+
@target_copy ||= "#{target}.orig"
|
52
|
+
end
|
53
|
+
|
54
|
+
def target_name
|
55
|
+
@options[:as] || @file
|
56
|
+
end
|
57
|
+
|
58
|
+
def source
|
59
|
+
@source ||= File.join(*[ @config.from_path, @file ].compact)
|
60
|
+
end
|
61
|
+
|
62
|
+
def digest file
|
63
|
+
Digest::SHA1.new.tap do |dig|
|
64
|
+
File.open(file, 'rb'){ |io| dig.update io.readpartial(4096) while !io.eof }
|
65
|
+
end
|
10
66
|
end
|
11
67
|
end
|
12
68
|
end
|
data/lib/gitenv/symlink.rb
CHANGED
@@ -3,59 +3,58 @@
|
|
3
3
|
module Gitenv
|
4
4
|
|
5
5
|
class Symlink
|
6
|
-
include Context
|
7
6
|
|
8
|
-
def initialize config, file
|
9
|
-
@config, @file = config, file
|
10
|
-
copy! config
|
11
|
-
end
|
12
|
-
|
13
|
-
def build!
|
14
|
-
@color, @mark, @message = if File.symlink? link
|
15
|
-
@current_target = File.expand_path File.readlink(link)
|
16
|
-
if @current_target == target
|
17
|
-
[ :green, "✓", "ok" ]
|
18
|
-
else
|
19
|
-
[ :yellow, "✗", "currently points to #{@current_target}" ]
|
20
|
-
end
|
21
|
-
elsif File.file? link
|
22
|
-
[ :red, "✗", "is a file" ]
|
23
|
-
elsif File.directory? link
|
24
|
-
[ :red, "✗", "is a directory" ]
|
25
|
-
elsif File.exists? link
|
26
|
-
[ :red, "✗", "exists but is not a symlink" ]
|
27
|
-
else
|
28
|
-
[ :blue, "✓", "is not set up" ]
|
29
|
-
end
|
7
|
+
def initialize config, file, options = {}
|
8
|
+
@config, @file, @options = config, file, options
|
30
9
|
end
|
31
10
|
|
32
11
|
def update!
|
33
|
-
|
12
|
+
unless File.exists? link
|
34
13
|
File.symlink target, link
|
35
|
-
@color, @mark, @message = :green, "✓", "ok"
|
36
14
|
end
|
37
15
|
end
|
38
16
|
|
39
17
|
def to_s
|
40
|
-
|
18
|
+
color, mark, msg = status
|
19
|
+
justification = @options[:justify] ? ' ' * (@options[:justify] - description.length) : ''
|
20
|
+
%/ #{Paint[mark, color]} #{Paint[link, :cyan]} -> #{target}#{justification}#{Paint[msg, color]}/
|
41
21
|
end
|
42
22
|
|
43
|
-
|
44
|
-
|
45
|
-
def status_mark
|
46
|
-
Paint["#{@mark}", @color]
|
23
|
+
def description
|
24
|
+
"#{link} -> #{target}"
|
47
25
|
end
|
48
26
|
|
49
|
-
|
50
|
-
|
27
|
+
private
|
28
|
+
|
29
|
+
def status
|
30
|
+
if File.symlink? link
|
31
|
+
current_target = File.expand_path File.readlink(link)
|
32
|
+
if current_target == target
|
33
|
+
[ :green, "✓", "ok" ]
|
34
|
+
else
|
35
|
+
[ :yellow, "✗", "currently points to #{current_target}; update will overwrite" ]
|
36
|
+
end
|
37
|
+
elsif File.file? link
|
38
|
+
[ :red, "✗", "is a file; update will ignore" ]
|
39
|
+
elsif File.directory? link
|
40
|
+
[ :red, "✗", "is a directory; update will ignore" ]
|
41
|
+
elsif File.exists? link
|
42
|
+
[ :red, "✗", "exists but is not a symlink; update will ignore" ]
|
43
|
+
else
|
44
|
+
[ :blue, "✗", "is not set up; update will create the link" ]
|
45
|
+
end
|
51
46
|
end
|
52
47
|
|
53
48
|
def link
|
54
|
-
File.join(*[ @config.
|
49
|
+
@link ||= File.join(*[ @config.to_path, link_name].compact)
|
55
50
|
end
|
56
51
|
|
57
52
|
def target
|
58
|
-
File.join(*[ @config.
|
53
|
+
@target ||= File.join(*[ @config.from_path, @file ].compact)
|
54
|
+
end
|
55
|
+
|
56
|
+
def link_name
|
57
|
+
@options[:as] || @file
|
59
58
|
end
|
60
59
|
end
|
61
60
|
end
|
data/lib/program.rb
CHANGED
@@ -5,20 +5,27 @@ program :name, 'gitenv'
|
|
5
5
|
program :version, Gitenv::VERSION
|
6
6
|
program :description, 'Symlink manager for git repositories with configuration files.'
|
7
7
|
|
8
|
+
global_option '-r', '--repo PATH', 'Specify the path to the environment repository'
|
9
|
+
global_option '-c', '--config PATH', 'Use a custom configuration file (defaults to ~/.gitenv.rb)'
|
10
|
+
|
8
11
|
command :info do |c|
|
12
|
+
c.syntax = 'gitenv info'
|
13
|
+
c.description = 'Display the current configuration (default action)'
|
9
14
|
c.action do |args,options|
|
10
15
|
Gitenv::Controller.new(:info, options).run
|
11
16
|
end
|
12
17
|
end
|
13
18
|
|
14
19
|
command :update do |c|
|
20
|
+
c.syntax = 'gitenv update'
|
21
|
+
c.description = 'Create/update the symlinks'
|
15
22
|
c.action do |args,options|
|
16
23
|
Gitenv::Controller.new(:update, options).run
|
17
24
|
end
|
18
25
|
end
|
19
26
|
|
20
|
-
|
21
|
-
|
27
|
+
# TODO: add a verbose option (show repo, show config file path)
|
28
|
+
# TODO: add link to documentation in help
|
22
29
|
|
23
30
|
default_command :info
|
24
31
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitenv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
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: 2012-09-
|
12
|
+
date: 2012-09-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: paint
|
@@ -171,7 +171,7 @@ dependencies:
|
|
171
171
|
- - ! '>='
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '0'
|
174
|
-
description:
|
174
|
+
description: Gitenv sets up symlinks to your configuration files in a git repository.
|
175
175
|
email: hydrae.alpha@gmail.com
|
176
176
|
executables:
|
177
177
|
- gitenv
|
@@ -231,5 +231,5 @@ rubyforge_project:
|
|
231
231
|
rubygems_version: 1.8.24
|
232
232
|
signing_key:
|
233
233
|
specification_version: 3
|
234
|
-
summary:
|
234
|
+
summary: Symlink manager for git repositories with configuration files.
|
235
235
|
test_files: []
|