dotmation 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", "~> 2.13.0"
10
+ gem "rdoc", "~> 4.0.0"
11
+ gem "bundler", "~> 1.3.5"
12
+ gem "jeweler", "~> 1.8.4"
13
+ gem "simplecov", "~> 0.7.1"
14
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2013 Brigham Young University
2
+ Authored by John T. Prince
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,107 @@
1
+ ## dotmation
2
+
3
+ Github aware manager for environment files (e.g. dotfiles) inspired by fresh.
4
+ It has far fewer features than fresh and is written in ruby (taken together it
5
+ means it *may* be easier to extend).
6
+
7
+ This is *alpha* software -- use at your own risk!
8
+
9
+ Features
10
+ * depends on ruby
11
+ * ruby dsl config file
12
+ * not yet as full featured as fresh but easy to customize if you write ruby
13
+
14
+ ## Installation
15
+
16
+ gem install dotmation
17
+
18
+ ### Usage
19
+
20
+ Assuming your dotmation file resides or is linked where expected
21
+ (~/.config/dotmation/config), then usage is trivial:
22
+
23
+ dotmation update
24
+
25
+ The first time you run dotmation, you will need to give it the filename or URI
26
+ to your dotmation file, or a github username (assuming it is in
27
+ <user>/dotfiles/master/config/dotmation/config)
28
+
29
+ dotmation update --config your_github_username
30
+ # --OR--
31
+ dotmation update --config path/to/your/dotmation/config
32
+ # --OR--
33
+ dotmation update --config https://url/to/your/dotmation/config
34
+
35
+ ### Configuration
36
+
37
+ A dotmation config file is pure ruby code, so anything you can do in ruby you
38
+ can do in your config file.
39
+ ```ruby
40
+
41
+ repo_cache "~/dotrepos" # where to stash github repos
42
+
43
+ github "jtprince/dotfiles/config" do
44
+ cfg 'dotmation' # symlink ~/.config/dotmation directory
45
+
46
+ dot 'Xresources' # symlink ~/.Xresources
47
+ dot 'Xresources', '.Xdefaults' # symlink ~/.Xdefaults -> Xresources
48
+
49
+ dot 'zsh/zshenv', '.zshenv' # symlink ~/.zshenv
50
+ cfg 'zsh' # symlink ~/.config/zsh directory
51
+
52
+ cfg 'dunstrc' # symlink ~/.config/dunstrc
53
+ cfg 'i3/config', 'i3/' # symlink ~/.config/i3/config inside i3 dir
54
+
55
+ # Trailing slash -> the file is to go under the given directory.
56
+ end
57
+
58
+ github "jtprince/dotfiles/bin" do
59
+ ln '.'
60
+ end
61
+
62
+ github "robbyrussell/oh-my-zsh" do
63
+ cfg '.' # symlink ~/.config/oh-my-zsh
64
+ end
65
+
66
+ ```
67
+
68
+ See a [real world example](https://github.com/jtprince/dotfiles/blob/master/config/dotmation/config).
69
+
70
+ The config file will be read in context of Dotmation::ConfigReader which is
71
+ responsible for creating repo objects and populating them with link objects.
72
+ All objects are created before being used to make links, so they can be easily
73
+ inspected.
74
+
75
+ ## Bootstrap an Installation
76
+
77
+ There are several chicken and egg problems with setting up an evironment
78
+ without an environment. This shell script initializes an environment to work
79
+ with dotmation(for debian systems).
80
+
81
+ bash -c `curl -sL https://raw.github.com/jtprince/dotmation/master/script/bootstrap-ruby-env.sh`
82
+
83
+ This will install:
84
+
85
+ * rbenv
86
+ * ruby-build
87
+ * critical deb packages for building:
88
+ * git curl zlib1g-dev build-essential libssl-dev libreadline-dev
89
+ * the latest stable ruby
90
+ * dotmation
91
+
92
+ Beware, it will write to (or create) ~/.profile, remove .bash_profile, and
93
+ write to ~/.bashrc. Of course, all of these changes will be clobbered with
94
+ your own fresh symlinks (assuming you use these files) once you run dotmation
95
+ update. The bootstrap supports the bash shell only (but you're smart enough
96
+ to drop down to bash to run the initial update if you're using a different
97
+ shell)
98
+
99
+ ## todo
100
+
101
+ * Add bitbucket support.
102
+ * work out kinks with more complicated destinations
103
+ * use git@github instead of https:// for read/write access
104
+
105
+ ## Copying
106
+
107
+ MIT license
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "dotmation"
18
+ gem.homepage = "http://github.com/jtprince/dotmation"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{ruby dsl/config to softlink dotfiles}
21
+ gem.description = %Q{ruby dsl/config to softlink dotfiles that is somewhat github aware}
22
+ gem.email = "jtprince@gmail.com"
23
+ gem.authors = ["John T. Prince"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ task :default => :spec
35
+
36
+ require 'rdoc/task'
37
+ Rake::RDocTask.new do |rdoc|
38
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
39
+
40
+ rdoc.rdoc_dir = 'rdoc'
41
+ rdoc.title = "dotmation #{version}"
42
+ rdoc.rdoc_files.include('README*')
43
+ rdoc.rdoc_files.include('lib/**/*.rb')
44
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'dotmation'
4
+ require 'optparse'
5
+ require 'open-uri'
6
+
7
+ progname = File.basename(__FILE__)
8
+
9
+ opt = {}
10
+ opts = OptionParser.new do |op|
11
+ op.banner = "usage: #{progname} <cmd>"
12
+ op.separator ""
13
+ op.separator "commands:"
14
+ op.separator " update"
15
+ op.separator ""
16
+ op.separator "options:"
17
+ op.on("--config <arg>", "arg may be a url or file", "may also be a github user name", "expects: #{Dotmation::DEFAULT_CONFIG_GITHUB_PATH}") do |v|
18
+ opt[:config] = v
19
+ end
20
+ end
21
+ opts.parse!
22
+
23
+ if ARGV.size == 0
24
+ puts opts
25
+ exit
26
+ end
27
+
28
+ (methd, *args) = ARGV
29
+
30
+ methd=methd.to_sym
31
+
32
+ args = [opt[:config]].compact
33
+ Dotmation.new(*args).send(methd)
@@ -0,0 +1,67 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "dotmation"
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["John T. Prince"]
12
+ s.date = "2013-05-09"
13
+ s.description = "ruby dsl/config to softlink dotfiles that is somewhat github aware"
14
+ s.email = "jtprince@gmail.com"
15
+ s.executables = ["dotmation"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ "Gemfile",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "bin/dotmation",
27
+ "dotmation.gemspec",
28
+ "lib/dotmation.rb",
29
+ "lib/dotmation/config_reader.rb",
30
+ "lib/dotmation/repo.rb",
31
+ "script/bootstrap-ruby-env.sh",
32
+ "spec/dotmation/repo_spec.rb",
33
+ "spec/dotmation_spec.rb",
34
+ "spec/spec_helper.rb",
35
+ "spec/testfiles/config"
36
+ ]
37
+ s.homepage = "http://github.com/jtprince/dotmation"
38
+ s.licenses = ["MIT"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = "1.8.23"
41
+ s.summary = "ruby dsl/config to softlink dotfiles"
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_development_dependency(%q<rspec>, ["~> 2.13.0"])
48
+ s.add_development_dependency(%q<rdoc>, ["~> 4.0.0"])
49
+ s.add_development_dependency(%q<bundler>, ["~> 1.3.5"])
50
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
51
+ s.add_development_dependency(%q<simplecov>, ["~> 0.7.1"])
52
+ else
53
+ s.add_dependency(%q<rspec>, ["~> 2.13.0"])
54
+ s.add_dependency(%q<rdoc>, ["~> 4.0.0"])
55
+ s.add_dependency(%q<bundler>, ["~> 1.3.5"])
56
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
57
+ s.add_dependency(%q<simplecov>, ["~> 0.7.1"])
58
+ end
59
+ else
60
+ s.add_dependency(%q<rspec>, ["~> 2.13.0"])
61
+ s.add_dependency(%q<rdoc>, ["~> 4.0.0"])
62
+ s.add_dependency(%q<bundler>, ["~> 1.3.5"])
63
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
64
+ s.add_dependency(%q<simplecov>, ["~> 0.7.1"])
65
+ end
66
+ end
67
+
@@ -0,0 +1,96 @@
1
+ require 'open-uri'
2
+ require 'fileutils'
3
+ require 'dotmation/config_reader'
4
+ require 'dotmation/repo'
5
+
6
+ class Dotmation
7
+
8
+ CONFIG_HOME = ENV['XDG_CONFIG_HOME'] || "#{ENV['HOME']}/.config"
9
+ DEFAULT_CONFIG_PATH = CONFIG_HOME + '/dotmation/config'
10
+ DEFAULT_CONFIG_GITHUB_REPO = "dotfiles"
11
+ DEFAULT_CONFIG_GITHUB_PATH = "config/dotmation/config"
12
+ GITHUB_REPO_BASE = "https://github.com"
13
+ DEFAULT_REPO_CACHE_DIR = "~/dotfile_repo"
14
+
15
+ attr_accessor :config_data
16
+
17
+ attr_accessor :data
18
+ attr_accessor :repos
19
+
20
+ # quick check to see if this looks like a dotmation config file
21
+ def is_config?
22
+ @config_data.match(/dot|xdg/)
23
+ end
24
+
25
+ # arg is the path to the config file (checks for existence first), a url or
26
+ # a github name. If given a file then it can give line number error
27
+ # messages.
28
+ def initialize(arg=DEFAULT_CONFIG_PATH)
29
+ @config_data =
30
+ if File.exist?(arg)
31
+ @config_filename = arg
32
+ IO.read(arg)
33
+ else # url or github name
34
+ uri =
35
+ if arg.include?("://")
36
+ arg
37
+ else
38
+ "https://raw.github.com/#{arg}/#{DEFAULT_CONFIG_GITHUB_REPO}/master/#{DEFAULT_CONFIG_GITHUB_PATH}"
39
+ end
40
+ open(uri) {|io| io.read }
41
+ end
42
+ warn "couldn't find config file locally or on github" unless is_config?
43
+ read_config!
44
+ end
45
+
46
+ def repo_cache
47
+ if @repo_cache
48
+ @repo_cache
49
+ else
50
+ @repo_cache =
51
+ if @data[:repo_cache]
52
+ File.expand_path(@data[:repo_cache])
53
+ else
54
+ File.expand_path(DEFAULT_REPO_CACHE_DIR)
55
+ end
56
+ end
57
+ end
58
+
59
+ def update(opts={})
60
+ unless opts[:no_update_github]
61
+ update_github_repos!
62
+ end
63
+ link!
64
+ end
65
+
66
+ def link!
67
+ repos.each(&:link!)
68
+ end
69
+
70
+ def update_github_repos!
71
+ FileUtils.mkpath(repo_cache) unless File.directory?(repo_cache)
72
+ Dir.chdir(repo_cache) do
73
+ repos_grouped_by_name(:github).each do |user_repo, repos|
74
+ repos.each {|r| r.cache_dir = repo_cache }
75
+ (user, repo) = user_repo.split('/')
76
+ FileUtils.mkdir(user) unless File.directory?(user)
77
+ Dir.chdir(user) do
78
+ if File.directory?(repo)
79
+ Dir.chdir(repo) { print `git pull` }
80
+ else
81
+ print `git clone #{GITHUB_REPO_BASE}/#{user}/#{repo}.git`
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ def repos_grouped_by_name(type=:github)
89
+ repos.select {|r| r.type == type }.group_by {|r| r.repo_name }
90
+ end
91
+
92
+ def read_config!
93
+ (@data, @repos) = ConfigReader.new.read(@config_data, @config_filename)
94
+ end
95
+
96
+ end
@@ -0,0 +1,30 @@
1
+ require 'dotmation/repo'
2
+
3
+ class Dotmation
4
+
5
+ class ConfigReader
6
+ # returns a list of links and a hash of any other values given outside
7
+ # standard blocks
8
+ def read(config_data, config_filename=nil)
9
+ @available_repos = Repo.classes_as_lc_symbols
10
+ @data = {}
11
+ @repos = []
12
+ args = [config_filename].compact
13
+ eval( config_data, binding, *args )
14
+ [@data, @repos]
15
+ end
16
+
17
+ def method_missing(methd, *argv, &block)
18
+ if Dotmation::Repo::Link::METHODS.include?(methd)
19
+ @repos.last.links << Dotmation::Repo::Link.new(methd, *argv)
20
+ elsif @available_repos.include?(methd) && block
21
+ @repos << Repo.const_get(methd.to_s.capitalize).new( *argv )
22
+ instance_eval(&block)
23
+ else
24
+ arg = (argv.size==1 ? argv.first : argv)
25
+ @data[methd] = arg
26
+ end
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,134 @@
1
+ require 'fileutils'
2
+
3
+ class Dotmation
4
+ module Repo
5
+ Sys = FileUtils
6
+
7
+ Link = Struct.new(:methd, :file, :linkname)
8
+ class Link
9
+ METHODS = [:dot, :cfg, :ln]
10
+ end
11
+
12
+ def self.classes_as_lc_symbols
13
+ self.constants.map {|v| v.to_s.downcase.to_sym }
14
+ end
15
+
16
+ attr_accessor :path
17
+ attr_accessor :links
18
+
19
+ def initialize(path)
20
+ @path = path
21
+ @links = []
22
+ end
23
+
24
+ def type
25
+ self.class.to_s.downcase.split('::').last.to_sym
26
+ end
27
+
28
+ class Local
29
+ include Repo
30
+ end
31
+
32
+ class Github
33
+ include Repo
34
+ attr_accessor :cache_dir
35
+
36
+ def path_parts
37
+ @path_parts ||= path.split('/')
38
+ end
39
+
40
+ def repo_name
41
+ path_parts[0,2].join('/')
42
+ end
43
+
44
+ def user
45
+ path_parts.first
46
+ end
47
+
48
+ def project
49
+ path_parts[1]
50
+ end
51
+
52
+ def extra_path
53
+ path_parts[2..-1].join('/')
54
+ end
55
+
56
+ # makes sure the directory exists. If it is a file, deletes the file
57
+ # and makes a directory
58
+ def ensure_dir(dir)
59
+ if File.exist?(dir)
60
+ unless File.directory?(dir)
61
+ File.rm_f(dir)
62
+ ensure_dir(dir)
63
+ end
64
+ else
65
+ Sys.mkpath(dir)
66
+ end
67
+ true
68
+ end
69
+
70
+ def no_trailing_slash(dir)
71
+ (dir[-1] == '/') ? dir[0...-1] : dir
72
+ end
73
+
74
+ # returns true if defined and there is a trailing slash
75
+ def target_is_dir?(dir)
76
+ dir && (dir[-1] == '/')
77
+ end
78
+
79
+ def ensure_underdir( link )
80
+ dir = File.dirname(link)
81
+ Sys.mkpath(dir)
82
+ end
83
+
84
+ def link!(opts={})
85
+ opts[:home] ||= ENV['HOME']
86
+ opts[:config_home] ||= Dotmation::CONFIG_HOME
87
+ [:home, :config_home].each {|sym| opts[sym] = no_trailing_slash(opts[sym]) }
88
+
89
+ ensure_dir( opts[:config_home] )
90
+ ensure_dir( opts[:home] )
91
+
92
+ Dir.chdir(cache_dir) do
93
+ Dir.chdir(self.path) do
94
+ @links.each do |link|
95
+ target_is_dir = target_is_dir?(link.linkname)
96
+ symlink =
97
+ case link.methd
98
+ when :cfg
99
+ File.join( opts[:config_home], link.linkname || '' )
100
+ when :dot
101
+ if link.linkname
102
+ File.join( opts[:home], link.linkname )
103
+ else
104
+ File.join( opts[:home], (link.file[0]=='.') ? link.file : ".#{link.file}" )
105
+ end
106
+ when :ln
107
+ if link.linkname
108
+ File.join( opts[:home], link.linkname )
109
+ else
110
+ File.join( opts[:home], link.file )
111
+ end
112
+ end
113
+
114
+ if link.linkname && link.linkname.include?('/')
115
+ ensure_underdir( symlink )
116
+ end
117
+ ensure_dir( symlink ) if target_is_dir
118
+ if File.exist?(symlink) && !File.directory?(symlink)
119
+ File.unlink(symlink)
120
+ end
121
+ file_to_link = File.expand_path(link.file)
122
+ #puts "TO LINK AN D SYMLINK:"
123
+ #p File.exist?(file_to_link)
124
+ #p file_to_link
125
+ #p symlink
126
+ Sys.ln_sf(file_to_link, symlink)
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,79 @@
1
+ #!/bin/bash
2
+
3
+ # ensures that we have a recent version of ruby installed
4
+ # and kicks things over to initialize.rb
5
+
6
+ set -o pipefail
7
+
8
+ pushd $HOME
9
+
10
+ if [ -f /etc/debian_version ]; then
11
+ RBENV_PREREQS="git curl zlib1g-dev build-essential libssl-dev libreadline-dev"
12
+ echo "debian based system"
13
+ echo "going to install prereqs: $RBENV_PREREQS"
14
+ sudo apt-get install $RBENV_PREREQS
15
+ fi
16
+
17
+ # rbenv
18
+ if [ ! -d ~/.rbenv ]; then
19
+ git clone git://github.com/sstephenson/rbenv.git .rbenv
20
+ export PATH="$HOME/.rbenv/bin:$PATH"
21
+ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.profile
22
+ if [ -f ~/.bash_profile ]; then
23
+ mv -f ~/.bash_profile ~/dot-bash_profile.orig
24
+ fi
25
+ eval "$(rbenv init -)"
26
+ fi
27
+
28
+ # ruby-build
29
+ if [ ! -d ~/.rbenv/plugins/ruby-build ]; then
30
+ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
31
+ fi
32
+ export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
33
+
34
+ # what is the latest stable ruby build?
35
+ latest_ruby=`rbenv install --list | grep 'p[0-9]\+' | tail -1`
36
+
37
+ # install it if we don't have it
38
+ our_ruby=`rbenv versions | grep -o '[0-9\.]\+-p[0-9]\+' | tail -1`
39
+
40
+ if [ "$our_ruby" == "$latest_ruby" ]; then
41
+ rbenv install "$latest_ruby"
42
+ rbenv rehash
43
+ fi
44
+
45
+ gem install dotmation
46
+
47
+ cat <<-MESSAGE
48
+ ___ ___ ___
49
+ /\ \ /\ \ /\ \
50
+ /::\ \ /::\ \ \:\ \
51
+ /:/\:\__\ /:/\:\__\ /::\__\
52
+ \:\/:/ / \:\/:/ / /:/\/__/
53
+ \::/ / \::/ / \/__/
54
+ \/__/ \/__/
55
+ ___ ___ ___ ___ ___ ___
56
+ /\__\ /\ \ /\ \ /\ \ /\ \ /\__\
57
+ /::L_L_ /::\ \ \:\ \ _\:\ \ /::\ \ /:| _|_
58
+ /:/L:\__\ /::\:\__\ /::\__\ /\/::\__\ /:/\:\__\ /::|/\__\
59
+ \/_/:/ / \/\::/ / /:/\/__/ \::/\/__/ \:\/:/ / \/|::/ /
60
+ /:/ / /:/ / \/__/ \:\__\ \::/ / |:/ /
61
+ \/__/ \/__/ \/__/ \/__/ \/__/
62
+
63
+ If you already have a dotmation config file in the expected location
64
+ (~/.config/dotmation/config) then just:
65
+
66
+ dotmation update
67
+
68
+ If you don't have thinks linked up yet, you need to initialize:
69
+
70
+ dotmation init <path/to/dotmation/config>
71
+
72
+ # or, if you have the file on github: (dotfiles/config/dotmation/config)
73
+ dotmation init <github-user-name>
74
+
75
+ [Many thanks to the excellent programmers of 'fresh' for inspiration]
76
+ MESSAGE
77
+
78
+ popd
79
+
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ require 'fileutils'
4
+ require 'dotmation'
5
+
6
+ describe Dotmation::Repo do
7
+
8
+ describe 'making cfg links' do
9
+
10
+ before do
11
+ @preval = ENV['XDG_CONFIG_HOME']
12
+ @cache_dir = File.expand_path(TESTFILES + '/tmp_github')
13
+ @internal_git_dir = @cache_dir + '/user/project'
14
+ FileUtils.mkpath @internal_git_dir
15
+ @file = @internal_git_dir + "/myfile"
16
+ File.write(@file, 'hiya')
17
+ end
18
+
19
+ specify 'cfg makes proper links to xdg spec' do
20
+ cfg_dir = File.expand_path(TESTFILES + '/tmp_cfg')
21
+
22
+ repo = Dotmation::Repo::Github.new('user/project')
23
+ repo.cache_dir = @cache_dir
24
+
25
+ repo.links << Dotmation::Repo::Link.new(:cfg, "myfile")
26
+ repo.links << Dotmation::Repo::Link.new(:cfg, "myfile", "diff-name")
27
+ repo.links << Dotmation::Repo::Link.new(:cfg, "myfile", "indir/")
28
+
29
+ repo.link!(config_home: cfg_dir)
30
+
31
+ %w(myfile diff-name indir/myfile).each do |linkname|
32
+ link = cfg_dir + '/' + linkname
33
+ File.symlink?(link).should be_true
34
+ IO.read(link).should == 'hiya'
35
+ end
36
+ FileUtils.rm_rf cfg_dir
37
+ end
38
+
39
+ specify 'dot makes proper links to home dir' do
40
+ home_dir = File.expand_path(TESTFILES + '/tmp_home')
41
+ repo = Dotmation::Repo::Github.new('user/project')
42
+ repo.cache_dir = @cache_dir
43
+
44
+ repo.links << Dotmation::Repo::Link.new(:dot, "myfile")
45
+ repo.links << Dotmation::Repo::Link.new(:dot, "myfile", ".AnotherName")
46
+ repo.links << Dotmation::Repo::Link.new(:dot, "myfile", "subdir/AnotherNameLower")
47
+ repo.links << Dotmation::Repo::Link.new(:dot, "myfile", "NoLeadingDot")
48
+ repo.links << Dotmation::Repo::Link.new(:dot, "myfile", "subdir2/")
49
+
50
+ repo.link!(home: home_dir)
51
+
52
+ %w(.myfile .AnotherName subdir/AnotherNameLower NoLeadingDot subdir2/myfile).each do |linkname|
53
+ link = home_dir + '/' + linkname
54
+ File.symlink?(link).should be_true
55
+ IO.read(link).should == 'hiya'
56
+ end
57
+ FileUtils.rm_rf home_dir
58
+ end
59
+
60
+ specify 'ln just makes the link to home dir' do
61
+ home_dir = File.expand_path(TESTFILES + '/tmp_home')
62
+ repo = Dotmation::Repo::Github.new('user/project')
63
+ repo.cache_dir = @cache_dir
64
+
65
+ repo.links << Dotmation::Repo::Link.new(:ln, "myfile")
66
+ repo.links << Dotmation::Repo::Link.new(:ln, "myfile", ".AnotherName")
67
+ repo.links << Dotmation::Repo::Link.new(:ln, "myfile", "subdir/AnotherNameLower")
68
+ repo.links << Dotmation::Repo::Link.new(:ln, "myfile", "NoLeadingDot")
69
+ repo.links << Dotmation::Repo::Link.new(:ln, "myfile", "subdir2/")
70
+
71
+ repo.link!(home: home_dir)
72
+
73
+ %w(myfile .AnotherName subdir/AnotherNameLower NoLeadingDot subdir2/myfile).each do |linkname|
74
+ link = home_dir + '/' + linkname
75
+ File.symlink?(link).should be_true
76
+ IO.read(link).should == 'hiya'
77
+ end
78
+ FileUtils.rm_rf home_dir
79
+ end
80
+
81
+ after do
82
+ ENV['XDG_CONFIG_HOME'] = @preval
83
+ FileUtils.rm_rf @cache_dir
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ require 'dotmation'
4
+
5
+ describe Dotmation do
6
+ describe 'reading a config file' do
7
+ before do
8
+ @config = TESTFILES + "/config"
9
+ end
10
+
11
+ it 'can read it' do
12
+ dotmation = Dotmation.new(@config)
13
+ end
14
+
15
+ describe 'the data' do
16
+
17
+ let(:dotmation) { Dotmation.new(@config) }
18
+
19
+ it 'knows data' do
20
+ data = dotmation.data
21
+ data.should be_an(Hash)
22
+ data[:repo_cache].should == "spec/testfiles/tmprepos"
23
+ end
24
+
25
+ it 'has repos with links' do
26
+ repos = dotmation.repos
27
+ repos.size.should == 4
28
+ repos.map(&:type).partition.to_a.should == [:github, :github, :local, :github]
29
+ end
30
+
31
+ it 'knows which git repos it needs to get' do
32
+ dotmation.repos_grouped_by_name.keys.should == ["jtprince/dotfiles", "robbyrussell/oh-my-zsh"]
33
+ end
34
+
35
+ end
36
+
37
+ describe 'an update' do
38
+ #describe 'an update', :pending => 'only run occasionally -- requires internet' do
39
+ let(:dotmation) { Dotmation.new(@config) }
40
+
41
+ before(:all) do
42
+ @tmprepos_dir = TESTFILES + "/tmprepos"
43
+ end
44
+
45
+ # turn on when you want to test github download
46
+ it 'downloads github repos' do
47
+ dotmation.update
48
+ ["jtprince/dotfiles", "robbyrussell/oh-my-zsh"].each do |path|
49
+ base = @tmprepos_dir + "/" + path
50
+ git_file = base + "/.git"
51
+ File.exist?( git_file ).should be_true
52
+ end
53
+ end
54
+
55
+ it 'updates existing repos' do
56
+ dotmation.update
57
+ end
58
+
59
+ after(:all) do
60
+ FileUtils.rm_rf(@tmprepos_dir) if File.directory?(@tmprepos_dir)
61
+ end
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,14 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'rspec'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ #Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ end
13
+
14
+ TESTFILES = File.expand_path(File.dirname(__FILE__) + "/testfiles")
@@ -0,0 +1,29 @@
1
+
2
+ repo_cache "spec/testfiles/tmprepos" # where to put all the github repos
3
+
4
+ github "jtprince/dotfiles/config" do # stored in ~/dotrepos/jtprince/dotfiles
5
+ cfg 'dotmation' # symlink ~/.config/dotmation
6
+ cfg 'dunstrc' # symlink ~/.config/dunstrc
7
+ cfg 'zsh' # symlink ~/.config/zsh
8
+ cfg 'i3/config', 'i3/' # symlink ~/.config/i3/config
9
+
10
+ dot 'Xresources' # symlink ~/.Xresources
11
+ dot 'Xresources', '.Xdefaults' # symlink ~/.Xdefaults -> Xresources
12
+ dot 'zsh/zshenv' # symlink ~/.zshenv
13
+ end
14
+
15
+ github "jtprince/dotfiles" do
16
+ ln 'bin'
17
+ ln 'bin', '~/local/'
18
+ ln 'bin', '~/local/bin' # same as directly above
19
+ ln 'bin', '~/local' # would link to local if not exist or local/bin if local existed
20
+ end
21
+
22
+ # always interpreted from $HOME
23
+ local "Dropbox/special_stash" do
24
+ dot "dot-fonts", ".fonts"
25
+ end
26
+
27
+ github "robbyrussell/oh-my-zsh" do
28
+ cfg '.' # symlink ~/.config/oh-my-zsh
29
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dotmation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John T. Prince
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.13.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.13.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rdoc
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 4.0.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 4.0.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.3.5
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.5
62
+ - !ruby/object:Gem::Dependency
63
+ name: jeweler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 1.8.4
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.8.4
78
+ - !ruby/object:Gem::Dependency
79
+ name: simplecov
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 0.7.1
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.7.1
94
+ description: ruby dsl/config to softlink dotfiles that is somewhat github aware
95
+ email: jtprince@gmail.com
96
+ executables:
97
+ - dotmation
98
+ extensions: []
99
+ extra_rdoc_files:
100
+ - LICENSE
101
+ - README.md
102
+ files:
103
+ - Gemfile
104
+ - LICENSE
105
+ - README.md
106
+ - Rakefile
107
+ - VERSION
108
+ - bin/dotmation
109
+ - dotmation.gemspec
110
+ - lib/dotmation.rb
111
+ - lib/dotmation/config_reader.rb
112
+ - lib/dotmation/repo.rb
113
+ - script/bootstrap-ruby-env.sh
114
+ - spec/dotmation/repo_spec.rb
115
+ - spec/dotmation_spec.rb
116
+ - spec/spec_helper.rb
117
+ - spec/testfiles/config
118
+ homepage: http://github.com/jtprince/dotmation
119
+ licenses:
120
+ - MIT
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ segments:
132
+ - 0
133
+ hash: 2585038009321147917
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubyforge_project:
142
+ rubygems_version: 1.8.23
143
+ signing_key:
144
+ specification_version: 3
145
+ summary: ruby dsl/config to softlink dotfiles
146
+ test_files: []