polka 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +22 -0
- data/LICENSE +20 -0
- data/bin/polka +6 -0
- data/lib/polka/bootstrapper.rb +99 -0
- data/lib/polka/cli.rb +12 -0
- data/lib/polka/dotfile.rb +39 -0
- data/lib/polka/dotfile_group.rb +50 -0
- data/lib/polka/operations/parsed_copying.rb +49 -0
- data/lib/polka/version.rb +3 -0
- data/lib/polka.rb +17 -0
- data/polka.gemspec +22 -0
- data/spec/polka/bootstrapper_spec.rb +101 -0
- data/spec/polka/cli_spec.rb +26 -0
- data/spec/polka/dotfile_group_spec.rb +38 -0
- data/spec/polka/dotfile_spec.rb +56 -0
- data/spec/polka/operations/parsed_copying_spec.rb +13 -0
- data/spec/polka_spec.rb +52 -0
- data/spec/spec_helper.rb +23 -0
- metadata +106 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Guardfile
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
colorize (0.5.8)
|
5
|
+
diff-lcs (1.1.3)
|
6
|
+
rspec (2.11.0)
|
7
|
+
rspec-core (~> 2.11.0)
|
8
|
+
rspec-expectations (~> 2.11.0)
|
9
|
+
rspec-mocks (~> 2.11.0)
|
10
|
+
rspec-core (2.11.1)
|
11
|
+
rspec-expectations (2.11.2)
|
12
|
+
diff-lcs (~> 1.1.3)
|
13
|
+
rspec-mocks (2.11.2)
|
14
|
+
thor (0.16.0)
|
15
|
+
|
16
|
+
PLATFORMS
|
17
|
+
ruby
|
18
|
+
|
19
|
+
DEPENDENCIES
|
20
|
+
colorize
|
21
|
+
rspec
|
22
|
+
thor
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Michi Huber
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/polka
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
module Polka
|
2
|
+
class Bootstrapper
|
3
|
+
def initialize(home_dir, dotfile_dir)
|
4
|
+
@home_dir = home_dir
|
5
|
+
@dotfile_dir = dotfile_dir
|
6
|
+
DotfileGroup.all_files = dotfiles_in_dotfile_dir
|
7
|
+
|
8
|
+
symlinking = lambda { |dest, src| FileUtils.ln_s(dest, src) }
|
9
|
+
copying = lambda { |dest, src| FileUtils.cp(dest, src) }
|
10
|
+
|
11
|
+
@symlink = DotfileGroup.new(symlinking, " Symlinking files".light_blue)
|
12
|
+
@copy = DotfileGroup.new(copying, " Copying files".light_blue)
|
13
|
+
@parsed_copy = DotfileGroup.new(Operations::ParsedCopying, " Parsing and copying files".light_blue)
|
14
|
+
@inclusive_groups = [@symlink, @copy, @parsed_copy]
|
15
|
+
@exclude = DotfileGroup.new
|
16
|
+
exclude("Dotfile")
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.from_dotfile(dotfile, home_dir)
|
20
|
+
bootstrapper = new(home_dir, File.expand_path(File.dirname(dotfile)))
|
21
|
+
bootstrapper.instance_eval(dotfile.read)
|
22
|
+
|
23
|
+
return bootstrapper
|
24
|
+
end
|
25
|
+
|
26
|
+
# TODO: the structure of copy and the rest is the same,
|
27
|
+
# refactor into one method?
|
28
|
+
[:symlink, :exclude].each do |var|
|
29
|
+
define_method(var) do |*files|
|
30
|
+
group = instance_variable_get("@#{var}")
|
31
|
+
if file_with_options?(files)
|
32
|
+
add_file_with_options_to_group(files, group)
|
33
|
+
else
|
34
|
+
group.add_all_other_files if files.delete(:all_other_files)
|
35
|
+
add_files_to_group(files, group)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def copy(*files)
|
41
|
+
if file_with_options?(files)
|
42
|
+
group = erb?(files[0]) ? @parsed_copy : @copy
|
43
|
+
add_file_with_options_to_group(files, group)
|
44
|
+
else
|
45
|
+
error_msg = "Cannot copy :all_other_files, please copy files explicitly."
|
46
|
+
raise ArgumentError, error_msg if files.include?(:all_other_files)
|
47
|
+
|
48
|
+
erb = files.select { |fn| erb?(fn) }
|
49
|
+
not_erb = files - erb
|
50
|
+
add_files_to_group(not_erb, @copy)
|
51
|
+
erb_dotfiles = erb.map { |erbfile| create_dotfile(erbfile, File.basename(erbfile, '.erb')) }
|
52
|
+
@parsed_copy.add(erb_dotfiles) unless erb_dotfiles.empty?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def setup
|
57
|
+
Polka.log "\nStarting Dotfile Setup with Polka...\n".green
|
58
|
+
@inclusive_groups.each(&:setup)
|
59
|
+
Polka.log "\nSetup completed. Enjoy!\n".green
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def add_files_to_group(files, group)
|
64
|
+
dotfiles = files.map { |fn| create_dotfile(fn) }
|
65
|
+
group.add(dotfiles) unless dotfiles.empty?
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_file_with_options_to_group(file_with_options, group)
|
69
|
+
filename = file_with_options[0]
|
70
|
+
homename = file_with_options[1][:as]
|
71
|
+
|
72
|
+
group.add([create_dotfile(filename, homename)])
|
73
|
+
end
|
74
|
+
|
75
|
+
def erb?(filename)
|
76
|
+
filename =~ /\.erb$/
|
77
|
+
end
|
78
|
+
|
79
|
+
def file_with_options?(files)
|
80
|
+
return false unless files.size == 2 && files.last.class == Hash && files.last[:as]
|
81
|
+
unless files[0] == :all_other_files
|
82
|
+
return true
|
83
|
+
else
|
84
|
+
raise ArgumentError, "Cannot add :all_other_files with :as options"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def dotfiles_in_dotfile_dir
|
89
|
+
files = Dir.new(@dotfile_dir).entries - %w(.. .)
|
90
|
+
files.map { |fn| create_dotfile(fn) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def create_dotfile(filename, homename=nil)
|
94
|
+
dotfile_path = File.join(@dotfile_dir, filename)
|
95
|
+
home_path = File.join(@home_dir, homename || filename)
|
96
|
+
Dotfile.new(dotfile_path, home_path)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/polka/cli.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Polka
|
2
|
+
class Cli < Thor
|
3
|
+
desc "setup", "sets up your dotfiles according to the instructions in Dotfile"
|
4
|
+
def setup(home_dir=nil, dotfile_dir=nil)
|
5
|
+
dotfile_path = dotfile_dir ? File.join(dotfile_dir, "Dotfile") : "Dotfile"
|
6
|
+
home_path = home_dir || ENV['HOME']
|
7
|
+
dotfile_path = File.expand_path(dotfile_path)
|
8
|
+
home_path = File.expand_path(home_path)
|
9
|
+
File.open(dotfile_path) { |the_dotfile| Bootstrapper.from_dotfile(the_dotfile, home_path).setup }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class FileNotPresentError < StandardError; end
|
2
|
+
|
3
|
+
class Dotfile
|
4
|
+
def initialize(path, home_path)
|
5
|
+
raise FileNotPresentError, "Could not find file at #{path}." unless File.exists?(path)
|
6
|
+
@path = path
|
7
|
+
@home_path = home_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def setup(operation)
|
11
|
+
backup if File.exists?(@home_path)
|
12
|
+
operation.call(@path, @home_path)
|
13
|
+
Polka.log " #{@path} set up as #{@home_path}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def backup
|
17
|
+
Polka.log " Backing up: ".light_yellow + "#{@home_path} => #{backup_dir}"
|
18
|
+
FileUtils.mkdir_p(backup_dir) unless File.exists?(backup_dir)
|
19
|
+
FileUtils.mv(@home_path, backup_dir)
|
20
|
+
end
|
21
|
+
|
22
|
+
def hash
|
23
|
+
@path.hash
|
24
|
+
end
|
25
|
+
|
26
|
+
def eql?(other)
|
27
|
+
hash == other.hash
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.backup_dir(home_path)
|
31
|
+
dir = File.join(".polka_backup", Time.now.strftime("%F_%T"))
|
32
|
+
@@backup_dir ||= File.join(home_path, dir)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def backup_dir
|
37
|
+
Dotfile.backup_dir(File.dirname(@home_path))
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class AllOtherFilesAlreadyAdded < StandardError; end
|
2
|
+
class FileAlreadyAddedError < StandardError; end
|
3
|
+
|
4
|
+
class DotfileGroup
|
5
|
+
@@all_files = []
|
6
|
+
@@grouped_files = []
|
7
|
+
@@all_other_files_added = false
|
8
|
+
|
9
|
+
def self.all_files=(files)
|
10
|
+
@@all_files = files
|
11
|
+
@@grouped_files = []
|
12
|
+
@@all_other_files_added = false
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.remaining_files
|
16
|
+
@@all_files - @@grouped_files
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(operation=nil, setup_msg=nil)
|
20
|
+
@operation = operation
|
21
|
+
@setup_message = setup_msg
|
22
|
+
@files = []
|
23
|
+
@all_other_files = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def add(new_files)
|
27
|
+
raise FileAlreadyAddedError if new_files.any? { |f| @@grouped_files.include?(f) }
|
28
|
+
@@grouped_files += new_files
|
29
|
+
@files += new_files
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_all_other_files
|
33
|
+
raise AllOtherFilesAlreadyAdded if @@all_other_files_added
|
34
|
+
@@all_other_files_added = true
|
35
|
+
@all_other_files = true
|
36
|
+
end
|
37
|
+
|
38
|
+
def files
|
39
|
+
if @all_other_files
|
40
|
+
DotfileGroup.remaining_files + @files
|
41
|
+
else
|
42
|
+
@files
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def setup
|
47
|
+
Polka.log @setup_message unless files.empty?
|
48
|
+
files.each { |f| f.setup(@operation) }
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Polka
|
2
|
+
module Operations
|
3
|
+
class ParsedCopying
|
4
|
+
def self.call(file, dest)
|
5
|
+
copier = new(file, dest)
|
6
|
+
copier.run
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(file, dest)
|
10
|
+
@file = file
|
11
|
+
@dest = dest
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
write(result)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def result
|
20
|
+
personal = context
|
21
|
+
erb.result(binding)
|
22
|
+
end
|
23
|
+
|
24
|
+
def write(result)
|
25
|
+
File.open(dest_without_erb, "w") { |f| f.write(result) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def dest_without_erb
|
29
|
+
@dest.gsub(/\.erb$/, "")
|
30
|
+
end
|
31
|
+
|
32
|
+
def yaml_file
|
33
|
+
File.join(File.dirname(@file), 'personal.yml')
|
34
|
+
end
|
35
|
+
|
36
|
+
def context_name
|
37
|
+
File.basename(@file, ".erb")
|
38
|
+
end
|
39
|
+
|
40
|
+
def context
|
41
|
+
YAML.load_file(yaml_file)[context_name]
|
42
|
+
end
|
43
|
+
|
44
|
+
def erb
|
45
|
+
ERB.new(File.open(@file) { |f| f.read })
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/polka.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "erb"
|
3
|
+
|
4
|
+
require "thor"
|
5
|
+
require "colorize"
|
6
|
+
|
7
|
+
require_relative "polka/cli"
|
8
|
+
require_relative "polka/bootstrapper"
|
9
|
+
require_relative "polka/dotfile"
|
10
|
+
require_relative "polka/dotfile_group"
|
11
|
+
require_relative "polka/operations/parsed_copying"
|
12
|
+
|
13
|
+
module Polka
|
14
|
+
def self.log(msg)
|
15
|
+
puts msg
|
16
|
+
end
|
17
|
+
end
|
data/polka.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'polka/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "polka"
|
6
|
+
s.version = Polka::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Michi Huber"]
|
9
|
+
s.email = ["michi.huber@gmail.com"]
|
10
|
+
s.homepage = "http://github.com/michihuber/polka"
|
11
|
+
s.summary = ""
|
12
|
+
s.description = "Easy Dotfile Management"
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_dependency "thor", ">=0.16.0"
|
20
|
+
s.add_dependency "colorize", "0.5.8"
|
21
|
+
s.add_development_dependency 'rspec', '~> 2.11'
|
22
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
require_relative "../../lib/polka/bootstrapper.rb"
|
3
|
+
class Dotfile; end
|
4
|
+
class DotfileGroup; end
|
5
|
+
module Operations
|
6
|
+
class ParsedCopying; end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Polka::Bootstrapper do
|
10
|
+
subject(:bs) { Polka::Bootstrapper.new('home', 'home/.polka') }
|
11
|
+
let(:copy_group) { double(:copies) }
|
12
|
+
let(:symlink_group) { double(:symlinks) }
|
13
|
+
let(:excluded_group) { double(:excluded) }
|
14
|
+
let(:parsed_copy_group) { double(:parsed_copy) }
|
15
|
+
|
16
|
+
before do
|
17
|
+
Dir.stub(:new) { double(entries: %w(. .. blah)) }
|
18
|
+
blah_dotfile = double
|
19
|
+
the_dotfile = double(:Dotfile)
|
20
|
+
Dotfile.should_receive(:new).with('home/.polka/blah', 'home/blah').and_return(blah_dotfile)
|
21
|
+
Dotfile.should_receive(:new).with('home/.polka/Dotfile', 'home/Dotfile').and_return(the_dotfile)
|
22
|
+
excluded_group.should_receive(:add).with([the_dotfile])
|
23
|
+
DotfileGroup.should_receive(:all_files=).with([blah_dotfile])
|
24
|
+
DotfileGroup.stub(:new).and_return(symlink_group, copy_group, parsed_copy_group, excluded_group)
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#setup" do
|
28
|
+
it "sets up the symlink group" do
|
29
|
+
Polka.stub(:log)
|
30
|
+
copy_group.should_receive(:setup)
|
31
|
+
symlink_group.should_receive(:setup)
|
32
|
+
parsed_copy_group.should_receive(:setup)
|
33
|
+
bs.setup
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#symlink, #exclude, #copy" do
|
38
|
+
describe "addings files without options" do
|
39
|
+
let(:hello_dotfile) { double(:hello_dotfile) }
|
40
|
+
before { Dotfile.stub(:new) { hello_dotfile } }
|
41
|
+
|
42
|
+
it "adds to the symlink group" do
|
43
|
+
symlink_group.should_receive(:add).with([hello_dotfile])
|
44
|
+
bs.symlink "hello"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "adds to the exclude group" do
|
48
|
+
excluded_group.should_receive(:add).with([hello_dotfile])
|
49
|
+
bs.exclude "hello"
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#copy" do
|
53
|
+
it "cannot copy :all_other_files" do
|
54
|
+
expect { bs.copy :all_other_files }.to raise_error(ArgumentError)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "can copy files with aliases" do
|
58
|
+
alias_dotfile = double(:alias_dotfile)
|
59
|
+
Dotfile.should_receive(:new).with("home/.polka/hello", "home/ciao").and_return(alias_dotfile)
|
60
|
+
copy_group.should_receive(:add).with([alias_dotfile])
|
61
|
+
bs.copy("hello", as: "ciao")
|
62
|
+
end
|
63
|
+
|
64
|
+
it "adds to the copy group" do
|
65
|
+
copy_group.should_receive(:add).with([hello_dotfile])
|
66
|
+
bs.copy "hello"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "adds to the parsed_copy group if file has erb extension (without extension on target)" do
|
70
|
+
Dotfile.should_receive(:new).with("home/.polka/hello.erb", "home/hello").and_return(hello_dotfile)
|
71
|
+
parsed_copy_group.should_receive(:add).with([hello_dotfile])
|
72
|
+
bs.copy "hello.erb"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe ":all_other_files" do
|
78
|
+
it "adds :all_other_files" do
|
79
|
+
symlink_group.should_receive(:add_all_other_files)
|
80
|
+
bs.symlink :all_other_files
|
81
|
+
end
|
82
|
+
|
83
|
+
it "adds :all_other_files" do
|
84
|
+
excluded_group.should_receive(:add_all_other_files)
|
85
|
+
bs.exclude :all_other_files
|
86
|
+
end
|
87
|
+
|
88
|
+
it "cannot add :all_other_files with an alias" do
|
89
|
+
expect { bs.symlink(:all_other_files, as: 'something') }.to raise_error(ArgumentError)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it "adds file with home_dir_path if specified" do
|
94
|
+
alias_dotfile = double(:alias_dotfile)
|
95
|
+
Dotfile.should_receive(:new).with("home/.polka/.testrc", "home/.onerc").and_return(alias_dotfile)
|
96
|
+
symlink_group.should_receive(:add).with([alias_dotfile])
|
97
|
+
bs.symlink(".testrc", as: ".onerc")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "thor"
|
2
|
+
require_relative "../../lib/polka/cli.rb"
|
3
|
+
class Polka::Bootstrapper; end
|
4
|
+
|
5
|
+
describe Polka::Cli do
|
6
|
+
describe "#setup" do
|
7
|
+
let(:the_dotfile) { double }
|
8
|
+
let(:bootstrapper) { double(:bootstrapper, setup: "works") }
|
9
|
+
|
10
|
+
it "initializes a bootstrapper with the Dotfile (and the target dir)" do
|
11
|
+
File.stub(:open).and_yield(the_dotfile)
|
12
|
+
Polka::Bootstrapper.should_receive(:from_dotfile).with(the_dotfile, File.expand_path(ENV['HOME'])).and_return(bootstrapper)
|
13
|
+
bootstrapper.setup.should == "works"
|
14
|
+
|
15
|
+
Polka::Cli.new.setup
|
16
|
+
end
|
17
|
+
|
18
|
+
it "accepts home_dir and dotfile_dir as optional arguments" do
|
19
|
+
File.stub(:open).and_yield(the_dotfile)
|
20
|
+
Polka::Bootstrapper.should_receive(:from_dotfile).with(the_dotfile, File.expand_path("home")).and_return(bootstrapper)
|
21
|
+
bootstrapper.setup.should == "works"
|
22
|
+
|
23
|
+
Polka::Cli.new.setup("home", "home/.polka")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative "../../lib/polka/dotfile_group.rb"
|
2
|
+
|
3
|
+
describe DotfileGroup do
|
4
|
+
subject(:group) { DotfileGroup.new }
|
5
|
+
1.upto(3) { |n| fn = "file#{n}".to_sym; let(fn) { double(fn) } }
|
6
|
+
|
7
|
+
before do
|
8
|
+
DotfileGroup.all_files = [file1, file2, file3]
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#add" do
|
12
|
+
it "adds dotfiles" do
|
13
|
+
group.add([file1, file2])
|
14
|
+
group.files.should == [file1, file2]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can only add each file once" do
|
18
|
+
group.add([file1])
|
19
|
+
expect { group.add([file1]) }.to raise_error(FileAlreadyAddedError)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#add_all_other_files" do
|
24
|
+
let(:other_group) { DotfileGroup.new }
|
25
|
+
|
26
|
+
it "adds all other files to the group" do
|
27
|
+
group.add([file1])
|
28
|
+
group.add_all_other_files
|
29
|
+
other_group.add([file3])
|
30
|
+
group.files.should == [file2, file1]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can only be called once" do
|
34
|
+
group.add_all_other_files
|
35
|
+
expect {other_group.add_all_other_files }.to raise_error(AllOtherFilesAlreadyAdded)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Dotfile do
|
4
|
+
describe "#setup", :integrated_with_files do
|
5
|
+
set_up_testdirs
|
6
|
+
|
7
|
+
def home_path(filename)
|
8
|
+
File.join(home_dir, filename)
|
9
|
+
end
|
10
|
+
|
11
|
+
def dotfile_path(filename)
|
12
|
+
File.join(dotfile_dir, filename)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "raises if dotfile does not exist" do
|
16
|
+
expect { Dotfile.new(dotfile_path('.testrc'), "irrelevant") }.to raise_error(FileNotPresentError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "yields to a given operation" do
|
20
|
+
Polka.stub(:log)
|
21
|
+
FileUtils.touch(dotfile_path('.testrc'))
|
22
|
+
df = Dotfile.new(dotfile_path('.testrc'), home_path('.testrc'))
|
23
|
+
df.setup(lambda { |dest, src| FileUtils.ln_s(dest, src) })
|
24
|
+
Dir.new(home_dir).entries.should == %w(. .. .dotfile_dir .testrc)
|
25
|
+
end
|
26
|
+
|
27
|
+
context "the homedir already contains the file" do
|
28
|
+
it "backs up into a backup dir" do
|
29
|
+
Time.stub(:now) { Time.new(2222, 2, 2, 2, 22, 22) }
|
30
|
+
FileUtils.touch(home_path('.testrc'))
|
31
|
+
FileUtils.touch(dotfile_path('.testrc'))
|
32
|
+
df = Dotfile.new(dotfile_path('.testrc'), home_path('.testrc'))
|
33
|
+
Polka.stub(:log)
|
34
|
+
df.setup(lambda { |a, b| FileUtils.cp(a, b) })
|
35
|
+
Dir.new(home_dir).entries.should == %w(. .. .dotfile_dir .polka_backup .testrc)
|
36
|
+
Dir.new(File.join(home_dir, '.polka_backup')).entries.should == %w(. .. 2222-02-02_02:22:22)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "equality" do
|
42
|
+
before { File.stub(:exists?) { true } }
|
43
|
+
|
44
|
+
it "regards dotfiles as equal if they share the same dotfile dir path" do
|
45
|
+
df1 = Dotfile.new("home/df1", "blah")
|
46
|
+
df2 = Dotfile.new("home/df1", "foo")
|
47
|
+
df1.eql?(df2).should == true
|
48
|
+
end
|
49
|
+
|
50
|
+
it "substracts equal dotfiles in array substraction" do
|
51
|
+
df1 = Dotfile.new("home/df1", "blah")
|
52
|
+
df2 = Dotfile.new("home/df1", "foo")
|
53
|
+
([df1] - [df2]).should == []
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Polka::Operations::ParsedCopying, :integrated_with_files do
|
4
|
+
set_up_testdirs
|
5
|
+
|
6
|
+
it "parses the erb file and copys the result without the extension" do
|
7
|
+
File.open(File.join(dotfile_dir, "blah.erb"), "w") { |f| f.write("hello <%= personal['name'] %>") }
|
8
|
+
File.open(File.join(dotfile_dir, "personal.yml"), "w") { |f| f.write("blah:\n name: ray stanz") }
|
9
|
+
|
10
|
+
Polka::Operations::ParsedCopying.call(File.join(dotfile_dir, "blah.erb"), File.join(home_dir, "foo.erb"))
|
11
|
+
File.open(File.join(home_dir, "foo")) { |f| f.read }.should == "hello ray stanz"
|
12
|
+
end
|
13
|
+
end
|
data/spec/polka_spec.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "polka", :integrated_with_files do
|
4
|
+
set_up_testdirs
|
5
|
+
|
6
|
+
before { Polka.stub(:log) }
|
7
|
+
|
8
|
+
it "provides a DSL to manage your dotfile setup" do
|
9
|
+
setup_dotfiles %w(.onerc .tworc .threerc .nodotfile copyrc)
|
10
|
+
setup_the_dotfile <<-EOF
|
11
|
+
symlink :all_other_files
|
12
|
+
symlink ".onerc", ".tworc"
|
13
|
+
copy "copyrc"
|
14
|
+
exclude ".nodotfile"
|
15
|
+
EOF
|
16
|
+
Cli.new.setup(home_dir, dotfile_dir)
|
17
|
+
dir_entries = Dir.new(home_dir).entries
|
18
|
+
dir_entries.should == %w(. .. .dotfile_dir .onerc .threerc .tworc copyrc)
|
19
|
+
File.symlink?(File.join(home_dir, '.onerc')).should == true
|
20
|
+
File.symlink?(File.join(home_dir, 'copyrc')).should == false
|
21
|
+
end
|
22
|
+
|
23
|
+
it "backs up existing files in your homedir" do
|
24
|
+
Time.stub(:now) { Time.new(2222, 2, 2, 2, 22, 22) }
|
25
|
+
setup_dotfiles %w(.onerc)
|
26
|
+
setup_the_dotfile("symlink '.onerc'")
|
27
|
+
FileUtils.touch(File.join(home_dir, '.onerc'))
|
28
|
+
Cli.new.setup(home_dir, dotfile_dir)
|
29
|
+
Dir.new(home_dir).entries.should == %w(. .. .dotfile_dir .onerc .polka_backup)
|
30
|
+
Dir.new(File.join(home_dir, ".polka_backup", "2222-02-02_02:22:22")).entries.should == %w(. .. .onerc)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "copys a parsed version of erb files" do
|
34
|
+
setup_the_dotfile("copy '.inforc.erb'")
|
35
|
+
setup_file_with_content("personal.yml", ".inforc:\n name: peter venkman")
|
36
|
+
setup_file_with_content(".inforc.erb", "hello <%= personal['name'] %>")
|
37
|
+
Cli.new.setup(home_dir, dotfile_dir)
|
38
|
+
File.open(File.join(home_dir, '.inforc')) { |f| f.read }.should == "hello peter venkman"
|
39
|
+
end
|
40
|
+
|
41
|
+
def setup_file_with_content(name, content)
|
42
|
+
File.open(File.join(dotfile_dir, name), "w") { |f| f.write(content) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup_the_dotfile(content)
|
46
|
+
setup_file_with_content("Dotfile", content)
|
47
|
+
end
|
48
|
+
|
49
|
+
def setup_dotfiles(files)
|
50
|
+
files.each { |fn| FileUtils.touch(File.join(dotfile_dir, fn)) }
|
51
|
+
end
|
52
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative "../lib/polka"
|
2
|
+
include Polka
|
3
|
+
|
4
|
+
module FileSetupHelper
|
5
|
+
def set_up_testdirs
|
6
|
+
let(:home_dir) { "home_dir" }
|
7
|
+
let(:dotfile_dir) { "home_dir/.dotfile_dir" }
|
8
|
+
|
9
|
+
before do
|
10
|
+
FileUtils.mkdir(home_dir)
|
11
|
+
FileUtils.mkdir(dotfile_dir)
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
FileUtils.rm_rf(home_dir)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
RSpec.configure do |config|
|
21
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
22
|
+
config.extend FileSetupHelper, :integrated_with_files
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: polka
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Michi Huber
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: &70162070820700 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.16.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70162070820700
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: colorize
|
27
|
+
requirement: &70162070820180 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - =
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.5.8
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70162070820180
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70162070819580 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.11'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70162070819580
|
47
|
+
description: Easy Dotfile Management
|
48
|
+
email:
|
49
|
+
- michi.huber@gmail.com
|
50
|
+
executables:
|
51
|
+
- polka
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- Gemfile
|
57
|
+
- Gemfile.lock
|
58
|
+
- LICENSE
|
59
|
+
- bin/polka
|
60
|
+
- lib/polka.rb
|
61
|
+
- lib/polka/bootstrapper.rb
|
62
|
+
- lib/polka/cli.rb
|
63
|
+
- lib/polka/dotfile.rb
|
64
|
+
- lib/polka/dotfile_group.rb
|
65
|
+
- lib/polka/operations/parsed_copying.rb
|
66
|
+
- lib/polka/version.rb
|
67
|
+
- polka.gemspec
|
68
|
+
- spec/polka/bootstrapper_spec.rb
|
69
|
+
- spec/polka/cli_spec.rb
|
70
|
+
- spec/polka/dotfile_group_spec.rb
|
71
|
+
- spec/polka/dotfile_spec.rb
|
72
|
+
- spec/polka/operations/parsed_copying_spec.rb
|
73
|
+
- spec/polka_spec.rb
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
homepage: http://github.com/michihuber/polka
|
76
|
+
licenses: []
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 1.8.11
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: ''
|
99
|
+
test_files:
|
100
|
+
- spec/polka/bootstrapper_spec.rb
|
101
|
+
- spec/polka/cli_spec.rb
|
102
|
+
- spec/polka/dotfile_group_spec.rb
|
103
|
+
- spec/polka/dotfile_spec.rb
|
104
|
+
- spec/polka/operations/parsed_copying_spec.rb
|
105
|
+
- spec/polka_spec.rb
|
106
|
+
- spec/spec_helper.rb
|