effuse 1.1.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +8 -0
- data/README.md +14 -10
- data/bin/effuse +81 -76
- data/effuse.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d68dcfbe45037643f26e40c799f57b68aa930d1
|
4
|
+
data.tar.gz: 6867ba6d3a880dbf9a2a92068a0e7178c2b1e4fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c6f1c2f9f94c3c7c95ff82668d9ec50e8d8c01c3c3547535306ed870f31ff56f42a81038335b980fb5acae42951172397dd62e842e3d282f7ee16866f4aac95
|
7
|
+
data.tar.gz: 7cfc78918e423fa35938dd5136d4382c8d2bf162ab26e145c26e1ff7bae097b6f7b6026e50311861cf7af401e4587e9b9d95e7f47e66c4bc8d9f9fdc77030a69
|
data/ChangeLog.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 2.0.0 (May 13 2013)
|
4
|
+
|
5
|
+
* Replace existing files by default
|
6
|
+
* Added `--import` option to import existing files
|
7
|
+
* Changed `--noconfirm` to `--no-confirm`
|
8
|
+
* Backup files to `.file.effuse`
|
9
|
+
* Removed short forms of `--exclude` and `--include` options
|
10
|
+
|
3
11
|
## 1.1.1 (March 12 2013)
|
4
12
|
|
5
13
|
* Dropped Ruby 1.8 compatibility
|
data/README.md
CHANGED
@@ -26,26 +26,30 @@ symlinks to all your configurations in your home directory!
|
|
26
26
|
Your configurations don't go in your home directory? No problem! Just run
|
27
27
|
`effuse /path/` and the symlinks will be created wherever your heart desires.
|
28
28
|
|
29
|
+
Would you rather import a dotfile from your system into your repository
|
30
|
+
than replace it? No problem, just use `effuse --import`.
|
31
|
+
|
29
32
|
Symlinks aren't working out for you? Effuse has got you covered. Just run
|
30
33
|
`effuse --clean` in your dotfiles repository and it will remove all those nasty
|
31
34
|
symlinks it created before.
|
32
35
|
|
33
|
-
Don't want to symlink a certain bothersome file? Why not tell Effuse
|
34
|
-
opinion on the matter using `effuse
|
35
|
-
talking to using a `.effuseignore` file? Just put one
|
36
|
-
line in there and never worry again.
|
36
|
+
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.
|
37
40
|
|
38
41
|
```
|
39
|
-
Usage: effuse [
|
42
|
+
Usage: effuse [OPTIONS] [DEST]
|
43
|
+
-i, --import Import existing files
|
40
44
|
-c, --clean Remove symlinks
|
41
45
|
|
42
|
-
|
43
|
-
|
46
|
+
--exclude GLOB Exclude GLOB from symlinking
|
47
|
+
--include GLOB Include GLOB in symlinking
|
44
48
|
|
45
|
-
-y, --
|
49
|
+
-y, --no-confirm Do not ask before replacing files
|
46
50
|
-n, --no-backup Do not create backup files
|
47
51
|
|
48
|
-
-p --prefix PREFIX
|
52
|
+
-p, --prefix PREFIX Prefix symlinked paths with PREFIX
|
49
53
|
|
50
54
|
-v, --verbose Show verbose output
|
51
55
|
-h, --help Show this message
|
@@ -53,7 +57,7 @@ Usage: effuse [OPTION...] [DEST]
|
|
53
57
|
|
54
58
|
## License
|
55
59
|
|
56
|
-
Copyright (c)
|
60
|
+
Copyright (c) 2012-2013, Curtis McEnroe <programble@gmail.com>
|
57
61
|
|
58
62
|
Permission to use, copy, modify, and/or distribute this software for any
|
59
63
|
purpose with or without fee is hereby granted, provided that the above
|
data/bin/effuse
CHANGED
@@ -1,155 +1,160 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require 'fileutils'
|
3
4
|
require 'optparse'
|
4
5
|
require 'ostruct'
|
5
|
-
require 'fileutils'
|
6
|
-
|
7
|
-
options = OpenStruct.new(:verbose => false,
|
8
|
-
:clean => false,
|
9
|
-
:noconfirm => nil,
|
10
|
-
:backup => true,
|
11
|
-
:prefix => '',
|
12
|
-
:exclude => %w[.effuseignore .git .gitignore .gitmodules *~ .*~ .*.swp])
|
13
6
|
|
14
|
-
|
15
|
-
|
16
|
-
|
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[.effuseignore .git .gitignore .gitmodules
|
15
|
+
*~ .*~ .*.swp])
|
16
|
+
|
17
|
+
if File.file?('.effuseignore')
|
18
|
+
File.open('.effuseignore').each_line do |glob|
|
19
|
+
opts.exclude << glob.chomp
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
20
23
|
OptionParser.new do |o|
|
21
|
-
o.banner = 'Usage: effuse [
|
24
|
+
o.banner = 'Usage: effuse [OPTIONS] [DEST]'
|
22
25
|
|
23
|
-
o.on('-
|
24
|
-
|
25
|
-
end
|
26
|
+
o.on('-i', '--import', 'Import existing files') { opts.import = true }
|
27
|
+
o.on('-c', '--clean', 'Remove symlinks') { opts.clean = true }
|
26
28
|
|
27
29
|
o.separator ''
|
28
30
|
|
29
|
-
o.on('
|
30
|
-
|
31
|
+
o.on('--exclude GLOB', 'Exclude GLOB from symlinking') do |glob|
|
32
|
+
opts.exclude << glob
|
31
33
|
end
|
32
|
-
|
33
|
-
|
34
|
-
options.exclude.delete(glob)
|
34
|
+
o.on('--include GLOB', 'Include GLOB in symlinking') do |glob|
|
35
|
+
opts.exclude.delete(glob)
|
35
36
|
end
|
36
37
|
|
37
38
|
o.separator ''
|
38
39
|
|
39
|
-
o.on('-y', '--
|
40
|
-
|
40
|
+
o.on('-y', '--no-confirm', 'Do not ask before replacing files') do
|
41
|
+
opts.confirm = false
|
41
42
|
end
|
42
|
-
|
43
43
|
o.on('-n', '--no-backup', 'Do not create backup files') do
|
44
|
-
|
44
|
+
opts.backup = false
|
45
45
|
end
|
46
46
|
|
47
47
|
o.separator ''
|
48
48
|
|
49
|
-
o.on('-p', '--prefix PREFIX', 'Prefix
|
50
|
-
|
49
|
+
o.on('-p', '--prefix PREFIX', 'Prefix symlinked paths with PREFIX') do |prefix|
|
50
|
+
opts.prefix = prefix
|
51
51
|
end
|
52
52
|
|
53
53
|
o.separator ''
|
54
54
|
|
55
|
-
o.on('-v', '--verbose', 'Show verbose output')
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
o.on_tail("-h", "--help", "Show this message") do
|
55
|
+
o.on('-v', '--verbose', 'Show verbose output') { opts.verbose = true }
|
56
|
+
o.on_tail('-h', '--help', 'Show this message') do
|
60
57
|
puts o
|
61
58
|
exit
|
62
59
|
end
|
63
60
|
end.parse!
|
64
61
|
|
65
|
-
dest_dir = ARGV[0]
|
62
|
+
opts.dest_dir = ARGV[0] if ARGV[0]
|
66
63
|
|
67
|
-
if File.identical?(dest_dir, '.')
|
64
|
+
if File.identical?(opts.dest_dir, '.')
|
68
65
|
puts 'error: destination directory is current directory'
|
69
66
|
exit 1
|
70
67
|
end
|
71
68
|
|
72
|
-
|
69
|
+
$opts = opts # Don't hate me
|
70
|
+
|
71
|
+
def vputs(s)
|
72
|
+
puts s if $opts.verbose
|
73
|
+
end
|
74
|
+
|
75
|
+
def confirm?(s)
|
76
|
+
return true unless $opts.confirm
|
77
|
+
loop do
|
78
|
+
print "#{s} [Y/n] "
|
79
|
+
input = $stdin.gets.chomp
|
80
|
+
return true if input.empty? || input[0].downcase == ?y
|
81
|
+
return false if input[0].downcase == ?n
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def backup(src)
|
86
|
+
if $opts.backup
|
87
|
+
dest = File.join(File.dirname(src), ".#{File.basename(src)}.effuse")
|
88
|
+
vputs "renaming '#{src}' -> '#{dest}'"
|
89
|
+
File.rename(src, dest)
|
90
|
+
else
|
91
|
+
vputs "deleting '#{src}'"
|
92
|
+
File.delete(src)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
73
96
|
dirs = ['.']
|
97
|
+
files = {}
|
74
98
|
|
75
99
|
dirs.each do |dir|
|
76
|
-
|
100
|
+
vputs "scanning '#{dir}'"
|
77
101
|
Dir.foreach(dir) do |file|
|
78
102
|
next if ['.', '..'].include?(file)
|
79
103
|
|
80
|
-
if
|
81
|
-
|
104
|
+
if opts.exclude.any? {|glob| File.fnmatch(glob, file) }
|
105
|
+
vputs "excluding '#{File.join(dir, file)}'"
|
82
106
|
next
|
83
107
|
end
|
84
108
|
|
85
109
|
file = File.join(dir, file)
|
86
110
|
|
87
111
|
if File.directory?(file)
|
112
|
+
vputs "adding '#{file}'"
|
88
113
|
dirs << file
|
89
|
-
puts "adding #{file}" if options.verbose
|
90
114
|
next
|
91
115
|
end
|
92
116
|
|
93
|
-
|
94
|
-
relpath = file.split('/')
|
95
|
-
|
96
|
-
files[File.absolute_path(file)] = dest
|
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)
|
97
120
|
end
|
98
121
|
end
|
99
122
|
|
100
|
-
if
|
123
|
+
if opts.clean
|
101
124
|
files.each_pair do |src, dest|
|
102
125
|
if File.exist?(dest) && File.identical?(src, dest)
|
103
126
|
puts dest
|
104
127
|
File.delete(dest)
|
105
128
|
else
|
106
|
-
|
129
|
+
vputs "not symlinked '#{dest}'"
|
107
130
|
end
|
108
131
|
end
|
109
132
|
else
|
110
133
|
files.each_pair do |src, dest|
|
111
134
|
if File.exist?(dest)
|
112
135
|
if File.identical?(src, dest)
|
113
|
-
|
136
|
+
vputs "already symlinked '#{dest}'"
|
114
137
|
next
|
115
|
-
|
116
|
-
if
|
117
|
-
|
118
|
-
|
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)
|
119
143
|
else
|
120
|
-
|
121
|
-
|
122
|
-
puts " [i] Import original file and symlink"
|
123
|
-
puts " [k] Keep original file"
|
124
|
-
|
125
|
-
loop do
|
126
|
-
input = gets.chomp.downcase[0] || 'r'
|
127
|
-
break if 'rik'.include?(input)
|
128
|
-
puts "Error: '#{input}' is not an option"
|
129
|
-
end
|
144
|
+
vputs "skipping '#{dest}'"
|
145
|
+
next
|
130
146
|
end
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
File.rename(dest, dest + '~')
|
137
|
-
end
|
138
|
-
when 'i'
|
139
|
-
if options.backup
|
140
|
-
puts "renaming #{src} -> #{src + '~'}" if options.verbose
|
141
|
-
File.rename(src, src + '~')
|
142
|
-
end
|
143
|
-
puts "renaming #{dest} -> #{src}" if options.verbose
|
144
|
-
File.rename(dest, src)
|
145
|
-
when 'k'
|
146
|
-
puts "skipping #{dest}" if options.verbose
|
147
|
+
else # Replace destination file
|
148
|
+
if confirm?("'#{dest}' already exists. Replace it?")
|
149
|
+
backup(dest)
|
150
|
+
else
|
151
|
+
vputs "skipping '#{dest}'"
|
147
152
|
next
|
148
153
|
end
|
149
154
|
end
|
150
155
|
end
|
151
156
|
|
152
|
-
puts "#{dest} -> #{src}"
|
157
|
+
puts "'#{dest}' -> '#{src}'"
|
153
158
|
FileUtils.mkdir_p(File.dirname(dest))
|
154
159
|
File.symlink(src, dest)
|
155
160
|
end
|
data/effuse.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effuse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.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-
|
11
|
+
date: 2013-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A tool for managing symlinks
|
14
14
|
email:
|