dotstrap 0.1.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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/CONTRIBUTING.md +11 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +20 -0
- data/README.md +97 -0
- data/Rakefile +49 -0
- data/bin/ds +176 -0
- data/dotstrap.gemspec +84 -0
- data/lib/dotstrap/git.rb +52 -0
- data/lib/dotstrap/shell.rb +177 -0
- data/lib/dotstrap.rb +151 -0
- data/spec/bundle_spec.rb +34 -0
- data/spec/shell_spec.rb +71 -0
- data/spec/spec_helper.rb +33 -0
- metadata +203 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 13228e7638010414944c3e805f6d4811dca803e1
|
4
|
+
data.tar.gz: 1e4669204ab6d0ef4477de3abad526647c21b7e0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 391562df75f5595bc22723ccf8ae3a687ff036eca55292e74dd019fe6a2ba388acc2a60269d92a2282d27041fee6f92d6ca5c5906ca9adce157362b824bcbd09
|
7
|
+
data.tar.gz: 368eada68300c2001e80bb60f5e5b4f3e2657697ae92b93e6a12d3ca43315d71128103ee7f5c8d8844c2a1202d77286b459f70b6e17e8c509166733a6cb1b198
|
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Contributing to dotstrap
|
2
|
+
|
3
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
4
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
5
|
+
* Fork the project.
|
6
|
+
* Start a feature/bugfix branch.
|
7
|
+
* Commit and push until you are happy with your contribution.
|
8
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
9
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
10
|
+
|
11
|
+
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
gem 'colorize', '~> 0.7'
|
4
|
+
gem 'parallel', '~> 1.6'
|
5
|
+
gem 'thor', '~> 0.19'
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem 'rspec', '~> 3.3'
|
9
|
+
gem 'yard', '~> 0.7'
|
10
|
+
gem 'rdoc', '~> 3.12'
|
11
|
+
gem 'bundler', '~> 1.0'
|
12
|
+
gem 'jeweler', '~> 2.0'
|
13
|
+
gem 'simplecov', '~> 0.10'
|
14
|
+
gem 'factory_girl', '~> 4.0'
|
15
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2015 William Myers
|
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/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# dotstrap
|
2
|
+
[](https://badge.fury.io/rb/dotstrap)
|
3
|
+
[](https://travis-ci.org/mkwmms/dotstrap)
|
4
|
+
[](https://codeclimate.com/github/mkwmms/dotstrap)
|
5
|
+
[](http://inch-ci.org/github/mkwmms/dotstrap)
|
6
|
+
[](https://gemnasium.com/mkwmms/dotstrap)
|
7
|
+
|
8
|
+
Downloads repositories from GitHub in parallel and symbolically links and/or
|
9
|
+
creates a file to be sourced in your `~/.zshrc`, `~/.bash_profile`, or `~/.config/fish/config.fish`
|
10
|
+
|
11
|
+
## get it
|
12
|
+
|
13
|
+
```bash
|
14
|
+
gem install dotstrap
|
15
|
+
```
|
16
|
+
|
17
|
+
__or stay on the bleeding edge:__
|
18
|
+
|
19
|
+
requires [bundler]
|
20
|
+
|
21
|
+
```bash
|
22
|
+
git clone https://github.com/mkwmms/dotstrap.git
|
23
|
+
```
|
24
|
+
|
25
|
+
```bash
|
26
|
+
rake install
|
27
|
+
```
|
28
|
+
|
29
|
+
## use it
|
30
|
+
|
31
|
+
download (or update) and configure `REPOs`:
|
32
|
+
```bash
|
33
|
+
ds install REPO|FILE
|
34
|
+
```
|
35
|
+
|
36
|
+
completely remove any symbolic links, `source` statements from dotstrap's config file, & the repository itself:
|
37
|
+
```bash
|
38
|
+
ds uninstall REPO
|
39
|
+
```
|
40
|
+
|
41
|
+
list the URL and install path for all currently installed repositories:
|
42
|
+
```bash
|
43
|
+
ds list [REPO]
|
44
|
+
```
|
45
|
+
|
46
|
+
`REPO` is a GitHub repository slug like `mkwmms/dotstrap-osx`
|
47
|
+
|
48
|
+
`FILE` is a newline separated list of `REPOS`
|
49
|
+
|
50
|
+
## how it works
|
51
|
+
|
52
|
+
#### bash
|
53
|
+
|
54
|
+
add `source "$XDG_CONFIG_HOME/dotstrap/config.bash"` to your `~/.bash_profile` or similar
|
55
|
+
|
56
|
+
- `*.bash` files' paths are written to: `$XDG_CONFIG_HOME/dotstrap/config.bash`
|
57
|
+
- `*.sh` files' paths are written to: `$XDG_CONFIG_HOME/dotstrap/config.bash`
|
58
|
+
|
59
|
+
#### zsh
|
60
|
+
|
61
|
+
add `source "$XDG_CONFIG_HOME/dotstrap/dotstrap.zsh"` to your `~/.zshrc`
|
62
|
+
|
63
|
+
- `*.zsh` files' paths are written to: `$XDG_CONFIG_HOME/dotstrap/config.zsh`
|
64
|
+
- `*.sh` files' paths are written to: `$XDG_CONFIG_HOME/dotstrap/config.zsh`
|
65
|
+
|
66
|
+
#### fish
|
67
|
+
|
68
|
+
add `source "$XDG_CONFIG_HOME/dotstrap/config.fish"` to your `~/.config/fish/config.fish`
|
69
|
+
|
70
|
+
- `./functions/*.fish` are symbolically linked under `~/.config/fish/functions/`
|
71
|
+
- `./completions/*.fish` are symbolically linked under `~/.config/fish/completions/`
|
72
|
+
- all other `*.fish` files' paths are written to: `$XDG_CONFIG_HOME/dotstrap/config.fish`
|
73
|
+
|
74
|
+
_Note_: if `$XDG_CONFIG_HOME` is not set, it defaults to `~/.config`. Read about the [XDG] base directory spec.
|
75
|
+
|
76
|
+
## in the wild
|
77
|
+
The entire purpose of `dotstrap` is to help you make your dotfiles modular while still keeping your prompt speedy. I also wanted to be able to use my [dotfiles] on bash, [zsh] and [fish] (yes I use all three on a daily basis).
|
78
|
+
|
79
|
+
There are many repositories out there that will work out of the box with `dotstrap` and many more that would only require minimal tweaking to get them to work.
|
80
|
+
|
81
|
+
Check out the [wiki] for a good list of repos to get you started.
|
82
|
+
|
83
|
+
## similar projects
|
84
|
+
- [antibody]: super fast, great app written in go. It only does ZSH and it is dynamic (it doesn't create a static file that can be sourced from your shell's init file), but man those microseconds are precious when it comes to loading my shell prompt. I still use it sometimes though because it is pretty dang cool.
|
85
|
+
|
86
|
+
|
87
|
+
[dotfiles]: https://github.com/mkwmms/dotfiles
|
88
|
+
[wiki]: https://github.com/mkwmms/dotstrap/wiki
|
89
|
+
|
90
|
+
[XDG]: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
91
|
+
|
92
|
+
[homebrew]: https://github.com/Homebrew/homebrew
|
93
|
+
[bundler]: https://github.com/bundler/bundler/
|
94
|
+
[antibody]: https://github.com/caarlos0/antibody
|
95
|
+
[zsh]: http://zsh.sourceforge.net
|
96
|
+
[fish]: http://fishshell.com/
|
97
|
+
[fasd]: https://github.com/clvv/fasd
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require_relative 'lib/dotstrap'
|
4
|
+
|
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.name = Dotstrap::NAME
|
17
|
+
gem.version = Dotstrap::VERSION
|
18
|
+
gem.homepage = Dotstrap::HOMEPAGE
|
19
|
+
gem.license = 'MIT'
|
20
|
+
gem.summary = Dotstrap::SUMMARY
|
21
|
+
gem.description = Dotstrap::DESCRIPTION
|
22
|
+
# gem.email = Dotstrap::EMAIL
|
23
|
+
gem.authors = Dotstrap::AUTHOR
|
24
|
+
gem.require_paths = ['lib']
|
25
|
+
gem.executables = ['ds']
|
26
|
+
gem.required_ruby_version = '>=1.9.2'
|
27
|
+
gem.metadata = { 'source_code' => Dotstrap::SOURCE_URL,
|
28
|
+
'documentation' => Dotstrap::DOC_URL
|
29
|
+
}
|
30
|
+
# dependencies defined in Gemfile
|
31
|
+
end
|
32
|
+
Jeweler::RubygemsDotOrgTasks.new
|
33
|
+
|
34
|
+
require 'rspec/core'
|
35
|
+
require 'rspec/core/rake_task'
|
36
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
37
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'Code coverage detail'
|
41
|
+
task :simplecov do
|
42
|
+
ENV['COVERAGE'] = 'true'
|
43
|
+
Rake::Task['spec'].execute
|
44
|
+
end
|
45
|
+
|
46
|
+
task default: :spec
|
47
|
+
|
48
|
+
require 'yard'
|
49
|
+
YARD::Rake::YardocTask.new
|
data/bin/ds
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'thor'
|
5
|
+
require 'dotstrap'
|
6
|
+
require 'colorize'
|
7
|
+
|
8
|
+
# Initialize logging
|
9
|
+
$LOG = Logger.new(STDOUT)
|
10
|
+
$LOG.level = Logger::WARN
|
11
|
+
$LOG.formatter = proc do |severity, datetime, progname, msg|
|
12
|
+
case (severity)
|
13
|
+
when 'ANY'
|
14
|
+
"#{msg}\n"
|
15
|
+
when 'DEBUG'
|
16
|
+
"#{'Debug'.underline}: #{datetime}: #{msg}\n"
|
17
|
+
when 'INFO'
|
18
|
+
"#{msg}\n"
|
19
|
+
when 'WARN'
|
20
|
+
"#{'Warning'.colorize(:yellow).underline}: #{msg}\n"
|
21
|
+
else
|
22
|
+
"#{severity.colorize(:red).underline}: #{datetime} #{msg}\n"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def __repo_format_desc; <<-DESC
|
27
|
+
REPO is a GitHub repository slug in the form: `username/repository`
|
28
|
+
|
29
|
+
If REPO is a file: read a newline seperated list of repositories
|
30
|
+
(in the form specified above)
|
31
|
+
\x5Lines starting with `#` are treated as comments and are ignored.
|
32
|
+
DESC
|
33
|
+
end
|
34
|
+
|
35
|
+
module Dotstrap
|
36
|
+
class Dotstrap::Cli < Thor
|
37
|
+
class_option 'verbose', type: :boolean, aliases: '-v',
|
38
|
+
desc: 'Enable verbose output mode'
|
39
|
+
class_option 'debug', type: :boolean, aliases: '-d',
|
40
|
+
desc: 'Enable debug output mode'
|
41
|
+
# class_option "quiet", :type => :boolean, :aliases => "-q",
|
42
|
+
# :desc => "Supress all output"
|
43
|
+
map %w[--version -V] => :__print_version
|
44
|
+
|
45
|
+
desc "--version, -V", "Print the version and exit"
|
46
|
+
def __print_version
|
47
|
+
puts "#{Dotstrap::NAME.colorize(:blue)} #{Dotstrap::VERSION}"
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'install REPO...', 'Download and configure REPO'
|
52
|
+
long_desc <<-LONGDESC
|
53
|
+
Download REPO(s) & set up the configuration file(s) so they can
|
54
|
+
be loaded by the shell environment
|
55
|
+
by creating a file to be sourced from within your shell startup file
|
56
|
+
and/or symbolically linking relevant files.
|
57
|
+
|
58
|
+
#{__repo_format_desc}
|
59
|
+
|
60
|
+
Remember to source dotstrap's config file in your shell's startup file:
|
61
|
+
\x5 `echo "source #{Dotstrap.config_file}" >> #{Dotstrap.shell_profile}`
|
62
|
+
|
63
|
+
Examples:
|
64
|
+
\x5 Download https://github.com/mkwmms/dotstrap-osx to
|
65
|
+
#{Dotstrap.config_home}
|
66
|
+
and creates #{Dotstrap.config_file} with commands to
|
67
|
+
source all relevant configure files
|
68
|
+
\x5 $ ds install mkwmms/dotstrap-osx
|
69
|
+
|
70
|
+
Download all the repositories listed in the file ~/.config/repos.txt
|
71
|
+
\x5 $ ds install ~/.config/repos.txt
|
72
|
+
LONGDESC
|
73
|
+
def install(repo, *args)
|
74
|
+
args << repo # so thor will complain when you call `install` with no args
|
75
|
+
repos = []
|
76
|
+
args.each do |repo|
|
77
|
+
if File.exist?(repo)
|
78
|
+
File.open(repo).each do |line|
|
79
|
+
# FIXME: strip everything afer '#' until newline (repo # comment)
|
80
|
+
repos << line.strip unless line.start_with?('#')
|
81
|
+
end
|
82
|
+
else
|
83
|
+
repos << repo
|
84
|
+
end
|
85
|
+
end
|
86
|
+
repos = repos.reject(&:empty?)
|
87
|
+
|
88
|
+
__set_log_level
|
89
|
+
$LOG.debug { "REPO ARGS:#{repos}" }
|
90
|
+
Dotstrap::Configuration.new(repos).configure
|
91
|
+
end
|
92
|
+
|
93
|
+
desc 'uninstall REPO...', 'Remove specified REPO'
|
94
|
+
long_desc <<-LONGDESC
|
95
|
+
Removes REPO's shell configuration file(s) and
|
96
|
+
lines from dotstraps's config file.
|
97
|
+
|
98
|
+
#{__repo_format_desc}
|
99
|
+
LONGDESC
|
100
|
+
def uninstall(repo, *args)
|
101
|
+
args << repo # so thor will complain when you call `uninstall` with no args
|
102
|
+
repos = []
|
103
|
+
args.each do |repo|
|
104
|
+
if File.exist?(repo)
|
105
|
+
File.open(repo).each do |line|
|
106
|
+
args << line.strip unless line.start_with?('#')
|
107
|
+
end
|
108
|
+
else
|
109
|
+
repos << repo
|
110
|
+
end
|
111
|
+
end
|
112
|
+
repos = repos.reject(&:empty?)
|
113
|
+
|
114
|
+
__set_log_level
|
115
|
+
$LOG.debug { "REPO ARGS:#{repos}" }
|
116
|
+
Dotstrap::Configuration.new(repos).remove
|
117
|
+
end
|
118
|
+
|
119
|
+
desc 'list [REPO...]',
|
120
|
+
'Print directory path & URL for currently installed REPO'
|
121
|
+
long_desc <<-LONGDESC
|
122
|
+
Print directory path & URL for currently installed REPO OR
|
123
|
+
print directory path & URL for all currently installed repositories
|
124
|
+
if REPO is not specified
|
125
|
+
|
126
|
+
#{__repo_format_desc}
|
127
|
+
LONGDESC
|
128
|
+
def list(*args)
|
129
|
+
repos = []
|
130
|
+
if args.empty?
|
131
|
+
Dotstrap::Configuration.new(Dotstrap.installed_repos).list
|
132
|
+
return
|
133
|
+
end
|
134
|
+
|
135
|
+
args.each do |repo|
|
136
|
+
if File.exist?(repo)
|
137
|
+
File.open(repo).each do |line|
|
138
|
+
args << line.strip unless line.start_with?('#')
|
139
|
+
end
|
140
|
+
else
|
141
|
+
repos << repo
|
142
|
+
end
|
143
|
+
end
|
144
|
+
repos = repos.reject(&:empty?)
|
145
|
+
|
146
|
+
__set_log_level
|
147
|
+
$LOG.debug { "REPO ARGS:#{repos}" }
|
148
|
+
Dotstrap::Configuration.new(repos).list
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def __set_log_level(level = nil)
|
154
|
+
# $LOG.close; return if options[:quiet]
|
155
|
+
unless level
|
156
|
+
level =
|
157
|
+
if options[:verbose]
|
158
|
+
Logger::INFO
|
159
|
+
elsif options[:debug]
|
160
|
+
Logger::DEBUG
|
161
|
+
else
|
162
|
+
Logger::WARN
|
163
|
+
end
|
164
|
+
end
|
165
|
+
$LOG.level = level
|
166
|
+
# $LOG.warn { __garbled_output_warning_string } if $LOG.info?
|
167
|
+
end
|
168
|
+
|
169
|
+
def __garbled_output_warning_string
|
170
|
+
'Output might be slightly out of order because' \
|
171
|
+
' thread synchronization is expensive just for pretty output.'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
Dotstrap::Cli.start(ARGV)
|
data/dotstrap.gemspec
ADDED
@@ -0,0 +1,84 @@
|
|
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
|
+
# stub: dotstrap 0.1.0 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "dotstrap"
|
9
|
+
s.version = "0.1.0"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.metadata = { "documentation" => "http://www.rubydoc.info/github/mkwmms/dotstrap/master/Dotstrap", "source_code" => "http://github.com/mkwmms/dotstrap" } if s.respond_to? :metadata=
|
13
|
+
s.require_paths = ["lib"]
|
14
|
+
s.authors = ["William Myers"]
|
15
|
+
s.date = "2015-11-04"
|
16
|
+
s.description = "bootstrap your shell dotfiles in parallel from GitHub repos"
|
17
|
+
s.executables = ["ds"]
|
18
|
+
s.extra_rdoc_files = [
|
19
|
+
"LICENSE.txt",
|
20
|
+
"README.md"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
".document",
|
24
|
+
".rspec",
|
25
|
+
"CONTRIBUTING.md",
|
26
|
+
"Gemfile",
|
27
|
+
"LICENSE.txt",
|
28
|
+
"README.md",
|
29
|
+
"Rakefile",
|
30
|
+
"bin/ds",
|
31
|
+
"dotstrap.gemspec",
|
32
|
+
"lib/dotstrap.rb",
|
33
|
+
"lib/dotstrap/git.rb",
|
34
|
+
"lib/dotstrap/shell.rb",
|
35
|
+
"spec/bundle_spec.rb",
|
36
|
+
"spec/shell_spec.rb",
|
37
|
+
"spec/spec_helper.rb"
|
38
|
+
]
|
39
|
+
s.homepage = "http://github.com/mkwmms/dotstrap"
|
40
|
+
s.licenses = ["MIT"]
|
41
|
+
s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
|
42
|
+
s.rubygems_version = "2.4.5.1"
|
43
|
+
s.summary = "bootstrap your shell dotfiles in parallel from GitHub repos"
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
s.specification_version = 4
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<colorize>, ["~> 0.7"])
|
50
|
+
s.add_runtime_dependency(%q<parallel>, ["~> 1.6"])
|
51
|
+
s.add_runtime_dependency(%q<thor>, ["~> 0.19"])
|
52
|
+
s.add_development_dependency(%q<rspec>, ["~> 3.3"])
|
53
|
+
s.add_development_dependency(%q<yard>, ["~> 0.7"])
|
54
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
55
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
|
56
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.0"])
|
57
|
+
s.add_development_dependency(%q<simplecov>, ["~> 0.10"])
|
58
|
+
s.add_development_dependency(%q<factory_girl>, ["~> 4.0"])
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<colorize>, ["~> 0.7"])
|
61
|
+
s.add_dependency(%q<parallel>, ["~> 1.6"])
|
62
|
+
s.add_dependency(%q<thor>, ["~> 0.19"])
|
63
|
+
s.add_dependency(%q<rspec>, ["~> 3.3"])
|
64
|
+
s.add_dependency(%q<yard>, ["~> 0.7"])
|
65
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
66
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
67
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
68
|
+
s.add_dependency(%q<simplecov>, ["~> 0.10"])
|
69
|
+
s.add_dependency(%q<factory_girl>, ["~> 4.0"])
|
70
|
+
end
|
71
|
+
else
|
72
|
+
s.add_dependency(%q<colorize>, ["~> 0.7"])
|
73
|
+
s.add_dependency(%q<parallel>, ["~> 1.6"])
|
74
|
+
s.add_dependency(%q<thor>, ["~> 0.19"])
|
75
|
+
s.add_dependency(%q<rspec>, ["~> 3.3"])
|
76
|
+
s.add_dependency(%q<yard>, ["~> 0.7"])
|
77
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
78
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
79
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
80
|
+
s.add_dependency(%q<simplecov>, ["~> 0.10"])
|
81
|
+
s.add_dependency(%q<factory_girl>, ["~> 4.0"])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
data/lib/dotstrap/git.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module Dotstrap
|
5
|
+
# TODO: split this into Git < Downloader class
|
6
|
+
class Dotstrap::Git
|
7
|
+
attr_accessor :url, :repo,
|
8
|
+
:repo_path, :repo_name,
|
9
|
+
:github_user, :github_project
|
10
|
+
|
11
|
+
def initialize(repo, dest_dir = Dotstrap.config_home)
|
12
|
+
@repo = repo
|
13
|
+
# TODO: allow an option to specify to download with SSH or HTTPs from Git
|
14
|
+
@url = "https://github.com/#{@repo}"
|
15
|
+
partition = @repo.partition("/")
|
16
|
+
@github_user = partition[0]
|
17
|
+
@github_project = @repo_name = partition[2]
|
18
|
+
@repo_path = File.join(dest_dir, "#{@github_user}-#{@repo_name}")
|
19
|
+
# @repo_path = File.join(dest_dir, @github_user, @repo_name)
|
20
|
+
end
|
21
|
+
|
22
|
+
# FIXME: if user is not logged in to Git the prompt for username/password
|
23
|
+
# is mangled because the threads are not synchronized
|
24
|
+
def clone(url = @url, repo_path = @repo_path, repo = @repo)
|
25
|
+
if Dir.exist?(repo_path)
|
26
|
+
return pull(repo_path)
|
27
|
+
end
|
28
|
+
return false unless system('git', 'clone', *git_verbosity, url, repo_path)
|
29
|
+
$LOG.debug { "CLONE #{repo} #{url} #{repo_path}" }
|
30
|
+
$LOG.unknown { "#{'=> '.colorize(:blue)}#{repo}\nupdated" }
|
31
|
+
repo_path
|
32
|
+
end
|
33
|
+
|
34
|
+
def pull(repo_path = @repo_path, repo = @repo)
|
35
|
+
Dir.chdir(repo_path)
|
36
|
+
return false unless system('git', 'pull', *git_verbosity, repo_path)
|
37
|
+
$LOG.debug { "PULL #{repo} #{url} #{repo_path}" }
|
38
|
+
$LOG.unknown { "#{'=> '.colorize(:blue)}#{repo}\nupdated" }
|
39
|
+
repo_path
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def git_verbosity
|
45
|
+
if $LOG.debug?
|
46
|
+
'--verbose'
|
47
|
+
else
|
48
|
+
return '--quiet'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Dotstrap
|
4
|
+
class Dotstrap::Shell
|
5
|
+
# TODO: cleanup shell class & split it into 3+ classes with inheritence
|
6
|
+
attr_accessor :repo_path
|
7
|
+
|
8
|
+
# TODO: how to handle load order? ie. load path.fish first
|
9
|
+
def initialize(repo_path)
|
10
|
+
@repo_path = repo_path
|
11
|
+
end
|
12
|
+
|
13
|
+
def configure(repo_dir = @repo_path)
|
14
|
+
configure_fish(repo_dir) if should_configure_fish?
|
15
|
+
configure_zsh(repo_dir)
|
16
|
+
configure_bash(repo_dir)
|
17
|
+
$LOG.unknown { "configuration complete" }
|
18
|
+
end
|
19
|
+
|
20
|
+
def unconfigure(repo_dir = @repo_path)
|
21
|
+
return unless Dir.exist?(repo_dir)
|
22
|
+
unconfigure_fish(repo_dir) if should_configure_fish?
|
23
|
+
unconfigure_zsh(repo_dir)
|
24
|
+
unconfigure_bash(repo_dir)
|
25
|
+
FileUtils.rm_r(repo_dir, force: true, secure: true)
|
26
|
+
$LOG.unknown { "removed: #{repo_dir}\n" }
|
27
|
+
end
|
28
|
+
|
29
|
+
def configure_fish(repo_dir)
|
30
|
+
fish_functions(repo_dir).each do |f|
|
31
|
+
link_config_file(f, File.join(Dotstrap.shell_config_home('fish'),
|
32
|
+
'functions'))
|
33
|
+
end
|
34
|
+
|
35
|
+
fish_completions(repo_dir).each do |f|
|
36
|
+
link_config_file(f, File.join(Dotstrap.shell_config_home('fish'),
|
37
|
+
'completions'))
|
38
|
+
end
|
39
|
+
|
40
|
+
write_config_file(fish_configs(repo_dir), config_file('fish'))
|
41
|
+
end
|
42
|
+
|
43
|
+
def unconfigure_fish(repo_dir)
|
44
|
+
fish_functions(repo_dir).each do |f|
|
45
|
+
file = File.join(Dotstrap.shell_config_home('fish'), 'functions',
|
46
|
+
File.basename(f))
|
47
|
+
rm_config_file(file)
|
48
|
+
end
|
49
|
+
|
50
|
+
fish_completions(repo_dir).each do |f|
|
51
|
+
file = File.join(Dotstrap.shell_config_home('fish'), 'completions',
|
52
|
+
File.basename(f))
|
53
|
+
rm_config_file(file)
|
54
|
+
end
|
55
|
+
|
56
|
+
unwrite_config_file(fish_configs(repo_dir), config_file('fish'))
|
57
|
+
end
|
58
|
+
|
59
|
+
def configure_zsh(repo_dir)
|
60
|
+
write_config_file(zsh_configs(repo_dir), config_file('zsh'))
|
61
|
+
end
|
62
|
+
|
63
|
+
def unconfigure_zsh(repo_dir)
|
64
|
+
unwrite_config_file(zsh_configs(repo_dir), config_file('zsh'))
|
65
|
+
end
|
66
|
+
|
67
|
+
def configure_bash(repo_dir)
|
68
|
+
write_config_file(bash_configs(repo_dir), config_file('bash'))
|
69
|
+
end
|
70
|
+
|
71
|
+
def unconfigure_bash(repo_dir)
|
72
|
+
unwrite_config_file(bash_configs(repo_dir), config_file('bash'))
|
73
|
+
end
|
74
|
+
|
75
|
+
def rm_config_file(file)
|
76
|
+
FileUtils.rm_rf file
|
77
|
+
end
|
78
|
+
|
79
|
+
def config_file(sh, dir = Dotstrap.config_home)
|
80
|
+
File.join(dir, "config.#{sh}")
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def write_config_file(repo_config_files, dotstrap_config_file)
|
86
|
+
return if repo_config_files.empty?
|
87
|
+
repo_config_files.each do |file|
|
88
|
+
append_config_file(file, dotstrap_config_file)
|
89
|
+
$LOG.info { "configured: #{file}" }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def unwrite_config_file(repo_config_files, dotstrap_config_file)
|
94
|
+
return if repo_config_files.empty?
|
95
|
+
repo_config_files.each do |file|
|
96
|
+
unappend_config_file(file, dotstrap_config_file)
|
97
|
+
$LOG.info { "removed: #{file}" }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# TODO: only open config file once, write all source strings at once
|
102
|
+
def append_config_file(file_to_source, config_file)
|
103
|
+
source_str = "source \"#{file_to_source}\"\n"
|
104
|
+
if File.exist?(config_file)
|
105
|
+
# Do not write source_str if we have already written it before
|
106
|
+
return if File.readlines(config_file).grep(source_str).any?
|
107
|
+
end
|
108
|
+
File.open(config_file, 'a') { |f| f.write source_str }
|
109
|
+
end
|
110
|
+
|
111
|
+
def unappend_config_file(file_to_unsource, config_file)
|
112
|
+
return unless File.exist?(config_file)
|
113
|
+
Dir.mktmpdir do |tmp_dir|
|
114
|
+
source_str = "source \"#{file_to_unsource}\""
|
115
|
+
tmp_config_file = File.join(tmp_dir, File.basename(config_file))
|
116
|
+
File.open(tmp_config_file, 'w') do |tmp_file|
|
117
|
+
File.foreach(file_to_unsource) do |line|
|
118
|
+
tmp_file.write line unless line.chomp == source_str
|
119
|
+
end
|
120
|
+
end
|
121
|
+
FileUtils.mv(tmp_config_file, config_file)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def link_config_file(src, dest_dir)
|
126
|
+
return unless File.exist?(src)
|
127
|
+
$LOG.debug { "LINK_CONFIG_FILE:#{src} to #{dest_dir}" }
|
128
|
+
dst = File.join(dest_dir, File.basename(src))
|
129
|
+
# FIXME: fails if dest_dir for link is a broken symbolic link
|
130
|
+
# parent = Pathname.new(dest_dir).parent
|
131
|
+
# FileUtils.mkdir parent unless Dir.exist? parent
|
132
|
+
FileUtils.mkdir_p dest_dir unless Dir.exist? dest_dir
|
133
|
+
FileUtils.ln_s src, dst, force: true
|
134
|
+
$LOG.info { "linked: #{src} to #{dst}" }
|
135
|
+
end
|
136
|
+
|
137
|
+
def fish_configs(dir, excl = 'fish_prompt.fish')
|
138
|
+
c = []
|
139
|
+
Dir.glob(File.join(dir, '*.fish')) { |f| c << f unless f.end_with?(excl) }
|
140
|
+
$LOG.debug { "FISH_CONFIGS:#{c}" }
|
141
|
+
c
|
142
|
+
end
|
143
|
+
|
144
|
+
def fish_functions(dir, incl = ['fish_prompt.fish'])
|
145
|
+
funcs = []
|
146
|
+
funcs << Dir.glob(File.join(dir, 'functions', '*.fish'))
|
147
|
+
incl.each do |f|
|
148
|
+
f = File.join(dir, f)
|
149
|
+
funcs << f if File.exist?(f)
|
150
|
+
end
|
151
|
+
$LOG.debug { "FISH_FUNCTIONS:#{funcs.flatten}" }
|
152
|
+
funcs.flatten
|
153
|
+
end
|
154
|
+
|
155
|
+
def fish_completions(dir)
|
156
|
+
c = Dir.glob(File.join(dir, 'completions', '*.fish'))
|
157
|
+
$LOG.debug { "FISH_COMPLETIONS:#{c}" }
|
158
|
+
c
|
159
|
+
end
|
160
|
+
|
161
|
+
def bash_configs(dir)
|
162
|
+
c = Dir.glob(File.join(dir, '**', '*.{sh,bash}'))
|
163
|
+
$LOG.debug { "BASH_CONFIGS:#{c}" }
|
164
|
+
c
|
165
|
+
end
|
166
|
+
|
167
|
+
def zsh_configs(dir)
|
168
|
+
c = Dir.glob(File.join(dir, '**', '*.{sh,zsh}'))
|
169
|
+
$LOG.debug { "ZSH_CONFIGS:#{c}" }
|
170
|
+
c
|
171
|
+
end
|
172
|
+
|
173
|
+
def should_configure_fish?
|
174
|
+
Dir.exist?(Dotstrap.shell_config_home('fish'))
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
data/lib/dotstrap.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'parallel'
|
4
|
+
require 'pathname'
|
5
|
+
require_relative 'dotstrap/git'
|
6
|
+
require_relative 'dotstrap/shell'
|
7
|
+
|
8
|
+
module Dotstrap
|
9
|
+
NAME = 'dotstrap'
|
10
|
+
EXE_NAME = 'ds'
|
11
|
+
VERSION = '0.1.0'
|
12
|
+
AUTHOR = 'William Myers'
|
13
|
+
HOMEPAGE = 'http://github.com/mkwmms/dotstrap'
|
14
|
+
SOURCE_URL = 'http://github.com/mkwmms/dotstrap'
|
15
|
+
DOC_URL = 'http://www.rubydoc.info/github/mkwmms/dotstrap/master/Dotstrap'
|
16
|
+
SUMMARY = 'bootstrap your shell dotfiles in parallel from GitHub repos'
|
17
|
+
DESCRIPTION = 'bootstrap your shell dotfiles in parallel from GitHub repos'
|
18
|
+
# DESCRIPTION = 'downloads repositories from GitHub in parallel and ' \
|
19
|
+
# 'symbolically links and/or creates a file to be sourced ' \
|
20
|
+
# 'according to your shell (fish, zsh, bash)'
|
21
|
+
|
22
|
+
class << self
|
23
|
+
require 'pathname'
|
24
|
+
|
25
|
+
def config_home
|
26
|
+
return ENV['DOTSTRAP_CONFIG_HOME'] if ENV.has_key?('DOTSTRAP_CONFIG_HOME')
|
27
|
+
|
28
|
+
config_dir = ENV.fetch('XDG_CONFIG_HOME', Dir.home)
|
29
|
+
if config_dir == Dir.home
|
30
|
+
File.join(config_dir, '.config', 'dotstrap')
|
31
|
+
else
|
32
|
+
File.join(config_dir, 'dotstrap')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def shell_name
|
37
|
+
# FIXME: bad to rely on SHELL environment variable to determine shell?
|
38
|
+
shell =
|
39
|
+
case ENV['SHELL']
|
40
|
+
when %r{/(ba)?sh} then
|
41
|
+
'bash'
|
42
|
+
when %r{/zsh} then
|
43
|
+
'zsh'
|
44
|
+
when %r{/fish} then
|
45
|
+
'fish'
|
46
|
+
else
|
47
|
+
raise RuntimeError, ENV['SHELL']
|
48
|
+
end
|
49
|
+
$LOG.debug { "SHELL_NAME:#{shell}" }
|
50
|
+
shell
|
51
|
+
end
|
52
|
+
|
53
|
+
def shell_profile(shell = shell_name)
|
54
|
+
profile =
|
55
|
+
case shell
|
56
|
+
when 'bash' then
|
57
|
+
bash_profile = ''
|
58
|
+
['.bash_profile' '.profile'].each do |file|
|
59
|
+
bash_profile = File.join(Dir.home, file)
|
60
|
+
break if File.exist?(bash_profile)
|
61
|
+
end
|
62
|
+
bash_profile
|
63
|
+
when 'zsh' then
|
64
|
+
File.join(Dir.home, '.zshrc')
|
65
|
+
when 'fish' then
|
66
|
+
File.join(Dir.home, '.config', 'fish', 'config.fish')
|
67
|
+
# File.exist?(file) ? file : fail ShellProfileError, "Fish shell config file not found
|
68
|
+
end
|
69
|
+
$LOG.debug { "SHELL_PROFILE:#{profile}" }
|
70
|
+
profile.strip unless profile.nil?
|
71
|
+
end
|
72
|
+
|
73
|
+
def shell_config_home(shell = shell_name)
|
74
|
+
h = Pathname.new(shell_profile(shell)).parent
|
75
|
+
$LOG.debug { "SHELL_CONFIG_HOME:#{h}" }
|
76
|
+
h
|
77
|
+
end
|
78
|
+
|
79
|
+
def config_file(shell = shell_name)
|
80
|
+
File.join(config_home, "config.#{shell}")
|
81
|
+
end
|
82
|
+
|
83
|
+
def installed_repo_paths
|
84
|
+
Dir[File.join(config_home, '**')]
|
85
|
+
end
|
86
|
+
|
87
|
+
def installed_repos
|
88
|
+
repos = []
|
89
|
+
installed_repo_paths.each do |repo_path|
|
90
|
+
# next unless repo_path.include?('-') && File.directory?(repo_path)
|
91
|
+
repo = File.basename(repo_path)
|
92
|
+
repos << repo.sub(/-/,'/')
|
93
|
+
end
|
94
|
+
repos
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class Dotstrap::Configuration
|
99
|
+
require 'fileutils'
|
100
|
+
|
101
|
+
attr_accessor :repos
|
102
|
+
|
103
|
+
def initialize(repos = nil)
|
104
|
+
@repos = repos unless repos.nil?
|
105
|
+
FileUtils.mkdir_p(Dotstrap.config_home)
|
106
|
+
end
|
107
|
+
|
108
|
+
def configure(dest_dir = Dotstrap.config_home, repos = @repos)
|
109
|
+
if Dotstrap.shell_name == 'fish'
|
110
|
+
FileUtils.mkdir_p(File.join(fish_config_home, 'functions'))
|
111
|
+
FileUtils.mkdir_p(File.join(fish_config_home, 'completions'))
|
112
|
+
end
|
113
|
+
|
114
|
+
Parallel.map(repos, in_threads: 16) do |r|
|
115
|
+
bundle = Dotstrap::Git.new(r, dest_dir)
|
116
|
+
path = bundle.clone
|
117
|
+
puts path
|
118
|
+
load_configs([path]) if path
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def remove(repos = @repos)
|
123
|
+
repos.each do |repo|
|
124
|
+
bundle = Dotstrap::Git.new(repo)
|
125
|
+
repo_path = bundle.repo_path
|
126
|
+
shell = Dotstrap::Shell.new(repo_path)
|
127
|
+
shell.unconfigure(repo_path)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# TODO: return a data-structure from `list`, do not print out
|
132
|
+
def list(repos = @repos)
|
133
|
+
repos.each do |repo|
|
134
|
+
bundle = Dotstrap::Git.new(repo)
|
135
|
+
next unless Dir.exist?(bundle.repo_path)
|
136
|
+
puts "#{'=>'.colorize(:blue)} #{repo}"
|
137
|
+
puts bundle.url
|
138
|
+
puts bundle.repo_path
|
139
|
+
# TODO: only output all associated files on --verbose
|
140
|
+
puts "\n"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def load_configs(repo_path)
|
145
|
+
repo_path.each do |r|
|
146
|
+
shell = Dotstrap::Shell.new(r)
|
147
|
+
shell.configure(repo_path)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/spec/bundle_spec.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'dotstrap/bundle'
|
3
|
+
|
4
|
+
describe Dotstrap::Bundle do
|
5
|
+
before :all do
|
6
|
+
@repos = { 'mkwmms/fish-osx' => %w(ql.fish),
|
7
|
+
'mkwmms/fish-basic' =>
|
8
|
+
%w(clear.fish mkcd.fish port_kill.fish port_top.fish td.fish)
|
9
|
+
}
|
10
|
+
@dotstrap_config_home = Dir.mktmpdir('test_dotstrap_config_home_')
|
11
|
+
# @bundle = FactoryGirl.create :bundle(@config_home, @repos)
|
12
|
+
@bundle = Dotstrap::Bundle.new(@dotstrap_config_home, @repos.keys)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#download' do
|
16
|
+
it 'can download real life repos' do
|
17
|
+
@bundle.download(@repos.keys)
|
18
|
+
@repos.each do |repo, expected_files|
|
19
|
+
# TODO: or should I uses checksums or something?
|
20
|
+
actual_files = []
|
21
|
+
Dir.glob(@dotstrap_config_home + repo + '**/*.{fish,sh,zsh}') do |f|
|
22
|
+
actual_files.push File.basename(f)
|
23
|
+
end
|
24
|
+
actual_files.each { |actual| expect(actual).to eql(expected_files) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO: write test for load_configs
|
30
|
+
|
31
|
+
after :all do
|
32
|
+
FileUtils.rm_r @dotstrap_config_home, force: true
|
33
|
+
end
|
34
|
+
end
|
data/spec/shell_spec.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'dotstrap/shell'
|
3
|
+
|
4
|
+
describe Dotstrap::Shell do
|
5
|
+
before :all do
|
6
|
+
# FIXME: decouple test config_files and define in each test
|
7
|
+
@config_files = { 'mkwmms/fish-osx' => %w(ql.fish),
|
8
|
+
# 'mkwmms/fish-basic/functions' =>
|
9
|
+
# %w(clear.fish mkcd.fish port_kill.fish port_top.fish td.fish)
|
10
|
+
}
|
11
|
+
@dotstrap_config_home = Dir.mktmpdir('test_dotstrap_config_home_')
|
12
|
+
@shell_config_home = Dir.mktmpdir('test_dotstrap_shell_config_home_')
|
13
|
+
# @bundle = FactoryGirl.create :bundle(@config_home, @repos)
|
14
|
+
@shell = Dotstrap::Shell.new(@dotstrap_config_home, @config_files.keys)
|
15
|
+
|
16
|
+
@config_files.each do |repo, files|
|
17
|
+
dir = File.join(@dotstrap_config_home, repo, 'functions')
|
18
|
+
FileUtils.mkdir_p dir
|
19
|
+
files.each do |f|
|
20
|
+
File.write(File.join(dir, f), 'TEST CONFIG')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'array test' do
|
26
|
+
# This will fail if we are not using rspec >= 3.0
|
27
|
+
it 'simple match_array' do
|
28
|
+
expect([1, 2, 3]).to match_array [2, 3, 1]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#fish_config_home' do
|
33
|
+
# ENV['XDG_CONFIG_HOME']
|
34
|
+
it 'gets the correct fish_config_home' do
|
35
|
+
expect(@shell.fish_config_home).to eql(File.expand_path('~/.config/fish'))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#fish_functions' do
|
40
|
+
# ENV['XDG_CONFIG_HOME']
|
41
|
+
it 'gets the correct fish function files before linking' do
|
42
|
+
actual_files = []
|
43
|
+
expected_files = []
|
44
|
+
@config_files.each do |repo, files|
|
45
|
+
dir = File.join(@dotstrap_config_home, repo)
|
46
|
+
actual_files.push @shell.fish_functions(dir)
|
47
|
+
files.each do |f|
|
48
|
+
expected_files.push File.join(dir, 'functions', f)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
# FIXME: worry about the fact that I need to call flatten on arrays?
|
52
|
+
expect(actual_files.flatten).to match_array(expected_files.flatten)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# describe '#configure' do
|
57
|
+
# it 'can configure 1 repo' do
|
58
|
+
# actual_files = []
|
59
|
+
# Dir.glob(@shell_config_home + 'functions/*.fish') do |f|
|
60
|
+
# actual_files.push File.basename(f)
|
61
|
+
# end
|
62
|
+
# expect(actual_files).to match_array(@config_files.values)
|
63
|
+
# end
|
64
|
+
# end
|
65
|
+
|
66
|
+
after :all do
|
67
|
+
[@dotstrap_config_home, @shell_config_home].each do |dir|
|
68
|
+
FileUtils.rm_r dir, force: true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
module SimpleCov::Configuration
|
4
|
+
def clean_filters
|
5
|
+
@filters = []
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
SimpleCov.configure do
|
10
|
+
clean_filters
|
11
|
+
load_profile 'test_frameworks'
|
12
|
+
end
|
13
|
+
|
14
|
+
ENV["COVERAGE"] && SimpleCov.start do
|
15
|
+
add_filter "/.rvm/"
|
16
|
+
end
|
17
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
18
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
19
|
+
# Dir["#{File.dirname(__FILE__)}/../lib/**/*.rb"].each {|f| puts f; require f}
|
20
|
+
|
21
|
+
require 'rspec'
|
22
|
+
# require 'factory_girl'
|
23
|
+
|
24
|
+
# Requires supporting files with custom matchers and macros, etc,
|
25
|
+
# in ./support/ and its subdirectories.
|
26
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
27
|
+
|
28
|
+
RSpec.configure do |config|
|
29
|
+
# config.include FactoryGirl::Syntax::Methods
|
30
|
+
# config.before(:suite) do
|
31
|
+
# FactoryGirl.lint
|
32
|
+
# end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dotstrap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- William Myers
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-11-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: parallel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.19'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.19'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: yard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.7'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.7'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rdoc
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.12'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.12'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: bundler
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: jeweler
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.10'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.10'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: factory_girl
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '4.0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '4.0'
|
153
|
+
description: bootstrap your shell dotfiles in parallel from GitHub repos
|
154
|
+
email:
|
155
|
+
executables:
|
156
|
+
- ds
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files:
|
159
|
+
- LICENSE.txt
|
160
|
+
- README.md
|
161
|
+
files:
|
162
|
+
- ".document"
|
163
|
+
- ".rspec"
|
164
|
+
- CONTRIBUTING.md
|
165
|
+
- Gemfile
|
166
|
+
- LICENSE.txt
|
167
|
+
- README.md
|
168
|
+
- Rakefile
|
169
|
+
- bin/ds
|
170
|
+
- dotstrap.gemspec
|
171
|
+
- lib/dotstrap.rb
|
172
|
+
- lib/dotstrap/git.rb
|
173
|
+
- lib/dotstrap/shell.rb
|
174
|
+
- spec/bundle_spec.rb
|
175
|
+
- spec/shell_spec.rb
|
176
|
+
- spec/spec_helper.rb
|
177
|
+
homepage: http://github.com/mkwmms/dotstrap
|
178
|
+
licenses:
|
179
|
+
- MIT
|
180
|
+
metadata:
|
181
|
+
documentation: http://www.rubydoc.info/github/mkwmms/dotstrap/master/Dotstrap
|
182
|
+
source_code: http://github.com/mkwmms/dotstrap
|
183
|
+
post_install_message:
|
184
|
+
rdoc_options: []
|
185
|
+
require_paths:
|
186
|
+
- lib
|
187
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: 1.9.2
|
192
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '0'
|
197
|
+
requirements: []
|
198
|
+
rubyforge_project:
|
199
|
+
rubygems_version: 2.4.5.1
|
200
|
+
signing_key:
|
201
|
+
specification_version: 4
|
202
|
+
summary: bootstrap your shell dotfiles in parallel from GitHub repos
|
203
|
+
test_files: []
|