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 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
- ### Setup Dotify
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
- Do you want to add .bachrc to Dotify? [Yn] n
32
- Do you want to add .gitconfig to Dotify? [Yn] y
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
- This will first create a `.dotify` directory in your home directory (yes, only one more dot directory, but this time it is a good thing). It will then ask which files you want to copy from your home directory into your `.dotify` directory.
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
- **This will *not* link up the dotfiles. This command simply copies the files over for you without having to go searching for them manually.**
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
- remove /Users/computer-user/.bashrc
131
+ remove /Users/computer-user/.bashrc
78
132
  Are you sure you want to remove ~/.gemrc? [Yn] Y
79
- remove /Users/computer-user/.gemrc
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:
@@ -16,5 +16,8 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Dotify::VERSION
17
17
 
18
18
  gem.add_dependency "thor"
19
+ gem.add_dependency "json"
19
20
  gem.add_development_dependency "rspec"
21
+ gem.add_development_dependency "webmock"
22
+ gem.add_development_dependency "vcr"
20
23
  end
@@ -1,4 +1,9 @@
1
- module Dotify
2
- end
3
1
  require 'bundler/setup'
2
+ require 'dotify/config'
4
3
  require "fileutils"
4
+
5
+ module Dotify
6
+ def self.installed?
7
+ Config.installed?
8
+ end
9
+ end
@@ -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 'fileutils'
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 "-l" => :link
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
- Config.home
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 :link, :default => false, :type => :boolean, :aliases => '-l', :desc => "Link dotfiles when setup is complete"
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
- empty_directory(Config.path) unless File.directory?(Config.path)
28
- Files.unlinked do |path, file|
29
- add(file) unless Config.dirname == file
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 } if options[:link]
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
- file = Files.file_name(file)
42
- dotfile = Files.dotfile(file)
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.quiet?
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.quiet?
95
+ say_status :removed, Files.dotify(file) unless options[:quiet] == true
81
96
  end
82
97
  end
83
98
 
84
- desc :link, "Link up all of your dotfiles"
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
- count = 0
88
- Files.dots do |file, dot|
89
- if options[:all]
90
- if File.exists? Files.dotfile(file)
91
- replace_link Files.dotfile(file), file
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 :unlink, "Unlink all of your dotfiles"
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
- count = 0
115
- Files.installed do |file, dot|
116
- if options[:all] || yes?("Are you sure you want to remove ~/#{dot}? [Yn]", :yellow)
117
- remove_file Files.dotfile(file)
118
- count += 1
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
@@ -6,61 +6,29 @@ module Dotify
6
6
  class Config
7
7
 
8
8
  DOTIFY_DIRNAME = '.dotify'
9
- DOTIFY_BACKUP = '.backup'
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 path
42
- File.join(home, dirname)
17
+ def installed?
18
+ File.directory?(File.join(home, dirname))
43
19
  end
44
20
 
45
- def backup
46
- File.join(path, backup_dirname)
21
+ def path
22
+ File.join(home, dirname)
47
23
  end
48
24
 
49
- def backup_dirname
50
- @backup ||= DOTIFY_BACKUP
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 load_config!
54
- #@config = File.exists?(config_file) ? (YAML.load_file(config_file) || {}) : {}
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
- #File.join(home, '.dotrc')
45
+ File.join(home, DOTIFY_CONFIG)
78
46
  end
79
47
 
80
48
  def symbolize_keys!(opts)