herdsman 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/README.md +64 -0
- data/bin/herdsman +7 -0
- data/herdsman.gemspec +21 -0
- data/lib/herdsman/cli.rb +60 -0
- data/lib/herdsman/command/status.rb +23 -0
- data/lib/herdsman/config.rb +67 -0
- data/lib/herdsman/environment.rb +10 -0
- data/lib/herdsman/git_repo.rb +101 -0
- data/lib/herdsman/herd.rb +18 -0
- data/lib/herdsman/herd_member.rb +85 -0
- data/lib/herdsman/log_adapter.rb +46 -0
- data/lib/herdsman/version.rb +3 -0
- data/lib/herdsman.rb +9 -0
- metadata +57 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: f18f584c60859f1587dd80aaa46f302cab09efb6
|
|
4
|
+
data.tar.gz: e8a287c600b82bea7fed32924ab6779b3557e77c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 4413b1e186657cd9dbc41be92e6530b509e022fdf1bc1cb604c022a58dcec676acca1f7f67db6ffccf0edfc4f5b43988670d5bfb12787b8cf136b4d5fbf912d2
|
|
7
|
+
data.tar.gz: 80d372ceb0e04bf9baf7775bdf404a6708b7c8ea4bc894ecc0d26e5e4f8ba8b894ea9fa988a9811806441f7e22ec66fce982171031026468ed7d8c69c8661432
|
data/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Herdsman
|
|
2
|
+
|
|
3
|
+
Herdsman is a command line utility for working with multiple Git repositories.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
gem install herdsman
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Commands:
|
|
15
|
+
herdsman help [COMMAND] # Describe available commands or one specific command
|
|
16
|
+
herdsman status # Check the status of the repositories in the herd
|
|
17
|
+
herdsman version # Show the herdsman version
|
|
18
|
+
|
|
19
|
+
Options:
|
|
20
|
+
q, [--quiet], [--no-quiet]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### `herdsman status`
|
|
24
|
+
|
|
25
|
+
`herdsman status` will check each of the repositories in the herd:
|
|
26
|
+
* for untracked files
|
|
27
|
+
* for modified files
|
|
28
|
+
* for unpushed commits
|
|
29
|
+
* for unpulled commits
|
|
30
|
+
* is on the specified revision (defaults to `master`)
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
$ herdsman status
|
|
34
|
+
WARN: foo-repo has untracked files
|
|
35
|
+
WARN: foo-repo has modified files
|
|
36
|
+
INFO: bar-repo is ok
|
|
37
|
+
WARN: baz-repo has unpushed commits
|
|
38
|
+
WARN: baz-repo has unpulled commits
|
|
39
|
+
WARN: baz-repo revision is not 'qux-branch'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Exits `0` if all checks pass. Exits `1` if any of the repositories in the herd fail any of the checks.
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
Configure the herd of repositories to manage with a `herdsman.yml` file in the current working directory.
|
|
47
|
+
|
|
48
|
+
Example:
|
|
49
|
+
|
|
50
|
+
```yml
|
|
51
|
+
repos:
|
|
52
|
+
- /path/to/foo-repo
|
|
53
|
+
- ../../path/to/bar-repo
|
|
54
|
+
- path: /path/to/baz-repo
|
|
55
|
+
revision: qux-branch # defaults to `master` if unset
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
|
|
60
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
61
|
+
|
|
62
|
+
## Credits
|
|
63
|
+
|
|
64
|
+
* [Thoughtbot's gitsh](https://github.com/thoughtbot/gitsh) Git shell, which was referenced for much of the Git CLI integration.
|
data/bin/herdsman
ADDED
data/herdsman.gemspec
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
|
2
|
+
$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
|
|
3
|
+
require 'herdsman/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.authors = ['Tom Marshall']
|
|
7
|
+
spec.description =
|
|
8
|
+
'Herdsman is a CLI utility for working with multiple Git repositories'
|
|
9
|
+
spec.files = %w(herdsman.gemspec) + Dir['*.md',
|
|
10
|
+
'bin/*',
|
|
11
|
+
'lib/**/*.rb']
|
|
12
|
+
spec.email = 'tommarshall7@gmail.com'
|
|
13
|
+
spec.executables = ['herdsman']
|
|
14
|
+
spec.homepage = 'https://github.com/tommarshall/herdsman'
|
|
15
|
+
spec.license = 'MIT'
|
|
16
|
+
spec.name = 'herdsman'
|
|
17
|
+
spec.require_paths = ['lib']
|
|
18
|
+
spec.summary =
|
|
19
|
+
'A CLI utility for working with multiple Git repositories'
|
|
20
|
+
spec.version = Herdsman::VERSION
|
|
21
|
+
end
|
data/lib/herdsman/cli.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
|
|
3
|
+
module Herdsman
|
|
4
|
+
class CLI < Thor
|
|
5
|
+
require 'herdsman'
|
|
6
|
+
|
|
7
|
+
class_option :quiet, type: :boolean, aliases: :q
|
|
8
|
+
|
|
9
|
+
default_task :status
|
|
10
|
+
|
|
11
|
+
desc 'status', 'Check the status of the repositories in the herd'
|
|
12
|
+
def status
|
|
13
|
+
cmd = Herdsman::Command::Status.new(herd: herd, logger: logger)
|
|
14
|
+
result = cmd.run
|
|
15
|
+
exit result
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc 'version', 'Show the herdsman version'
|
|
19
|
+
map %w(-v --version) => :version
|
|
20
|
+
def version
|
|
21
|
+
puts "Herdsman version #{Herdsman::VERSION}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def config
|
|
27
|
+
Herdsman::Config.new(File.expand_path('herdsman.yml', Dir.pwd))
|
|
28
|
+
rescue
|
|
29
|
+
$stderr.puts "ERROR: #{$!.message}"
|
|
30
|
+
exit 1
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def env
|
|
34
|
+
Herdsman::Environment.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def herd
|
|
38
|
+
Herdsman::Herd.new(env, config, herd_members(config.repos))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def logger
|
|
42
|
+
writer = Logger.new(STDOUT)
|
|
43
|
+
writer.formatter = proc do |severity, _, _, msg|
|
|
44
|
+
"#{severity.upcase}: #{msg}\n"
|
|
45
|
+
end
|
|
46
|
+
logger = Herdsman::LogAdapter.new(writer)
|
|
47
|
+
logger.adjust_verbosity(quiet: options[:quiet])
|
|
48
|
+
logger
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def herd_members(repos)
|
|
52
|
+
repos.map do |repo|
|
|
53
|
+
Herdsman::HerdMember.new(
|
|
54
|
+
Herdsman::GitRepo.new(env, repo.path),
|
|
55
|
+
repo.revision,
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Herdsman
|
|
2
|
+
module Command
|
|
3
|
+
class Status
|
|
4
|
+
def initialize(args = {})
|
|
5
|
+
@herd = args[:herd]
|
|
6
|
+
@logger = args[:logger]
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def run
|
|
10
|
+
herd.members.each do |herd_member|
|
|
11
|
+
herd_member.status_report.each do |message|
|
|
12
|
+
logger.send(message.level, message.msg)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
herd.gathered?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
attr_reader :herd, :logger
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
module Herdsman
|
|
4
|
+
class Config
|
|
5
|
+
def initialize(path)
|
|
6
|
+
@config = read_config!(path)
|
|
7
|
+
validate!
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def repos
|
|
11
|
+
config_repos = config['repos'] || []
|
|
12
|
+
config_repos.map do |repo_config|
|
|
13
|
+
RepoConfig.new(repo_config)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
attr_reader :config
|
|
20
|
+
|
|
21
|
+
class RepoConfig
|
|
22
|
+
def initialize(repo_config)
|
|
23
|
+
@repo_config = repo_config
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def path
|
|
27
|
+
if repo_config.is_a?(Hash)
|
|
28
|
+
repo_config['path']
|
|
29
|
+
else
|
|
30
|
+
repo_config
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def revision
|
|
35
|
+
if repo_config.is_a?(Hash) && repo_config.include?('revision')
|
|
36
|
+
repo_config['revision']
|
|
37
|
+
else
|
|
38
|
+
default_revision
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
attr_reader :repo_config
|
|
45
|
+
|
|
46
|
+
def default_revision
|
|
47
|
+
'master'
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def read_config!(path)
|
|
52
|
+
YAML.load_file(path)
|
|
53
|
+
rescue
|
|
54
|
+
raise 'No config found'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def validate!
|
|
58
|
+
raise 'Invalid config' unless config.is_a?(Hash) && repos.is_a?(Array)
|
|
59
|
+
raise 'No repos defined' if repos.empty?
|
|
60
|
+
repos.each do |repo|
|
|
61
|
+
unless File.directory?(repo.path)
|
|
62
|
+
raise "#{repo.path} is not a directory"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require 'open3'
|
|
2
|
+
|
|
3
|
+
module Herdsman
|
|
4
|
+
class GitRepo
|
|
5
|
+
attr_reader :path
|
|
6
|
+
def initialize(env, path)
|
|
7
|
+
@env = env
|
|
8
|
+
@path = path
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def initialized?
|
|
12
|
+
!git_dir.empty? && File.exist?(path + '/' + git_dir)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def git_dir
|
|
16
|
+
git_output('rev-parse --git-dir')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def current_head
|
|
20
|
+
current_branch_name || current_tag_name || abbreviated_commit_ref
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def has_untracked_files?
|
|
24
|
+
status.untracked_files.any?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def has_modified_files?
|
|
28
|
+
status.modified_files.any?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def has_unpushed_commits?
|
|
32
|
+
git_output('log --oneline @{u}..').lines.any?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def has_unpulled_commits?
|
|
36
|
+
fetch
|
|
37
|
+
git_output('log --oneline ..@{u}').lines.any?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def revision?(revision)
|
|
41
|
+
[current_branch_name, current_tag_name, abbreviated_commit_ref].include?(
|
|
42
|
+
revision,
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
attr_reader :env
|
|
49
|
+
|
|
50
|
+
def current_branch_name
|
|
51
|
+
branch_name = git_output('symbolic-ref HEAD --short')
|
|
52
|
+
branch_name unless branch_name.empty?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def current_tag_name
|
|
56
|
+
tag_name = git_output('describe --exact-match --tags HEAD')
|
|
57
|
+
tag_name unless tag_name.empty?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def abbreviated_commit_ref
|
|
61
|
+
commit_ref = git_output('rev-parse HEAD')
|
|
62
|
+
commit_ref[0, 7].to_s unless commit_ref.empty?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def status
|
|
66
|
+
StatusParser.new(git_output('status --porcelain'))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def fetch
|
|
70
|
+
git_output('fetch --all')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def git_output(command)
|
|
74
|
+
Dir.chdir(File.expand_path(path, Dir.pwd)) do
|
|
75
|
+
Open3.capture3(git_command(command)).first.chomp
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def git_command(sub_command)
|
|
80
|
+
"#{env.git_command} #{sub_command}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class StatusParser
|
|
84
|
+
def initialize(status_porcelain)
|
|
85
|
+
@status_porcelain = status_porcelain
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def untracked_files
|
|
89
|
+
status_porcelain.lines.select { |l| l.start_with?('??') }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def modified_files
|
|
93
|
+
status_porcelain.lines.select { |l| l =~ /^ ?[A-Z]/ }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
attr_reader :status_porcelain
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Herdsman
|
|
2
|
+
class Herd
|
|
3
|
+
attr_reader :members
|
|
4
|
+
def initialize(env, config, members)
|
|
5
|
+
@env = env
|
|
6
|
+
@config = config
|
|
7
|
+
@members = members
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def gathered?
|
|
11
|
+
members.all?(&:gathered?)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
attr_reader :env
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Herdsman
|
|
2
|
+
class HerdMember
|
|
3
|
+
attr_reader :name
|
|
4
|
+
def initialize(repo, revision, args = {})
|
|
5
|
+
@repo = repo
|
|
6
|
+
@revision = revision
|
|
7
|
+
@name = args[:name] || default_name
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def gathered?
|
|
11
|
+
[repo_initialized?,
|
|
12
|
+
repo_has_zero_unpushed_commits?,
|
|
13
|
+
repo_has_zero_unpulled_commits?,
|
|
14
|
+
repo_has_zero_untracked_files?,
|
|
15
|
+
repo_has_zero_modified_files?,
|
|
16
|
+
repo_on_specified_revision?].all?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def status_report
|
|
20
|
+
clear_messages
|
|
21
|
+
messages << Message.new(:info, "#{name} is ok") if gathered?
|
|
22
|
+
messages
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
attr_reader :repo, :revision
|
|
28
|
+
|
|
29
|
+
def default_name
|
|
30
|
+
File.basename(repo.path)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Message = Struct.new(:level, :msg)
|
|
34
|
+
|
|
35
|
+
def messages
|
|
36
|
+
@messages ||= []
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def clear_messages
|
|
40
|
+
@messages = []
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def repo_initialized?
|
|
44
|
+
unless repo.initialized?
|
|
45
|
+
messages << Message.new(:warn, "#{repo.path} is not a git repo")
|
|
46
|
+
end
|
|
47
|
+
repo.initialized?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def repo_has_zero_unpushed_commits?
|
|
51
|
+
if repo.has_unpushed_commits?
|
|
52
|
+
messages << Message.new(:warn, "#{name} has unpushed commits")
|
|
53
|
+
end
|
|
54
|
+
!repo.has_unpushed_commits?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def repo_has_zero_unpulled_commits?
|
|
58
|
+
if repo.has_unpulled_commits?
|
|
59
|
+
messages << Message.new(:warn, "#{name} has unpulled commits")
|
|
60
|
+
end
|
|
61
|
+
!repo.has_unpulled_commits?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def repo_has_zero_untracked_files?
|
|
65
|
+
if repo.has_untracked_files?
|
|
66
|
+
messages << Message.new(:warn, "#{name} has untracked files")
|
|
67
|
+
end
|
|
68
|
+
!repo.has_untracked_files?
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def repo_has_zero_modified_files?
|
|
72
|
+
if repo.has_modified_files?
|
|
73
|
+
messages << Message.new(:warn, "#{name} has modified files")
|
|
74
|
+
end
|
|
75
|
+
!repo.has_modified_files?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def repo_on_specified_revision?
|
|
79
|
+
if repo.initialized? && !repo.revision?(revision)
|
|
80
|
+
messages << Message.new(:warn, "#{name} revision is not '#{revision}'")
|
|
81
|
+
end
|
|
82
|
+
!repo.initialized? || repo.revision?(revision)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Herdsman
|
|
2
|
+
class LogAdapter
|
|
3
|
+
attr_accessor :writer
|
|
4
|
+
|
|
5
|
+
LOG_LEVELS = {
|
|
6
|
+
debug: ::Logger::DEBUG,
|
|
7
|
+
info: ::Logger::INFO,
|
|
8
|
+
warn: ::Logger::WARN,
|
|
9
|
+
error: ::Logger::ERROR,
|
|
10
|
+
}.freeze
|
|
11
|
+
|
|
12
|
+
def log_level
|
|
13
|
+
writer.level
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def log_level=(level)
|
|
17
|
+
writer.level = LOG_LEVELS.fetch(level)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def adjust_verbosity(options = {})
|
|
21
|
+
if options[:quiet]
|
|
22
|
+
self.log_level = :error
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(writer)
|
|
27
|
+
@writer = writer
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def debug(message)
|
|
31
|
+
writer.debug(message)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def info(message)
|
|
35
|
+
writer.info(message)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def warn(message)
|
|
39
|
+
writer.warn(message)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def error(message)
|
|
43
|
+
writer.error(message)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/herdsman.rb
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
require 'herdsman/command/status'
|
|
3
|
+
require 'herdsman/config'
|
|
4
|
+
require 'herdsman/environment'
|
|
5
|
+
require 'herdsman/git_repo'
|
|
6
|
+
require 'herdsman/herd'
|
|
7
|
+
require 'herdsman/herd_member'
|
|
8
|
+
require 'herdsman/log_adapter'
|
|
9
|
+
require 'herdsman/version'
|
metadata
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: herdsman
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Tom Marshall
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2017-02-20 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Herdsman is a CLI utility for working with multiple Git repositories
|
|
14
|
+
email: tommarshall7@gmail.com
|
|
15
|
+
executables:
|
|
16
|
+
- herdsman
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- README.md
|
|
21
|
+
- bin/herdsman
|
|
22
|
+
- herdsman.gemspec
|
|
23
|
+
- lib/herdsman.rb
|
|
24
|
+
- lib/herdsman/cli.rb
|
|
25
|
+
- lib/herdsman/command/status.rb
|
|
26
|
+
- lib/herdsman/config.rb
|
|
27
|
+
- lib/herdsman/environment.rb
|
|
28
|
+
- lib/herdsman/git_repo.rb
|
|
29
|
+
- lib/herdsman/herd.rb
|
|
30
|
+
- lib/herdsman/herd_member.rb
|
|
31
|
+
- lib/herdsman/log_adapter.rb
|
|
32
|
+
- lib/herdsman/version.rb
|
|
33
|
+
homepage: https://github.com/tommarshall/herdsman
|
|
34
|
+
licenses:
|
|
35
|
+
- MIT
|
|
36
|
+
metadata: {}
|
|
37
|
+
post_install_message:
|
|
38
|
+
rdoc_options: []
|
|
39
|
+
require_paths:
|
|
40
|
+
- lib
|
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
47
|
+
requirements:
|
|
48
|
+
- - ">="
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: '0'
|
|
51
|
+
requirements: []
|
|
52
|
+
rubyforge_project:
|
|
53
|
+
rubygems_version: 2.4.5.1
|
|
54
|
+
signing_key:
|
|
55
|
+
specification_version: 4
|
|
56
|
+
summary: A CLI utility for working with multiple Git repositories
|
|
57
|
+
test_files: []
|