effuse 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +6 -0
  3. data/README.md +92 -26
  4. data/bin/effuse +2 -160
  5. data/effuse.gemspec +14 -9
  6. data/lib/effuse.rb +211 -0
  7. metadata +11 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e208d054b1eb72349a276a147661a166d1ebe4f
4
- data.tar.gz: d2e9ea2a776e62cfa3e1f4ae75ba4f6308d43e9a
3
+ metadata.gz: 01fcca7a41037832b35adf55ac340137179f2b52
4
+ data.tar.gz: b5eddc54ee5243de924620a40eef9c27e8a59216
5
5
  SHA512:
6
- metadata.gz: 2823430b0105b2bd90fbe46e8a62920cc0830e2675320123ce25c08b35586b5d2e185b33c0c1ea163052ec78471774cea0ceb20729ec2cac1e2b14ec30a39334
7
- data.tar.gz: c91052dda97b8a0e8ff34a3bbe2041b118911386faed70bbe9a2ff211b50dbc913ff9802f6953b19457ae208029385f3ca83b59a93fb08bcdbadd76accb3b9c2
6
+ metadata.gz: c2e4b5451947f1c3aa09e7c6d5622f51bc6a60bd3a17b89c5185a929a69f13f9b8c6903e6b61cfa4a2e15ed91d16aa82d67821ee9da2336c0590276a00ebc14f
7
+ data.tar.gz: 4cb6206d5d4a6d5ea70478505c1bd08ea00ca18af8b008b9f04cd16d54e7a2d512099bfc90383743587298a42d0313e82c88c50a3b663b22ba212d75b834b262
data/ChangeLog.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Change Log
2
2
 
3
+ ## 2.1.0 (November 10 2013)
4
+
5
+ * Added support for `effuse.yml` files
6
+ * Deprecated `.effuseignore` files
7
+ * Added `--version` option
8
+
3
9
  ## 2.0.1 (May 14 2013)
4
10
 
5
11
  * Fix: Backup files by appending `.effuse`
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Effuse
2
2
 
3
- A tool for symlinking dotfiles
3
+ Tool for symlinking dotfiles.
4
4
 
5
5
  ## Install
6
6
 
@@ -10,54 +10,121 @@ gem install effuse
10
10
 
11
11
  ## Usage
12
12
 
13
- So, say you have all your precious dotfiles in a nice little git repository or
14
- Dropbox folder or whatever else you might use. It's a great way to be able to
15
- use your configurations on multiple computers, but how do you get those
16
- configurations out of the repository and into your filesystem?
13
+ So, say you have all your precious dotfiles in a nice little git
14
+ repository or Dropbox folder or whatever else you might use. It's a
15
+ great way to be able to use your configurations on multiple computers,
16
+ but how do you get those configurations out of the repository and into
17
+ your filesystem?
17
18
 
18
- The answer: symbolic links. Lots of them. And how do you go about creating all
19
- these symlinks? Sure, you could create each one by hand, but you're a busy
20
- person and obviously don't have time for such menial tasks. Luckily, you've
21
- just discovered Effuse!
19
+ The answer: symbolic links. Lots of them. And how do you go about
20
+ creating all these symlinks? Sure, you could create each one by hand,
21
+ but you're a busy person and obviously don't have time for such menial
22
+ tasks. Luckily, you've just discovered Effuse!
22
23
 
23
- Just run `effuse` in your dotfiles repository and it will automagically create
24
- symlinks to all your configurations in your home directory!
24
+ Just run `effuse` in your dotfiles repository and it will automagically
25
+ create symlinks to all your configurations in your home directory!
25
26
 
26
- Your configurations don't go in your home directory? No problem! Just run
27
- `effuse /path/` and the symlinks will be created wherever your heart desires.
27
+ Your configurations don't go in your home directory? No problem! Just
28
+ run `effuse /path/` and the symlinks will be created wherever your heart
29
+ desires.
28
30
 
29
31
  Would you rather import a dotfile from your system into your repository
30
32
  than replace it? No problem, just use `effuse --import`.
31
33
 
32
- Symlinks aren't working out for you? Effuse has got you covered. Just run
33
- `effuse --clean` in your dotfiles repository and it will remove all those nasty
34
- symlinks it created before.
34
+ Symlinks aren't working out for you? Effuse has got you covered. Just
35
+ run `effuse --clean` in your dotfiles repository and it will remove all
36
+ those nasty symlinks it created before.
35
37
 
36
38
  Don't want to symlink a certain bothersome file? Why not tell Effuse
37
- your opinion on the matter using `effuse --exclude file`? Or why not
38
- give it a stern talking to using a `.effuseignore` file? Just put one
39
- file glob to exclude per line in there and never worry again.
39
+ your opinion on the matter using `effuse --exclude file`?
40
+
41
+ Maybe you don't like to have the files in your dotfiles repository named
42
+ with leading dots. If that's what floats your boat, you can have Effuse
43
+ prefix the symlink paths using `effuse --prefix .`.
44
+
45
+ Now, say you want to create symlinks in `~/foo`, you want to exclude
46
+ `*.bak` files, and you want to prefix your symlink paths with `.`.
47
+ Specifying all those on the command line every time you run Effuse
48
+ sounds horrible, doesn't it? Luckily, you can use an `effuse.yml` file
49
+ instead!
50
+
51
+ ```yaml
52
+ destination: ~/foo
53
+ prefix: .
54
+ exclude:
55
+ - '*.bak'
56
+ ```
57
+
58
+ ### Example
59
+
60
+ ```sh
61
+ ~ $ cd dotfiles
62
+ dotfiles $ ls -a
63
+ . .. .vimrc .zshrc .zsh
64
+ dotfiles $ ls .zsh
65
+ foo.zsh
66
+ dotfiles $ effuse
67
+ '/home/you/.vimrc' -> '/home/you/dotfiles/.vimrc'
68
+ '/home/you/.zshrc' -> '/home/you/dotfiles/.zshrc'
69
+ '/home/you/.zsh/foo.zsh' -> '/home/you/dotfiles/.zsh/foo.zsh'
70
+ dotfiles $ file ~/.zsh/foo.zsh
71
+ /home/you/.zsh/foo.zsh: symbolic link to `/home/you/dotfiles/.zsh/foo.zsh`
72
+ ```
73
+
74
+ ### Command Line
40
75
 
41
76
  ```
42
- Usage: effuse [OPTIONS] [DEST]
77
+ usage: effuse [OPTIONS...] [DEST]
43
78
  -i, --import Import existing files
44
79
  -c, --clean Remove symlinks
45
80
 
46
- --exclude GLOB Exclude GLOB from symlinking
47
- --include GLOB Include GLOB in symlinking
48
-
49
81
  -y, --no-confirm Do not ask before replacing files
50
82
  -n, --no-backup Do not create backup files
51
83
 
52
- -p, --prefix PREFIX Prefix symlinked paths with PREFIX
84
+ --exclude GLOB Exclude GLOB from symlinking
85
+ --include GLOB Include GLOB in symlinking
86
+
87
+ -p, --prefix Prefix symlink paths with PREFIX
53
88
 
54
89
  -v, --verbose Show verbose output
90
+
91
+ --version Show version
55
92
  -h, --help Show this message
56
93
  ```
57
94
 
95
+ ### YAML File
96
+
97
+ The `effuse.yml` file may contain the following keys:
98
+
99
+ * `destination`: Symlink destination directory (defaults to `~`)
100
+ * `prefix`: Symlink path prefix
101
+ * `exclude`: Array of globs to exclude from symlinking
102
+ * `include`: Array of globs to not exclude from symlinking
103
+
104
+ ### Migrating from 2.0 to 2.1
105
+
106
+ Version 2.1 of Effuse deprecates the use of `.effuseignore` files in
107
+ favor of `effuse.yml` files. To migrate, add each line of the ignore
108
+ file to the `exclude` array of the YAML file.
109
+
110
+ `.effuseignore`:
111
+
112
+ ```
113
+ *.bak
114
+ foo
115
+ ```
116
+
117
+ `effuse.yml`:
118
+
119
+ ```yaml
120
+ exclude:
121
+ - '*.bak'
122
+ - 'foo'
123
+ ```
124
+
58
125
  ## License
59
126
 
60
- Copyright (c) 2012-2013, Curtis McEnroe <programble@gmail.com>
127
+ Copyright © 2012-2013, Curtis McEnroe <programble@gmail.com>
61
128
 
62
129
  Permission to use, copy, modify, and/or distribute this software for any
63
130
  purpose with or without fee is hereby granted, provided that the above
@@ -70,4 +137,3 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70
137
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
71
138
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
72
139
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
73
-
data/bin/effuse CHANGED
@@ -1,161 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require 'fileutils'
4
- require 'optparse'
5
- require 'ostruct'
6
-
7
- opts = OpenStruct.new(dest_dir: Dir.home,
8
- import: false,
9
- clean: false,
10
- confirm: true,
11
- backup: true,
12
- prefix: '',
13
- verbose: false,
14
- exclude: %w[*~ .*~ .*.swp
15
- .effuseignore *.effuse .*.effuse
16
- .git .gitignore .gitmodules])
17
-
18
- if File.file?('.effuseignore')
19
- File.open('.effuseignore').each_line do |glob|
20
- opts.exclude << glob.chomp
21
- end
22
- end
23
-
24
- OptionParser.new do |o|
25
- o.banner = 'Usage: effuse [OPTIONS] [DEST]'
26
-
27
- o.on('-i', '--import', 'Import existing files') { opts.import = true }
28
- o.on('-c', '--clean', 'Remove symlinks') { opts.clean = true }
29
-
30
- o.separator ''
31
-
32
- o.on('--exclude GLOB', 'Exclude GLOB from symlinking') do |glob|
33
- opts.exclude << glob
34
- end
35
- o.on('--include GLOB', 'Include GLOB in symlinking') do |glob|
36
- opts.exclude.delete(glob)
37
- end
38
-
39
- o.separator ''
40
-
41
- o.on('-y', '--no-confirm', 'Do not ask before replacing files') do
42
- opts.confirm = false
43
- end
44
- o.on('-n', '--no-backup', 'Do not create backup files') do
45
- opts.backup = false
46
- end
47
-
48
- o.separator ''
49
-
50
- o.on('-p', '--prefix PREFIX', 'Prefix symlinked paths with PREFIX') do |prefix|
51
- opts.prefix = prefix
52
- end
53
-
54
- o.separator ''
55
-
56
- o.on('-v', '--verbose', 'Show verbose output') { opts.verbose = true }
57
- o.on_tail('-h', '--help', 'Show this message') do
58
- puts o
59
- exit
60
- end
61
- end.parse!
62
-
63
- opts.dest_dir = ARGV[0] if ARGV[0]
64
-
65
- if File.identical?(opts.dest_dir, '.')
66
- puts 'error: destination directory is current directory'
67
- exit 1
68
- end
69
-
70
- $opts = opts # Don't hate me
71
-
72
- def vputs(s)
73
- puts s if $opts.verbose
74
- end
75
-
76
- def confirm?(s)
77
- return true unless $opts.confirm
78
- loop do
79
- print "#{s} [Y/n] "
80
- input = $stdin.gets.chomp
81
- return true if input.empty? || input[0].downcase == ?y
82
- return false if input[0].downcase == ?n
83
- end
84
- end
85
-
86
- def backup(src)
87
- if $opts.backup
88
- vputs "renaming '#{src}' -> '#{src}.effuse'"
89
- File.rename(src, src + '.effuse')
90
- else
91
- vputs "deleting '#{src}'"
92
- File.delete(src)
93
- end
94
- end
95
-
96
- dirs = ['.']
97
- files = {}
98
-
99
- dirs.each do |dir|
100
- vputs "scanning '#{dir}'"
101
- Dir.foreach(dir) do |file|
102
- next if ['.', '..'].include?(file)
103
-
104
- if opts.exclude.any? {|glob| File.fnmatch(glob, file) }
105
- vputs "excluding '#{File.join(dir, file)}'"
106
- next
107
- end
108
-
109
- file = File.join(dir, file)
110
-
111
- if File.directory?(file)
112
- vputs "adding '#{file}'"
113
- dirs << file
114
- next
115
- end
116
-
117
- vputs "found '#{file}'"
118
- relpath = opts.prefix + File.join(file.split('/').drop(1))
119
- files[File.absolute_path(file)] = File.join(opts.dest_dir, relpath)
120
- end
121
- end
122
-
123
- if opts.clean
124
- files.each_pair do |src, dest|
125
- if File.exist?(dest) && File.identical?(src, dest)
126
- puts dest
127
- File.delete(dest)
128
- else
129
- vputs "not symlinked '#{dest}'"
130
- end
131
- end
132
- else
133
- files.each_pair do |src, dest|
134
- if File.exist?(dest)
135
- if File.identical?(src, dest)
136
- vputs "already symlinked '#{dest}'"
137
- next
138
- elsif opts.import
139
- if confirm?("'#{dest}' already exists. Import it?")
140
- backup(src)
141
- vputs "renaming '#{dest}' -> '#{src}'"
142
- File.rename(dest, src)
143
- else
144
- vputs "skipping '#{dest}'"
145
- next
146
- end
147
- else # Replace destination file
148
- if confirm?("'#{dest}' already exists. Replace it?")
149
- backup(dest)
150
- else
151
- vputs "skipping '#{dest}'"
152
- next
153
- end
154
- end
155
- end
156
-
157
- puts "'#{dest}' -> '#{src}'"
158
- FileUtils.mkdir_p(File.dirname(dest))
159
- File.symlink(src, dest)
160
- end
161
- end
2
+ require 'effuse'
3
+ Effuse.new.execute
data/effuse.gemspec CHANGED
@@ -1,12 +1,17 @@
1
+ $LOAD_PATH << File.expand_path('../lib', __FILE__)
2
+ require 'effuse'
3
+
1
4
  Gem::Specification.new do |s|
2
- s.name = 'effuse'
3
- s.version = '2.0.1'
4
- s.authors = ['Curtis McEnroe']
5
- s.email = ['programble@gmail.com']
6
- s.homepage = 'https://github.com/programble/effuse'
7
- s.summary = 'A tool for symlinking dotfiles'
8
- s.description = s.summary
5
+ s.name = 'effuse'
6
+ s.version = Effuse::VERSION
7
+ s.authors = ['Curtis McEnroe']
8
+ s.email = ['programble@gmail.com']
9
+ s.homepage = 'https://github.com/programble/effuse'
10
+ s.licenses = ['ISC']
11
+ s.summary = 'Tool for symlinking dotfiles'
12
+ s.description = s.summary
9
13
 
10
- s.files = `git ls-files`.split("\n")
11
- s.executables = 'effuse'
14
+ s.files = `git ls-files`.split("\n")
15
+ s.executables = 'effuse'
16
+ s.require_paths = ['lib']
12
17
  end
data/lib/effuse.rb ADDED
@@ -0,0 +1,211 @@
1
+ require 'fileutils'
2
+ require 'yaml'
3
+ require 'optparse'
4
+
5
+ class Effuse
6
+ VERSION = '2.1.0'
7
+
8
+ def initialize
9
+ @dest_dir = Dir.home
10
+ @import = false
11
+ @clean = false
12
+ @confirm = true
13
+ @backup = true
14
+ @prefix = ''
15
+ @verbose = false
16
+ @exclude = %w[*~ .*~ .*.sw? .effuseignore effuse.yml *.effuse .*.effuse
17
+ .git .gitignore .gitmodules]
18
+
19
+ ignore_file
20
+ effuse_file
21
+ options
22
+
23
+ vputs self.inspect
24
+ end
25
+
26
+ def ignore_file
27
+ return unless File.file? '.effuseignore'
28
+ puts 'warning: ignore file is deprecated, use effuse.yml instead'
29
+ File.readlines('.effuseignore').each do |glob|
30
+ @exclude << glob.chomp
31
+ end
32
+ end
33
+
34
+ def effuse_file
35
+ return unless File.file? 'effuse.yml'
36
+ yaml = YAML.load_file('effuse.yml')
37
+
38
+ if yaml.include? 'destination'
39
+ @dest_dir = File.expand_path(yaml['destination'])
40
+ end
41
+ @prefix = yaml['prefix'] if yaml.include? 'prefix'
42
+
43
+ exclude = yaml['exclude'] || yaml['ignore']
44
+ @exclude.concat(exclude) if exclude
45
+ @exclude -= yaml['include'] if yaml.include? 'include'
46
+ end
47
+
48
+ def options
49
+ OptionParser.new do |o|
50
+ o.banner = 'usage: effuse [OPTIONS...] [DEST]'
51
+
52
+ o.on('-i', '--import', 'Import existing files') do
53
+ @import = true
54
+ end
55
+ o.on('-c', '--clean', 'Remove symlinks') do
56
+ @clean = true
57
+ end
58
+
59
+ o.separator ''
60
+
61
+ o.on('-y', '--no-confirm', 'Do not ask before replacing files') do
62
+ @confirm = false
63
+ end
64
+ o.on('-n', '--no-backup', 'Do not create backup files') do
65
+ @backup = false
66
+ end
67
+
68
+ o.separator ''
69
+
70
+ o.on('--exclude GLOB', 'Exclude GLOB from symlinking') do |glob|
71
+ @exclude << glob
72
+ end
73
+ o.on('--include GLOB', 'Include GLOB in symlinking') do |glob|
74
+ @exclude.delete(glob)
75
+ end
76
+
77
+ o.separator ''
78
+
79
+ o.on('-p', '--prefix', 'Prefix symlink paths with PREFIX') do |prefix|
80
+ @prefix = prefix
81
+ end
82
+
83
+ o.separator ''
84
+
85
+ o.on('-v', '--verbose', 'Show verbose output') do
86
+ @verbose = true
87
+ end
88
+
89
+ o.separator ''
90
+
91
+ o.on_tail('--version', 'Show version') do
92
+ puts "effuse #{VERSION}"
93
+ exit
94
+ end
95
+ o.on_tail('-h', '--help', 'Show this message') do
96
+ puts o
97
+ exit
98
+ end
99
+ end.parse!
100
+ @dest_dir = ARGV.first if ARGV.first
101
+ end
102
+
103
+ def vputs(s)
104
+ puts(s) if @verbose
105
+ end
106
+
107
+ def confirm? s
108
+ return true unless @confirm
109
+ loop do
110
+ print "#{s} [Y/n] "
111
+ input = $stdin.gets.chomp
112
+ return true if input.empty? || input[0].downcase == ?y
113
+ return false if input[0].downcase == ?n
114
+ end
115
+ end
116
+
117
+ def backup(src)
118
+ if @backup
119
+ vputs "renaming '#{src}' -> '#{src}.effuse'"
120
+ File.rename(src, src + '.effuse')
121
+ else
122
+ vputs "deleting '#{src}'"
123
+ File.delete(src)
124
+ end
125
+ end
126
+
127
+ def scan
128
+ dirs = ['.']
129
+ files = {}
130
+
131
+ dirs.each do |dir|
132
+ vputs "scanning '#{dir}'"
133
+ Dir.foreach(dir) do |entry|
134
+ next if %w[. ..].include? entry
135
+
136
+ path = File.join(dir, entry)
137
+
138
+ if @exclude.any? {|g| File.fnmatch(g, entry) }
139
+ vputs "excluding '#{path}'"
140
+ next
141
+ end
142
+
143
+ if File.directory? path
144
+ dirs << path
145
+ next
146
+ end
147
+
148
+ vputs "adding '#{path}'"
149
+ relpath = @prefix + File.join(path.split('/').drop(1))
150
+ files[File.absolute_path(path)] = File.join(@dest_dir, relpath)
151
+ end
152
+ end
153
+
154
+ files
155
+ end
156
+
157
+ def clean(files)
158
+ files.each do |src, dest|
159
+ if File.exist?(dest) && File.identical?(src, dest)
160
+ puts dest
161
+ File.delete(dest)
162
+ else
163
+ vputs "'#{dest}' not symlinked"
164
+ end
165
+ end
166
+ end
167
+
168
+ def symlink(files)
169
+ files.each do |src, dest|
170
+ if File.exist? dest
171
+ if File.identical? src, dest
172
+ vputs "'#{dest}' already symlinked"
173
+ next
174
+ elsif @import
175
+ if confirm? "'#{dest}' already exists. Import it?"
176
+ backup(src)
177
+ vputs "renaming '#{dest}' -> '#{src}'"
178
+ File.rename(dest, src)
179
+ else
180
+ vputs "skipping '#{dest}'"
181
+ next
182
+ end
183
+ else # Replace destination file
184
+ if confirm? "'#{dest}' already exists. Replace it?"
185
+ backup(dest)
186
+ else
187
+ vputs "skipping '#{dest}'"
188
+ next
189
+ end
190
+ end
191
+ end
192
+
193
+ puts "'#{dest}' -> '#{src}'"
194
+ FileUtils.mkdir_p(File.dirname(dest))
195
+ File.symlink(src, dest)
196
+ end
197
+ end
198
+
199
+ def execute
200
+ if File.identical? @dest_dir, '.'
201
+ puts 'error: destination directory is current directory'
202
+ exit 1
203
+ end
204
+
205
+ if @clean
206
+ clean(scan)
207
+ else
208
+ symlink(scan)
209
+ end
210
+ end
211
+ end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effuse
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Curtis McEnroe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-14 00:00:00.000000000 Z
11
+ date: 2013-11-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: A tool for symlinking dotfiles
13
+ description: Tool for symlinking dotfiles
14
14
  email:
15
15
  - programble@gmail.com
16
16
  executables:
@@ -18,13 +18,15 @@ executables:
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
- - .gitignore
21
+ - ".gitignore"
22
22
  - ChangeLog.md
23
23
  - README.md
24
24
  - bin/effuse
25
25
  - effuse.gemspec
26
+ - lib/effuse.rb
26
27
  homepage: https://github.com/programble/effuse
27
- licenses: []
28
+ licenses:
29
+ - ISC
28
30
  metadata: {}
29
31
  post_install_message:
30
32
  rdoc_options: []
@@ -32,18 +34,18 @@ require_paths:
32
34
  - lib
33
35
  required_ruby_version: !ruby/object:Gem::Requirement
34
36
  requirements:
35
- - - '>='
37
+ - - ">="
36
38
  - !ruby/object:Gem::Version
37
39
  version: '0'
38
40
  required_rubygems_version: !ruby/object:Gem::Requirement
39
41
  requirements:
40
- - - '>='
42
+ - - ">="
41
43
  - !ruby/object:Gem::Version
42
44
  version: '0'
43
45
  requirements: []
44
46
  rubyforge_project:
45
- rubygems_version: 2.0.0
47
+ rubygems_version: 2.0.2
46
48
  signing_key:
47
49
  specification_version: 4
48
- summary: A tool for symlinking dotfiles
50
+ summary: Tool for symlinking dotfiles
49
51
  test_files: []