dottor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+ gem "thor"
3
+ gem "rspec"
@@ -0,0 +1,20 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.3)
5
+ rspec (2.9.0)
6
+ rspec-core (~> 2.9.0)
7
+ rspec-expectations (~> 2.9.0)
8
+ rspec-mocks (~> 2.9.0)
9
+ rspec-core (2.9.0)
10
+ rspec-expectations (2.9.1)
11
+ diff-lcs (~> 1.1.3)
12
+ rspec-mocks (2.9.0)
13
+ thor (0.14.6)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ rspec
20
+ thor
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2012 Marco Campana
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,85 @@
1
+ Dottor
2
+ ======
3
+
4
+ Description
5
+ -----------
6
+ Dottor is an unobtrusive command line tool for easily managing your dotfiles,
7
+ without assumptions on how your dotfiles repository should be organized.
8
+
9
+ Why Dottor?
10
+ -----------
11
+ I designed dottor so that it would be easy to setup and use, reliable and work
12
+ with existing dotfiles repos.
13
+
14
+ With Dottor you can:
15
+
16
+ 1. Get started with yout current dotfils repo, without changing anything.
17
+ 2. Specify different profiles, so that you can use it to symlink files in your
18
+ dev machine as well as in your production boxes.
19
+
20
+ How it works?
21
+ -------------
22
+
23
+ Dottor expect to find in your repo a YAML file named dottor_rules.yml (or you
24
+ can specify a different path) with the following format
25
+
26
+ ```ruby
27
+ profile_name:
28
+ - source: <dotffile or directory>
29
+ target: <where do you want the file to be symlinked to>
30
+ - source: <dotffile or directory>
31
+ target: <where do you want the file to be symlinked to>
32
+ ```
33
+
34
+ All the actions performed by Dottor are based on the dottor_rules.yml file.
35
+ Check my [dotfiles repo][dotfiles_repo] for a working example.
36
+
37
+
38
+ Getting started
39
+ ---------------
40
+
41
+ ```
42
+ gem install dottor
43
+ ```
44
+
45
+ ### Create a dottor_rules.yml inside your dotfiles repo
46
+
47
+ ```
48
+ dottor init
49
+ ```
50
+
51
+ ### Create symlinks based on dottor_rules.yml file in current directory
52
+
53
+ ```
54
+ dottor symlink <profile_name>
55
+ ```
56
+
57
+ ### Specify a dottor_rules.yml file in another directory
58
+
59
+ ```
60
+ dottor symlink <profile_name> -f <custom_path>
61
+ ```
62
+
63
+ ### Delete all the symlinks
64
+
65
+ ```
66
+ dottor symlink -d
67
+ ```
68
+
69
+ Submitting a Pull Request
70
+ -------------------------
71
+
72
+ 1. Fork the project.
73
+ 2. Create a topic branch.
74
+ 3. Implement your feature or bug fix.
75
+ 4. Add documentation for your feature or bug fix.
76
+ 6. Add specs for your feature or bug fix.
77
+ 8. Commit and push your changes.
78
+
79
+ License
80
+ -------
81
+ Released under the MIT License. See the [LICENSE][license] file for further
82
+ details.
83
+
84
+ [license]: https://github.com/marcocampana/dottor/blob/master/LICENSE.md
85
+ [dotfiles_repo]: https://github.com/marcocampana/dotfiles
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require "dottor"
3
+
4
+ Dottor::App.start
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "dottor/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "dottor"
7
+ s.version = Dottor::VERSION
8
+ s.authors = ["Marco Campana"]
9
+ s.email = ["m.campana@gmail.com"]
10
+ s.homepage = 'http://github.com/marcocampana/dottor'
11
+ s.summary = %q{Command line tool to manage dotfiles the easy way}
12
+ s.description = %q{Unobtrusive command line tool for easily managing your dotfiles, without assumptions on how your dotfiles repository should be organized.}
13
+
14
+ s.rubyforge_project = "dottor"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'thor'
22
+ s.add_development_dependency 'rspec'
23
+ end
@@ -0,0 +1,70 @@
1
+ require 'yaml'
2
+ require 'fileutils'
3
+ require 'thor'
4
+ require 'dottor/dotfile'
5
+
6
+ module Dottor
7
+ class App < Thor
8
+ desc "symlink <profile_name>", "Symlink dotfiles defined in specified profile name"
9
+ method_option :file, :aliases => "-f", :desc => "Use specified rules yaml file instead of the default dottor_rules.yml"
10
+ method_option :delete, :aliases => "-d", :desc => "Delete existing symlinks added by dottor"
11
+ def symlink(profile_name)
12
+ yaml_rules = options[:file] ? File.open(options[:file]) : File.open('dottor_rules.yml')
13
+
14
+ say("Loading rules YAML file")
15
+ rules = YAML::load(yaml_rules)
16
+
17
+ rules[profile_name].each do |mapping|
18
+ dotfile = Dotfile.new(mapping)
19
+ if options[:delete]
20
+ dotfile.delete_symlink
21
+ else
22
+ dotfile.create_symlink
23
+ end
24
+ end
25
+ end
26
+
27
+ desc "init", "Create dottor_rule.yml file"
28
+ method_option :force, :desc => "Overwrite existing dottor_rules.yml file"
29
+ def init
30
+ if File.exists?('dottor_rules.yml')
31
+ if options[:force]
32
+ FileUtils.rm 'dottor_rules.yml'
33
+ else
34
+ say("Abort: dottor_rules.yml already exist. Use the --force to overwrite.")
35
+ exit(1)
36
+ end
37
+ end
38
+
39
+ rules_hash = {"profile_name" => []}
40
+
41
+ exclude_files = ['.gitignore', 'README', 'README.md']
42
+ if git_repo?
43
+ files_in_current_dir = `git ls-files`.split("\n") - exclude_files
44
+ else
45
+ files_in_current_dir = Dir["*"] - exclude_files
46
+ end
47
+
48
+ if files_in_current_dir.empty?
49
+ rules_hash["profile_name"] = [{"source" => ".dotfile", "target" => "target_path/.dotfile"}]
50
+ else
51
+ files_in_current_dir.each do |file_name|
52
+ rules_hash["profile_name"] << {"source" => file_name, "target" => "target_path/#{file_name}"}
53
+ end
54
+ end
55
+
56
+ File.open('dottor_rules.yml', 'w') do |file|
57
+ file.write(YAML.dump(rules_hash))
58
+ end
59
+
60
+ say("dottor_rules.yml file created. Modify it and run 'dottor symlink <profile_name>'")
61
+ end
62
+
63
+ private
64
+
65
+ # TODO move into an helper module
66
+ def git_repo?
67
+ File.exists? '.git'
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,39 @@
1
+ module Dottor
2
+ class Dotfile
3
+ attr_accessor :source, :target
4
+
5
+ def initialize(hash)
6
+ @source = hash["source"]
7
+ @target = hash["target"]
8
+ end
9
+
10
+ def create_symlink
11
+ # If file exists rename it to .old
12
+ # TODO check if .old file already exists
13
+ if File.exists?(target)
14
+ old_file_name = "#{target}.old"
15
+ FileUtils.mv target, old_file_name
16
+ end
17
+
18
+ # If symlink exists, remove it
19
+ if File.symlink?(target)
20
+ FileUtils.rm target
21
+ end
22
+
23
+ $stdout.puts("Create symlink #{File.join(current_path, source)} -> #{target}")
24
+ FileUtils.symlink File.join(current_path, source), target
25
+ end
26
+
27
+ def delete_symlink
28
+ if File.symlink?(target)
29
+ FileUtils.rm target
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def current_path
36
+ Dir.pwd
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Dottor
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Dottor::App" do
4
+ describe "symlink" do
5
+ it "should use the dottor_rules.yml in current directory by default" do
6
+ stub_dottor_rules_file('dottor_rules.yml')
7
+ stub_dotfile
8
+
9
+ Dottor::App.start(['symlink', 'development'])
10
+ end
11
+
12
+ it "should use the specified dottor_rules file with -f option" do
13
+ stub_dottor_rules_file('../my_custom_dottor_rules.yml')
14
+ stub_dotfile
15
+
16
+ Dottor::App.start(['symlink', 'development', '-f', '../my_custom_dottor_rules.yml'])
17
+ end
18
+
19
+ it "should call the create_symlink method" do
20
+ stub_dottor_rules_file('dottor_rules.yml')
21
+ stub_dotfile(:create_symlink)
22
+
23
+ Dottor::App.start(['symlink', 'development'])
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ development:
3
+ - source: .vimrc
4
+ target: target_path/.vimrc
@@ -0,0 +1,13 @@
1
+ module Utils
2
+ def stub_dottor_rules_file(file_name)
3
+ dottor_rules_file = File.open(File.expand_path(File.dirname(__FILE__) + '/../fixtures/dottor_rules.yml'))
4
+ File.should_receive(:open).with(file_name).and_return(dottor_rules_file)
5
+ end
6
+
7
+ def stub_dotfile(method=nil)
8
+ dotfile_mock = mock(:delete_symlink => nil, :create_symlink => nil)
9
+ Dottor::Dotfile.should_receive(:new).and_return(dotfile_mock)
10
+
11
+ dotfile_mock.should_receive(method) if method
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ require 'rspec'
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
4
+ require 'dottor'
5
+ require 'helpers/utils'
6
+
7
+ RSpec.configure do |c|
8
+ c.include Utils
9
+
10
+ c.mock_with :rspec
11
+
12
+ c.before(:each) do
13
+ STDOUT.should_receive(:puts).and_return("")
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dottor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Marco Campana
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: &70257029527160 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70257029527160
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70257029524660 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70257029524660
36
+ description: Unobtrusive command line tool for easily managing your dotfiles, without
37
+ assumptions on how your dotfiles repository should be organized.
38
+ email:
39
+ - m.campana@gmail.com
40
+ executables:
41
+ - dottor
42
+ extensions: []
43
+ extra_rdoc_files: []
44
+ files:
45
+ - .gitignore
46
+ - Gemfile
47
+ - Gemfile.lock
48
+ - LICENSE.md
49
+ - README.md
50
+ - bin/dottor
51
+ - dottor.gemspec
52
+ - lib/dottor.rb
53
+ - lib/dottor/dotfile.rb
54
+ - lib/dottor/version.rb
55
+ - spec/app_spec.rb
56
+ - spec/fixtures/dottor_rules.yml
57
+ - spec/helpers/utils.rb
58
+ - spec/spec_helper.rb
59
+ homepage: http://github.com/marcocampana/dottor
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project: dottor
79
+ rubygems_version: 1.8.15
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Command line tool to manage dotfiles the easy way
83
+ test_files:
84
+ - spec/app_spec.rb
85
+ - spec/fixtures/dottor_rules.yml
86
+ - spec/helpers/utils.rb
87
+ - spec/spec_helper.rb
88
+ has_rdoc: