effuse 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +60 -0
- data/bin/effuse +108 -0
- data/effuse.gemspec +12 -0
- metadata +50 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Effuse
|
2
|
+
|
3
|
+
A tool for managing symlinks
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
```
|
8
|
+
gem install effuse
|
9
|
+
```
|
10
|
+
|
11
|
+
## Usage
|
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?
|
17
|
+
|
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!
|
22
|
+
|
23
|
+
Just run `effuse` in your dotfiles repository and it will automagically create
|
24
|
+
symlinks to all your configurations in your home directory!
|
25
|
+
|
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.
|
28
|
+
|
29
|
+
Symlinks aren't working out for you? Effuse has got you covered. Just run
|
30
|
+
`effuse --clean` in your dotfiles repository and it will remove all those nasty
|
31
|
+
symlinks it created before.
|
32
|
+
|
33
|
+
Don't want to symlink a certain bothersome file? Why not tell Effuse your
|
34
|
+
opinion on the matter using `effuse -e file`?
|
35
|
+
|
36
|
+
```
|
37
|
+
Usage: effuse [OPTION...] [DEST]
|
38
|
+
-c, --clean Remove symlinks
|
39
|
+
-e, --exclude GLOB Exclude GLOB from symlinking
|
40
|
+
-v, --verbose Show verbose output
|
41
|
+
|
42
|
+
-h, --help Show this message
|
43
|
+
```
|
44
|
+
|
45
|
+
## License
|
46
|
+
|
47
|
+
Copyright (c) 2011, Curtis McEnroe <programble@gmail.com>
|
48
|
+
|
49
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
50
|
+
purpose with or without fee is hereby granted, provided that the above
|
51
|
+
copyright notice and this permission notice appear in all copies.
|
52
|
+
|
53
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
54
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
55
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
56
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
57
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
58
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
59
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
60
|
+
|
data/bin/effuse
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'ostruct'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
options = OpenStruct.new(:verbose => false, :exclude => ['.git*', '*~', '.*.swp'], :clean => false)
|
8
|
+
|
9
|
+
OptionParser.new do |o|
|
10
|
+
o.banner = 'Usage: effuse [OPTION...] [DEST]'
|
11
|
+
|
12
|
+
o.on('-c', '--clean', 'Remove symlinks') do
|
13
|
+
options.clean = true
|
14
|
+
end
|
15
|
+
|
16
|
+
o.on('-e', '--exclude GLOB', 'Exclude GLOB from symlinking') do |glob|
|
17
|
+
options.exclude << glob
|
18
|
+
end
|
19
|
+
|
20
|
+
o.on('-v', '--verbose', 'Show verbose output') do
|
21
|
+
options.verbose = true
|
22
|
+
end
|
23
|
+
|
24
|
+
o.separator ''
|
25
|
+
|
26
|
+
o.on_tail("-h", "--help", "Show this message") do
|
27
|
+
puts o
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
end.parse!
|
31
|
+
|
32
|
+
dest_dir = ARGV[0] || Dir.home
|
33
|
+
|
34
|
+
files = {}
|
35
|
+
dirs = ['.']
|
36
|
+
|
37
|
+
dirs.each do |dir|
|
38
|
+
puts "scanning #{dir}" if options.verbose
|
39
|
+
Dir.foreach(dir) do |file|
|
40
|
+
next if ['.', '..'].include?(file)
|
41
|
+
|
42
|
+
if options.exclude.any? {|e| File.fnmatch(e, file)}
|
43
|
+
puts "excluding #{File.join(dir, file)}" if options.verbose
|
44
|
+
next
|
45
|
+
end
|
46
|
+
|
47
|
+
file = File.join(dir, file)
|
48
|
+
|
49
|
+
if File.directory?(file)
|
50
|
+
dirs << file
|
51
|
+
puts "adding #{file}" if options.verbose
|
52
|
+
next
|
53
|
+
end
|
54
|
+
|
55
|
+
puts "found #{file}" if options.verbose
|
56
|
+
dest = File.join([dest_dir] + file.split('/')[1..-1])
|
57
|
+
files[File.absolute_path(file)] = dest
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if options.clean
|
62
|
+
files.each_pair do |src, dest|
|
63
|
+
if File.exist?(dest) && File.identical?(src, dest)
|
64
|
+
puts dest
|
65
|
+
File.delete(dest)
|
66
|
+
else
|
67
|
+
puts "not symlinked #{dest}" if options.verbose
|
68
|
+
end
|
69
|
+
end
|
70
|
+
else
|
71
|
+
files.each_pair do |src, dest|
|
72
|
+
if File.exist?(dest)
|
73
|
+
if File.identical?(src, dest)
|
74
|
+
puts "already symlinked #{dest}" if options.verbose
|
75
|
+
next
|
76
|
+
else
|
77
|
+
puts "File already exists: #{dest}"
|
78
|
+
puts " [R] Backup and replace"
|
79
|
+
puts " [i] Import original file and symlink"
|
80
|
+
puts " [k] Keep original file"
|
81
|
+
|
82
|
+
skip = false
|
83
|
+
loop do
|
84
|
+
case gets.chomp.downcase[0] || 'r'
|
85
|
+
when 'r'
|
86
|
+
puts "renaming #{dest} -> #{dest + '~'}" if options.verbose
|
87
|
+
File.rename(dest, dest + '~')
|
88
|
+
break
|
89
|
+
when 'i'
|
90
|
+
puts "renaming #{src} -> #{src + '~'}" if options.verbose
|
91
|
+
File.rename(src, src + '~')
|
92
|
+
puts "renaming #{dest} -> #{src}" if options.verbose
|
93
|
+
File.rename(dest, src)
|
94
|
+
break
|
95
|
+
when 'k'
|
96
|
+
skip = true
|
97
|
+
break
|
98
|
+
end
|
99
|
+
end
|
100
|
+
next if skip
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
puts "#{dest} -> #{src}"
|
105
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
106
|
+
File.symlink(src, dest)
|
107
|
+
end
|
108
|
+
end
|
data/effuse.gemspec
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'effuse'
|
3
|
+
s.version = '0.1.0'
|
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 managing symlinks'
|
8
|
+
s.description = s.summary
|
9
|
+
|
10
|
+
s.files = `git ls-files`.split("\n")
|
11
|
+
s.executables = 'effuse'
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: effuse
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Curtis McEnroe
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-22 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A tool for managing symlinks
|
15
|
+
email:
|
16
|
+
- programble@gmail.com
|
17
|
+
executables:
|
18
|
+
- effuse
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- README.md
|
24
|
+
- bin/effuse
|
25
|
+
- effuse.gemspec
|
26
|
+
homepage: https://github.com/programble/effuse
|
27
|
+
licenses: []
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 1.8.11
|
47
|
+
signing_key:
|
48
|
+
specification_version: 3
|
49
|
+
summary: A tool for managing symlinks
|
50
|
+
test_files: []
|