dotify 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +68 -8
- data/dotify.gemspec +3 -0
- data/lib/dotify.rb +7 -2
- data/lib/dotify/cli.rb +115 -55
- data/lib/dotify/config.rb +11 -43
- data/lib/dotify/file_list.rb +41 -0
- data/lib/dotify/files.rb +28 -29
- data/lib/dotify/version.rb +1 -1
- data/lib/dotify/version_checker.rb +29 -0
- data/spec/dotify/cli_spec.rb +0 -1
- data/spec/dotify/config_spec.rb +25 -45
- data/spec/dotify/file_list_spec.rb +113 -0
- data/spec/dotify/files_spec.rb +55 -33
- data/spec/dotify/version_checker_spec.rb +33 -0
- data/spec/fixtures/.dotrc-default +5 -2
- data/spec/fixtures/vcr/version_check.yml +74 -0
- data/spec/spec_helper.rb +0 -3
- data/spec/support/vcr.rb +6 -0
- data/spec/support/with_constants.rb +49 -0
- data/templates/.dotrc +14 -0
- data/templates/.gitkeep +0 -0
- metadata +64 -6
- data/spec/fixtures/.dotrc-mattbridges +0 -3
- data/spec/support/fake.rb +0 -39
data/README.md
CHANGED
@@ -4,6 +4,16 @@
|
|
4
4
|
|
5
5
|
Dotify is a simple CLI tool to make managing dotfiles on your system easy. When developing on a Linux/Unix basic system, keeping track of all of those dotfiles in the home directory can be pain. Some developers do not even bother managing them and many have come up with their own static or even dynamic way of managing them. This is a need in the community, and this tool makes managing these crazy files a breeze.
|
6
6
|
|
7
|
+
## Ruby Version Support
|
8
|
+
|
9
|
+
As this is a gem for use on your local system, I understand there are still many Ruby developers still stuck with using Ruby 1.8. As such, Dotify supports the following Ruby versions definitively:
|
10
|
+
|
11
|
+
* 1.8.7
|
12
|
+
* 1.9.2
|
13
|
+
* 1.9.3
|
14
|
+
* JRuby
|
15
|
+
* Rubinius
|
16
|
+
|
7
17
|
## Installation
|
8
18
|
|
9
19
|
Add this line to your application's Gemfile:
|
@@ -22,19 +32,57 @@ Or install it yourself as:
|
|
22
32
|
|
23
33
|
As dotify is a CLI tool, everything is done in the command line. Here are the current available methods for managing dotfiles.
|
24
34
|
|
25
|
-
###
|
35
|
+
### Preparing your system for Dotify
|
26
36
|
|
27
37
|
To setup Dotify, you must first run `dotify setup` in your terminal.
|
28
38
|
|
29
39
|
$ dotify setup
|
30
40
|
create /Users/computer-user/.dotify
|
31
|
-
|
32
|
-
|
33
|
-
|
41
|
+
create /Users/computer-user/.dotrc
|
42
|
+
|
43
|
+
This will first create a `.dotify` directory in your home directory as well as a `.dotrc` file for Dotify configuration (yes, it is more dotfiles, but this is a good thing!).
|
44
|
+
|
45
|
+
In order to install files from the home directory into Dotify, you must run the `install` task.
|
46
|
+
|
47
|
+
### The .dotrc file
|
48
|
+
|
49
|
+
The `.dotrc` file in your home directory serves as the configuration file for Dotify.
|
50
|
+
|
51
|
+
#### Ignoring files
|
52
|
+
|
53
|
+
When you are linking files in your Dotify directory, some files you do not want ever want to link (`.git`, `.gitmodules`, `.gitignore`, .etc) because they are used specifically for that directory (such as git versioning). You can configure Dotify to ignore these files when calling `dotify link` in the `.dotrc` in this way:
|
54
|
+
|
55
|
+
$ cat ~/.dotrc
|
56
|
+
ignore:
|
57
|
+
dotify:
|
58
|
+
- '.git'
|
59
|
+
- '.gitmodules'
|
60
|
+
- '.gitignore'
|
34
61
|
|
35
|
-
|
62
|
+
The same can be done for the home directory when running `dotify setup`. There are some directories that you should not move around (`.dropbox`, `.rbenv`, `.rvm`) and do not want to accidentally attempt to move. You can do that in your `.dotrc` file as well:
|
36
63
|
|
37
|
-
|
64
|
+
$ cat ~/.dotrc
|
65
|
+
ignore:
|
66
|
+
dotfiles:
|
67
|
+
- '.dropbox'
|
68
|
+
- '.rbenv'
|
69
|
+
- '.rvm'
|
70
|
+
|
71
|
+
More configuration options will likely be added in future versions, so be sure to check up here for your options.
|
72
|
+
|
73
|
+
### Install Dotify
|
74
|
+
|
75
|
+
Now that you have configured Dotify to your liking, you should now run `dotify install`.
|
76
|
+
|
77
|
+
$ dotify install
|
78
|
+
Do you want to add .bash_history to Dotify? [Yn] n
|
79
|
+
Do you want to add .bashrc to Dotify? [Yn] y
|
80
|
+
create /Users/mattbridges/.dotify/.bashrc
|
81
|
+
Do you want to add .railsrc to Dotify? [Yn] n
|
82
|
+
create /Users/mattbridges/.dotify/.railsrc
|
83
|
+
Do you want to add .zshrc to Dotify? [Yn] n
|
84
|
+
create /Users/mattbridges/.dotify/.zshrc
|
85
|
+
...
|
38
86
|
|
39
87
|
### Add single files
|
40
88
|
|
@@ -68,20 +116,32 @@ This is the heart of the Dotify tool. This command will link the files within th
|
|
68
116
|
Do you want to link ~/.gitignore? [Yn] Y
|
69
117
|
...
|
70
118
|
|
119
|
+
You can also link files one-by-one by passing the filename to the `link` task.
|
120
|
+
|
121
|
+
$ dotify link .bashrc
|
122
|
+
Do you want to link ~/.bashrc? [Yn] Y
|
123
|
+
create /Users/computer-user/.bashrc
|
124
|
+
|
71
125
|
### Unlink everything
|
72
126
|
|
73
127
|
Don't want any of the dotfiles anymore? Well, I'm not one to question. Go ahead and wipe them out.
|
74
128
|
|
75
129
|
$ dotify unlink
|
76
130
|
Are you sure you want to remove ~/.bashrc? [Yn] Y
|
77
|
-
|
131
|
+
remove /Users/computer-user/.bashrc
|
78
132
|
Are you sure you want to remove ~/.gemrc? [Yn] Y
|
79
|
-
|
133
|
+
remove /Users/computer-user/.gemrc
|
80
134
|
Are you sure you want to remove ~/.gitconfig? [Yn] n
|
81
135
|
...
|
82
136
|
|
83
137
|
Should you run this horrid task accidentally, you can simply run `dotify link` again if you want to restore your previous settings.
|
84
138
|
|
139
|
+
By default, `unlink` loops through all of the Dotify files. You can also pass a filename to `unlink` to unlink a single file.
|
140
|
+
|
141
|
+
$ dotify unlink .bashrc
|
142
|
+
Are you sure you want to remove ~/.bashrc? [Yn] Y
|
143
|
+
remove /Users/mattbridges/.bashrc
|
144
|
+
|
85
145
|
## Confused?
|
86
146
|
|
87
147
|
Dotify can manages dotfiles from two different directions:
|
data/dotify.gemspec
CHANGED
data/lib/dotify.rb
CHANGED
data/lib/dotify/cli.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require 'thor'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'json'
|
4
|
+
require 'net/http'
|
5
|
+
|
2
6
|
require 'dotify'
|
3
7
|
require 'dotify/config'
|
4
8
|
require 'dotify/files'
|
5
|
-
require '
|
9
|
+
require 'dotify/file_list'
|
10
|
+
require 'dotify/version_checker'
|
6
11
|
|
7
12
|
Dotify::Config.load_config!
|
8
13
|
|
@@ -11,52 +16,61 @@ module Dotify
|
|
11
16
|
include Thor::Actions
|
12
17
|
default_task :help
|
13
18
|
|
14
|
-
map
|
15
|
-
map "-u" => :unlink
|
19
|
+
map %w[-v --version] => :version
|
16
20
|
map "-s" => :setup
|
17
21
|
map "-a" => :add
|
18
22
|
map "-r" => :remove
|
23
|
+
map "-l" => :link
|
24
|
+
map "-u" => :unlink
|
19
25
|
|
20
26
|
def self.source_root
|
21
|
-
|
27
|
+
File.expand_path("../../../templates", __FILE__)
|
28
|
+
end
|
29
|
+
|
30
|
+
desc :version, "Check your Dotify version"
|
31
|
+
def version
|
32
|
+
if VersionChecker.out_of_date?
|
33
|
+
say "Your version of Dotify is out of date.", :yellow
|
34
|
+
say " Your Version: #{Dotify::VERSION}", :blue
|
35
|
+
say " Latest Version: #{VersionChecker.version}", :blue
|
36
|
+
say "I recommend that you uninstall Dotify completely before updating", :yellow
|
37
|
+
else
|
38
|
+
say "Your version of Dotify is up to date: #{Dotify::VERSION}", :blue
|
39
|
+
end
|
40
|
+
rescue Exception
|
41
|
+
say "There was an error checking your Dotify version. Please try again.", :red
|
22
42
|
end
|
23
43
|
|
24
44
|
desc :setup, "Setup your system for Dotify to manage your dotfiles"
|
25
|
-
method_option :
|
45
|
+
method_option :install, :default => false, :type => :boolean, :aliases => '-i', :desc => "Run Dotify install right away. This does not allow for customizing your .dotrc file before attempting install files into Dotify."
|
46
|
+
method_option :verbose, :default => true, :type => :boolean, :aliases => '-v', :desc => "Setup Dotify with verbose output."
|
26
47
|
def setup
|
27
|
-
|
28
|
-
|
29
|
-
|
48
|
+
return say('Dotify has already been setup!', :blue) if Dotify.installed?
|
49
|
+
empty_directory(Config.path, :verbose => options[:verbose])
|
50
|
+
dotrc = File.join(Config.home, Config::DOTIFY_CONFIG)
|
51
|
+
template Config::DOTIFY_CONFIG, dotrc, :verbose => options[:verbose]
|
52
|
+
invoke :install if options[:install] == true
|
53
|
+
end
|
54
|
+
|
55
|
+
desc :install, "Install files from your home directory into Dotify"
|
56
|
+
method_option :link, :default => false, :type => :boolean, :aliases => '-l', :desc => "Link dotfiles when setup is complete"
|
57
|
+
def install
|
58
|
+
invoke :setup unless Dotify.installed?
|
59
|
+
Files.uninstalled do |path, file|
|
60
|
+
add_file(file, options.merge(:quiet => true)) unless Config.dirname == file
|
30
61
|
end
|
31
62
|
say "Dotify has been successfully setup.", :blue
|
32
63
|
if options[:link]
|
33
64
|
say "Linking up the new dotfiles...", :blue
|
34
|
-
invoke :link, nil, { :all => true }
|
65
|
+
invoke :link, nil, { :all => true }
|
35
66
|
end
|
36
67
|
end
|
37
68
|
|
38
69
|
desc "add [FILENAME]", "Add a single dotfile to the Dotify directory"
|
39
70
|
method_option :force, :default => false, :type => :boolean, :aliases => '-f', :desc => "Add file without confirmation"
|
40
71
|
def add(file)
|
41
|
-
|
42
|
-
|
43
|
-
dotify_file = Files.dotify(file)
|
44
|
-
case
|
45
|
-
when !File.exist?(dotfile)
|
46
|
-
say "'~/#{file}' does not exist", :blue
|
47
|
-
when File.identical?(dotfile, dotify_file)
|
48
|
-
say "'~/#{file}' is already identical to '~/.dotify/#{file}'", :blue
|
49
|
-
else
|
50
|
-
if options[:force] == true || yes?("Do you want to add #{file} to Dotify? [Yn]", :yellow)
|
51
|
-
if File.directory?(dotfile)
|
52
|
-
FileUtils.rm_rf dotify_file
|
53
|
-
FileUtils.cp_r dotfile, dotify_file
|
54
|
-
say_status :create, dotify_file
|
55
|
-
else
|
56
|
-
copy_file dotfile, dotify_file
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
72
|
+
return not_setup_warning unless Dotify.installed?
|
73
|
+
add_file(file, options)
|
60
74
|
end
|
61
75
|
|
62
76
|
desc "remove [FILENAME]", "Remove a single dotfile from Dotify"
|
@@ -69,60 +83,106 @@ module Dotify
|
|
69
83
|
method_option :force, :default => false, :type => :boolean, :aliases => '-f', :desc => "Remove file without confirmation"
|
70
84
|
method_option :quiet, :default => false, :type => :boolean, :aliases => '-q', :desc => "Don't output anything"
|
71
85
|
def remove(file)
|
86
|
+
return not_setup_warning unless Dotify.installed?
|
72
87
|
if !File.exists?(Files.dotify(file))
|
73
|
-
say "Dotify is not currently managing ~/#{file}.", :blue unless options
|
88
|
+
say "Dotify is not currently managing ~/#{file}.", :blue unless options[:quiet] == true
|
74
89
|
return
|
75
90
|
end
|
76
91
|
if options[:force] == true || yes?("Are you sure you want to remove #{file} from Dotify? [Yn]", :yellow)
|
77
92
|
remove_file Files.dotfile(file), :verbose => false
|
78
93
|
copy_file Files.dotify(file), Files.dotfile(file), :verbose => false
|
79
94
|
remove_file Files.dotify(file), :verbose => false
|
80
|
-
say_status :removed, Files.dotify(file) unless options
|
95
|
+
say_status :removed, Files.dotify(file) unless options[:quiet] == true
|
81
96
|
end
|
82
97
|
end
|
83
98
|
|
84
|
-
desc
|
99
|
+
desc 'link {{FILENAME}}', "Link up one or all of your dotfiles (FILENAME is optional)"
|
85
100
|
method_option :all, :default => false, :type => :boolean, :aliases => '-a', :desc => "Link dotfiles without confirmation"
|
86
|
-
def link
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
else
|
93
|
-
create_link Files.dotfile(file), file
|
94
|
-
end
|
95
|
-
count += 1
|
96
|
-
else
|
97
|
-
if yes?("Do you want to link ~/#{dot}? [Yn]", :yellow)
|
98
|
-
create_link Files.dotfile(file), file
|
99
|
-
count += 1
|
100
|
-
end
|
101
|
+
def link(file=nil)
|
102
|
+
return not_setup_warning unless Dotify.installed?
|
103
|
+
if file.nil?
|
104
|
+
count = 0
|
105
|
+
Files.dots do |file, dot|
|
106
|
+
count += 1 if link_file(file, dot, options) == true
|
101
107
|
end
|
108
|
+
say "No files were linked.", :blue if count == 0
|
109
|
+
else
|
110
|
+
link_file(file, Files.filename(file), options)
|
102
111
|
end
|
103
|
-
say "No files were linked.", :blue if count == 0
|
104
112
|
end
|
105
113
|
|
106
|
-
desc
|
114
|
+
desc 'unlink {{FILENAME}}', "Unlink one or all of your dotfiles (FILENAME is optional)"
|
107
115
|
long_desc <<-STRING
|
108
116
|
`dotify unlink` removes the dotfiles from the home directory and preserves the
|
109
117
|
files in the Dotify directory. This allows you to simply run `dotify link` again
|
110
118
|
should you decide you want to relink anything to the Dotify files.
|
111
119
|
STRING
|
112
120
|
method_option :all, :default => false, :type => :boolean, :aliases => '-a', :desc => 'Remove all installed dotfiles without confirmation'
|
113
|
-
def unlink
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
121
|
+
def unlink(file = nil)
|
122
|
+
return not_setup_warning unless Dotify.installed?
|
123
|
+
if file.nil?
|
124
|
+
count = 0
|
125
|
+
Files.installed do |file, dot|
|
126
|
+
if options[:all] || yes?("Are you sure you want to remove ~/#{dot}? [Yn]", :yellow)
|
127
|
+
unlink_file(file)
|
128
|
+
count += 1
|
129
|
+
end
|
119
130
|
end
|
131
|
+
say "No files were unlinked.", :blue if count == 0
|
132
|
+
else
|
133
|
+
unlink_file(file)
|
120
134
|
end
|
121
|
-
say "No files were unlinked.", :blue if count == 0
|
122
135
|
end
|
123
136
|
|
124
137
|
no_tasks do
|
125
138
|
|
139
|
+
def not_setup_warning
|
140
|
+
say('Dotify has not been setup yet! You need to run \'dotify setup\' first.', :yellow)
|
141
|
+
end
|
142
|
+
|
143
|
+
def unlink_file(file)
|
144
|
+
remove_file Files.dotfile(file)
|
145
|
+
return true
|
146
|
+
end
|
147
|
+
|
148
|
+
def link_file(file, dot, options = {})
|
149
|
+
if options[:all]
|
150
|
+
if File.exists? Files.dotfile(file)
|
151
|
+
replace_link Files.dotfile(file), file
|
152
|
+
else
|
153
|
+
create_link Files.dotfile(file), file
|
154
|
+
end
|
155
|
+
return true
|
156
|
+
else
|
157
|
+
if yes?("Do you want to link ~/#{dot}? [Yn]", :yellow)
|
158
|
+
create_link Files.dotfile(file), file
|
159
|
+
return true
|
160
|
+
end
|
161
|
+
return false
|
162
|
+
end
|
163
|
+
return false
|
164
|
+
end
|
165
|
+
|
166
|
+
def add_file(file, options = {})
|
167
|
+
file = Files.filename(file)
|
168
|
+
dotfile = Files.dotfile(file)
|
169
|
+
dotify_file = Files.dotify(file)
|
170
|
+
|
171
|
+
if !File.exist?(dotfile) || !File.identical?(dotfile, dotify_file)
|
172
|
+
if options[:force] == true || yes?("Do you want to add #{file} to Dotify? [Yn]", :yellow)
|
173
|
+
if File.directory?(dotfile)
|
174
|
+
FileUtils.rm_rf dotify_file
|
175
|
+
FileUtils.cp_r dotfile, dotify_file
|
176
|
+
say_status :create, dotify_file
|
177
|
+
else
|
178
|
+
copy_file dotfile, dotify_file
|
179
|
+
end
|
180
|
+
end
|
181
|
+
else
|
182
|
+
say "'#{file}' does not exist or is already installed in Dotify.", :blue unless options[:quiet] == true
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
126
186
|
def replace_link(dotfile, file)
|
127
187
|
remove_file dotfile, :verbose => false
|
128
188
|
create_link dotfile, file, :verbose => false
|
data/lib/dotify/config.rb
CHANGED
@@ -6,61 +6,29 @@ module Dotify
|
|
6
6
|
class Config
|
7
7
|
|
8
8
|
DOTIFY_DIRNAME = '.dotify'
|
9
|
-
|
10
|
-
#SHELLS = {
|
11
|
-
# 'zsh' => '/bin/zsh',
|
12
|
-
# 'bash' => '/bin/bash',
|
13
|
-
# 'sh' => '/bin/sh'
|
14
|
-
#}
|
9
|
+
DOTIFY_CONFIG = '.dotrc'
|
15
10
|
|
16
11
|
class << self
|
17
12
|
|
18
|
-
#def shell=(shell)
|
19
|
-
# if !SHELLS.keys.include?(shell)
|
20
|
-
# raise NonValidShell, "You must specify a valid shell: #{SHELLS.keys.map(&:inspect).join(", ")}"
|
21
|
-
# end
|
22
|
-
# @shell = shell
|
23
|
-
#end
|
24
|
-
|
25
|
-
#def shell
|
26
|
-
# @shell
|
27
|
-
#end
|
28
|
-
|
29
|
-
#def profile=(name)
|
30
|
-
# @profile = name
|
31
|
-
#end
|
32
|
-
|
33
|
-
#def profile
|
34
|
-
# @profile
|
35
|
-
#end
|
36
|
-
|
37
13
|
def dirname
|
38
14
|
@dirname ||= DOTIFY_DIRNAME
|
39
15
|
end
|
40
16
|
|
41
|
-
def
|
42
|
-
File.join(home, dirname)
|
17
|
+
def installed?
|
18
|
+
File.directory?(File.join(home, dirname))
|
43
19
|
end
|
44
20
|
|
45
|
-
def
|
46
|
-
File.join(
|
21
|
+
def path
|
22
|
+
File.join(home, dirname)
|
47
23
|
end
|
48
24
|
|
49
|
-
def
|
50
|
-
|
25
|
+
def load_config!
|
26
|
+
config = File.exists?(config_file) ? (YAML.load_file(config_file) || {}) : {}
|
27
|
+
symbolize_keys!(config)
|
51
28
|
end
|
52
29
|
|
53
|
-
def
|
54
|
-
|
55
|
-
#symbolize_keys!(@config)
|
56
|
-
#@config.each do |key, value|
|
57
|
-
# if !value.nil? && methods(false).map(&:to_s).include?("#{key}=")
|
58
|
-
# self.__send__("#{key}=", value)
|
59
|
-
# else
|
60
|
-
# @config.delete(key)
|
61
|
-
# end
|
62
|
-
#end
|
63
|
-
#@config
|
30
|
+
def ignore(what)
|
31
|
+
config.fetch(:ignore, {}).fetch(what, [])
|
64
32
|
end
|
65
33
|
|
66
34
|
def config
|
@@ -74,7 +42,7 @@ module Dotify
|
|
74
42
|
private
|
75
43
|
|
76
44
|
def config_file
|
77
|
-
|
45
|
+
File.join(home, DOTIFY_CONFIG)
|
78
46
|
end
|
79
47
|
|
80
48
|
def symbolize_keys!(opts)
|