invoca_gems 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.ruby_version +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +43 -0
- data/README.md +81 -0
- data/Rakefile +17 -0
- data/exe/invoca_gem +3 -0
- data/invoca_gems.gemspec +26 -0
- data/lib/invoca_gems.rb +18 -0
- data/lib/invoca_gems/bundler.rb +88 -0
- data/lib/invoca_gems/cli.rb +102 -0
- data/lib/invoca_gems/gem.rb +225 -0
- data/lib/invoca_gems/gemfile.rb +34 -0
- data/lib/invoca_gems/gemfile_line.rb +47 -0
- data/lib/invoca_gems/gemspec.rb +22 -0
- data/lib/invoca_gems/gemspec_line.rb +19 -0
- data/lib/invoca_gems/git_repo.rb +80 -0
- data/lib/invoca_gems/presenter.rb +118 -0
- data/lib/invoca_gems/shell_command.rb +22 -0
- data/lib/invoca_gems/version.rb +3 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6a2b87073e43fb10edbab421db7aa4c230ce7dda
|
4
|
+
data.tar.gz: bdc0d31c950d2b5eabe2cc4c591dc740160ff688
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dbf0d9e1a6301fa42bb871355e582226fecc8b6c9321028390ab714ae5e5f986acd2a1edf486075b166c1efc95c5d47bf2665f1f50eac67f15cda8c4bc104d75
|
7
|
+
data.tar.gz: 940827af82abd909c66ebf1949e788567c946be8b24e2fb8c6366aa366d3c81df6b70bab3f21596c1a2479cff7e463d09acda431ab863876fbde1dfe9bdfb603
|
data/.gitignore
ADDED
data/.ruby_version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.2
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in invoca_gems.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
# These are used for testing.
|
7
|
+
gem 'invoca-utils', '0.0.2', git: 'git@github.com:Invoca/invoca-utils', ref: 'c508647bc8adcba14e9cb86e03a6721af83d0195'
|
8
|
+
|
9
|
+
gem 'test_source_gem', path: 'test/fixtures/test_source_gem'
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git@github.com:Invoca/invoca-utils
|
3
|
+
revision: c508647bc8adcba14e9cb86e03a6721af83d0195
|
4
|
+
ref: c508647bc8adcba14e9cb86e03a6721af83d0195
|
5
|
+
specs:
|
6
|
+
invoca-utils (0.0.2)
|
7
|
+
|
8
|
+
PATH
|
9
|
+
remote: .
|
10
|
+
specs:
|
11
|
+
invoca_gems (0.1.0)
|
12
|
+
|
13
|
+
PATH
|
14
|
+
remote: test/fixtures/test_source_gem
|
15
|
+
specs:
|
16
|
+
test_source_gem (0.1.0)
|
17
|
+
|
18
|
+
GEM
|
19
|
+
remote: https://rubygems.org/
|
20
|
+
specs:
|
21
|
+
coderay (1.1.1)
|
22
|
+
method_source (0.8.2)
|
23
|
+
minitest (5.8.4)
|
24
|
+
pry (0.10.3)
|
25
|
+
coderay (~> 1.1.0)
|
26
|
+
method_source (~> 0.8.1)
|
27
|
+
slop (~> 3.4)
|
28
|
+
rake (10.5.0)
|
29
|
+
slop (3.6.0)
|
30
|
+
thor (0.19.1)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
bundler (~> 1.8)
|
37
|
+
invoca-utils (= 0.0.2)!
|
38
|
+
invoca_gems!
|
39
|
+
minitest
|
40
|
+
pry
|
41
|
+
rake (~> 10.0)
|
42
|
+
test_source_gem!
|
43
|
+
thor
|
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# InvocaGems
|
2
|
+
|
3
|
+
Makes working on the Invoca gems used by applications easier.
|
4
|
+
|
5
|
+
## Lighting Talk Intro
|
6
|
+
Watch it here and count how many times I say "uuum"! (Answer: lots)
|
7
|
+
|
8
|
+
[Invoca Gem Lightning Talk](https://drive.google.com/a/invoca.com/file/d/0BzmD8uReM33rRi0ydTBiQlRmMzA/view)
|
9
|
+
|
10
|
+
## Workflow
|
11
|
+
The normal workflow would go something like this....
|
12
|
+
|
13
|
+
### 1) Create a branch on the app-repo
|
14
|
+
Start in the repo for the application that needs the changes. (For example web or pnapi). Create a branch for your story changes.
|
15
|
+
|
16
|
+
### 2) Open the gem for editing
|
17
|
+
I am using invoca-metrics in this example.
|
18
|
+
|
19
|
+
```
|
20
|
+
bundle exec invoca_gem edit invoca-metrics
|
21
|
+
```
|
22
|
+
This will do the following:
|
23
|
+
* check out the invoca-metrics repo into invoca_gems/invoca_metrics.
|
24
|
+
* create a new branch on that repo starting at the sha from the app-repo Gemfile. The branch will use the same name as the app-repo.
|
25
|
+
* update the app-repo Gemfile to refer to the invoca metrics gem using a path.
|
26
|
+
|
27
|
+
### 3) Make your gem changes
|
28
|
+
At this point you can edit the invoca-metrics gem from the invoca_gems/invoca_metrics directory. You can confirm your changes work on the app-repo by running tests there.
|
29
|
+
|
30
|
+
### 4) Save your gem changes
|
31
|
+
When ready, save your changes to the invoca_metrics gem.
|
32
|
+
|
33
|
+
```
|
34
|
+
bundle exec invoca_gem save invoca-metrics --commit-message 'made some changes'
|
35
|
+
```
|
36
|
+
This can take a little while, so brace for it. This will do the following:
|
37
|
+
* Commit your changes to the invoca_metrics gem and push them to github.
|
38
|
+
* Update the app-repo Gemfile for the new version and sha of the invoca_metrics gem.
|
39
|
+
* Update any other invoca gems that depend invoca_metrics. For each of these gems it will:
|
40
|
+
* Pull down the gem and create a branch at the sha from the app-repo.
|
41
|
+
* Update the gem version of invoca_metrics in the gemspec.
|
42
|
+
* Update the sha in the Gemfile for the dependent gem.
|
43
|
+
* Bundle install to pick up the changes. (Takes a while.)
|
44
|
+
* Commit the changes and push to github.
|
45
|
+
* Update the app-repo gem to refer to the new sha.
|
46
|
+
* Bundle install the app-repo to pick up all the changes.
|
47
|
+
|
48
|
+
Whew.
|
49
|
+
|
50
|
+
### 5) Create pull requests
|
51
|
+
When ready you can view the changes and issue pull requests from github using the following command.
|
52
|
+
|
53
|
+
```
|
54
|
+
bundle exec invoca_gem show_changes
|
55
|
+
```
|
56
|
+
|
57
|
+
This will open a browser window showing all of the changed gems. From there you can open pull requests and confirm build results.
|
58
|
+
|
59
|
+
|
60
|
+
## Other commands
|
61
|
+
|
62
|
+
Run the following to find available commands.
|
63
|
+
```
|
64
|
+
bundle exec invoca_gem
|
65
|
+
```
|
66
|
+
|
67
|
+
## Installation
|
68
|
+
|
69
|
+
Add this line to your application's Gemfile as a development dependency:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
group :development do
|
73
|
+
gem 'invoca_gems'
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
And then execute:
|
78
|
+
|
79
|
+
$ bundle
|
80
|
+
|
81
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
namespace :test do
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.name = :unit
|
8
|
+
t.libs.push "lib"
|
9
|
+
t.test_files = FileList['test/unit/*_test.rb','test/unit/*/*_test.rb']
|
10
|
+
t.verbose = true
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => 'test:unit'
|
16
|
+
|
17
|
+
|
data/exe/invoca_gem
ADDED
data/invoca_gems.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'invoca_gems/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "invoca_gems"
|
8
|
+
spec.version = InvocaGems::VERSION
|
9
|
+
spec.authors = ["Bob Smith"]
|
10
|
+
spec.email = ["bob@ringrevenue.com"]
|
11
|
+
|
12
|
+
spec.summary = "help manage invoca_gems"
|
13
|
+
spec.description = "manage invoca gems as if they were in-app gems"
|
14
|
+
spec.homepage = "http://www.invoca.com"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.8"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "minitest"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
spec.add_development_dependency "thor"
|
26
|
+
end
|
data/lib/invoca_gems.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "pry"
|
2
|
+
require "invoca_gems/version"
|
3
|
+
require "invoca_gems/presenter"
|
4
|
+
require "invoca_gems/shell_command"
|
5
|
+
require "invoca_gems/bundler"
|
6
|
+
require "invoca_gems/gem"
|
7
|
+
require "invoca_gems/git_repo"
|
8
|
+
require "invoca_gems/gemfile_line"
|
9
|
+
require "invoca_gems/gemfile"
|
10
|
+
require "invoca_gems/gemspec_line"
|
11
|
+
require "invoca_gems/gemspec"
|
12
|
+
|
13
|
+
require "invoca_gems/cli"
|
14
|
+
|
15
|
+
module InvocaGems
|
16
|
+
end
|
17
|
+
|
18
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class InvocaGems::Bundler
|
2
|
+
|
3
|
+
GitSource = Struct.new(:name, :uri, :ref, :version)
|
4
|
+
def find_git_source(gem_name)
|
5
|
+
if source = definition.send(:sources).git_sources.find { |gs| source_name(gs) == gem_name }
|
6
|
+
GitSource.new(source_name(source), source.uri, source.ref, source.version)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
PathSource = Struct.new(:name, :path, :version)
|
11
|
+
def find_path_source(gem_name)
|
12
|
+
if (spec = find_spec(gem_name)) && spec.source.respond_to?(:path)
|
13
|
+
PathSource.new(spec.name, spec.source.path, spec.version.to_s)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def dependants(gem_name)
|
18
|
+
dependant_hash[gem_name]
|
19
|
+
end
|
20
|
+
|
21
|
+
def dependencies_yuml_url
|
22
|
+
"http://yuml.me/diagram/class/#{URI::encode(invoca_dependencies.join(','))}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def invoca_source_names
|
26
|
+
@invoca_source_names ||= definition.send(:sources).all_sources.map do |source|
|
27
|
+
if is_invoca_github_source?(source) || is_edited_source?(source)
|
28
|
+
source_name(source)
|
29
|
+
end
|
30
|
+
end.compact
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def source_name(source)
|
37
|
+
# bundler replaces the name on the source with the github name, but the
|
38
|
+
# @name variable is still set with no other way to get to it.
|
39
|
+
source.instance_eval("@name") || source.name
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def is_invoca_github_source?(source)
|
44
|
+
source.respond_to?(:uri) && source.uri =~ /Invoca/
|
45
|
+
end
|
46
|
+
|
47
|
+
def is_edited_source?(source)
|
48
|
+
source.respond_to?(:path) && source.path.to_s =~ /\Ainvoca_gems\//
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_spec(gem_name)
|
52
|
+
definition.specs.select{ |s| s.name == gem_name }.first
|
53
|
+
end
|
54
|
+
|
55
|
+
def definition
|
56
|
+
@definition ||= Bundler.definition
|
57
|
+
end
|
58
|
+
|
59
|
+
def dependant_hash
|
60
|
+
unless @dependants
|
61
|
+
@dependants = {}
|
62
|
+
definition.specs.each do |spec|
|
63
|
+
spec.dependencies.each do |dependancy|
|
64
|
+
@dependants[dependancy.name] ||= []
|
65
|
+
@dependants[dependancy.name] << spec.name
|
66
|
+
end
|
67
|
+
end
|
68
|
+
@dependants
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def invoca_dependencies
|
74
|
+
edges = []
|
75
|
+
definition.specs.each do |spec|
|
76
|
+
if invoca_source_names.include?(spec.name)
|
77
|
+
edges << "[#{spec.name}|#{spec.version}]"
|
78
|
+
spec.dependencies.each do |dep|
|
79
|
+
if invoca_source_names.include?(dep.name)
|
80
|
+
edges << "[#{spec.name}]->[#{dep.name}]"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
edges.uniq
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "open-uri"
|
3
|
+
require 'bundler'
|
4
|
+
|
5
|
+
class InvocaGems::Cli < Thor
|
6
|
+
|
7
|
+
desc "graph", "show graph of gem dependencies"
|
8
|
+
def graph
|
9
|
+
InvocaGems::Presenter.with_presenter do |presenter|
|
10
|
+
presenter.message "Generating Dependency Graph"
|
11
|
+
bw = InvocaGems::Bundler.new
|
12
|
+
`open #{bw.dependencies_yuml_url}`
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "edit GEM", "configure a gem for local editing"
|
17
|
+
def edit(gem_name)
|
18
|
+
InvocaGems::Presenter.with_presenter do |presenter|
|
19
|
+
presenter.set_task "Configuring #{gem_name}"
|
20
|
+
gem = InvocaGems::Gem.new(gem_name, presenter)
|
21
|
+
gem.edit
|
22
|
+
presenter.set_subtask("done")
|
23
|
+
presenter.message("#{gem_name} is now available at #{gem.repo_directory}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "save GEM", "save gem changes"
|
28
|
+
option :commit_message
|
29
|
+
def save(gem_name)
|
30
|
+
InvocaGems::Presenter.with_presenter do |presenter|
|
31
|
+
presenter.set_task "Saving changes to #{gem_name}"
|
32
|
+
gem = InvocaGems::Gem.new(gem_name, presenter)
|
33
|
+
gem.save(options[:commit_message])
|
34
|
+
presenter.message "Done"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "update GEM VERSION SHA", "updates a gem"
|
39
|
+
def update(gem_name, version, sha)
|
40
|
+
InvocaGems::Presenter.with_presenter do |presenter|
|
41
|
+
gem = InvocaGems::Gem.new(gem_name, presenter)
|
42
|
+
gem.update_version(version, sha)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "has_unsaved_changes GEM", "reports if the gem has changes"
|
47
|
+
def has_unsaved_changes(gem_name)
|
48
|
+
InvocaGems::Presenter.with_presenter do |presenter|
|
49
|
+
gem = InvocaGems::Gem.new(gem_name, presenter)
|
50
|
+
if gem.git_repo.unsaved_changes?
|
51
|
+
presenter.message "found unsaved changes"
|
52
|
+
else
|
53
|
+
presenter.message "no unsaved changes"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "show_changes", "show committed and pushed changes for the gem"
|
59
|
+
def show_changes
|
60
|
+
InvocaGems::Presenter.with_presenter do |presenter|
|
61
|
+
bw = InvocaGems::Bundler.new
|
62
|
+
bw.invoca_source_names.each do |gem_name|
|
63
|
+
presenter.set_task("#{gem_name}")
|
64
|
+
gem = InvocaGems::Gem.new(gem_name, presenter)
|
65
|
+
if gem.repo_exists? && gem.git_repo.branch_exists?(gem.local_branch_name)
|
66
|
+
# TODO - check for differences with master
|
67
|
+
url = gem.uri.gsub("git@github.com:", "https://github.com/").gsub(".git","") + "/compare/#{gem.local_branch_name}"
|
68
|
+
`open #{url}`
|
69
|
+
presenter.set_subtask(url)
|
70
|
+
else
|
71
|
+
presenter.clear_task(keep: false)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
presenter.message("done")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
desc "list", "display the available invoca gems"
|
80
|
+
def list
|
81
|
+
InvocaGems::Presenter.with_presenter do |presenter|
|
82
|
+
presenter.silence do
|
83
|
+
format = " %-30s %10s %-60s"
|
84
|
+
bw = InvocaGems::Bundler.new
|
85
|
+
puts
|
86
|
+
puts format % ["Name", "Version", "Status"]
|
87
|
+
puts format % ["="*30, "="*10, "="*60]
|
88
|
+
bw.invoca_source_names.each do |gem_name|
|
89
|
+
gem = InvocaGems::Gem.new(gem_name, presenter)
|
90
|
+
status =
|
91
|
+
if gem.path
|
92
|
+
presenter.using_mode( :green, "open for editing at #{gem.path}" )
|
93
|
+
else
|
94
|
+
"#{gem.sha[0..6]} for #{gem.uri}"
|
95
|
+
end
|
96
|
+
puts format % [gem.name, gem.version, status]
|
97
|
+
end
|
98
|
+
puts
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
class InvocaGems::Gem
|
2
|
+
WORKING_DIRECTORY = "invoca_gems"
|
3
|
+
|
4
|
+
include InvocaGems::ShellCommand
|
5
|
+
|
6
|
+
attr_reader :name, :uri, :sha, :version, :used_by, :dependants, :path, :branch, :presenter
|
7
|
+
|
8
|
+
def initialize(gem_name, presenter, defer_bundle: false)
|
9
|
+
@presenter = presenter
|
10
|
+
bundle_wrapper = InvocaGems::Bundler.new
|
11
|
+
try_load_from_git_source(bundle_wrapper, gem_name)
|
12
|
+
try_load_from_path_source(bundle_wrapper, gem_name)
|
13
|
+
@name or presenter.stop_with_message("Could not find gem #{gem_name}")
|
14
|
+
@dependants = bundle_wrapper.dependants(gem_name)
|
15
|
+
@defer_bundle = defer_bundle
|
16
|
+
end
|
17
|
+
|
18
|
+
def edit
|
19
|
+
configure_branch
|
20
|
+
update_gemfile_for_source
|
21
|
+
bundle_install_application
|
22
|
+
end
|
23
|
+
|
24
|
+
def save(commit_message=nil)
|
25
|
+
if git_repo.unsaved_changes?
|
26
|
+
if commit_message
|
27
|
+
commit_changes(commit_message)
|
28
|
+
else
|
29
|
+
presenter.stop_with_message "unsaved changes found in #{repo_directory}"
|
30
|
+
end
|
31
|
+
else
|
32
|
+
git_repo.push
|
33
|
+
end
|
34
|
+
|
35
|
+
update_gemfile_for_github(gemfile_path: "Gemfile",
|
36
|
+
gem_name: name,
|
37
|
+
gem_uri: uri,
|
38
|
+
new_version: version,
|
39
|
+
new_sha: git_repo.sha)
|
40
|
+
|
41
|
+
presenter.set_subtask("now at #{version} #{git_repo.sha[0..6]}")
|
42
|
+
update_dependencies(name, version, git_repo.sha)
|
43
|
+
bundle_install_application
|
44
|
+
end
|
45
|
+
|
46
|
+
def update_version(new_version, new_sha)
|
47
|
+
presenter.set_subtask "updating #{name} to #{new_version} #{new_sha}"
|
48
|
+
update_gemfile_for_github(
|
49
|
+
gemfile_path: "Gemfile",
|
50
|
+
gem_name: name,
|
51
|
+
gem_uri: uri,
|
52
|
+
new_version: new_version,
|
53
|
+
new_sha: new_sha)
|
54
|
+
update_dependencies(name, new_version, new_sha)
|
55
|
+
bundle_install_application
|
56
|
+
end
|
57
|
+
|
58
|
+
def update_dependencies(gem_to_update, version, sha)
|
59
|
+
if dependants
|
60
|
+
dependants.uniq.each do |dependant|
|
61
|
+
presenter.set_task "Updating #{dependant} for #{gem_to_update}"
|
62
|
+
gem = self.class.new(dependant, presenter, defer_bundle: true)
|
63
|
+
gem.edit
|
64
|
+
|
65
|
+
# Dependant gem update
|
66
|
+
gem.update_gemfile_for_github(
|
67
|
+
gemfile_path: gem.repo_directory + '/Gemfile',
|
68
|
+
gem_name: name,
|
69
|
+
gem_uri: uri,
|
70
|
+
new_version: version,
|
71
|
+
new_sha: sha)
|
72
|
+
|
73
|
+
# Project gem update
|
74
|
+
gem.update_gemfile_for_github(
|
75
|
+
gemfile_path: gem.repo_directory + '/Gemfile',
|
76
|
+
gem_name: name,
|
77
|
+
gem_uri: uri,
|
78
|
+
new_version: version,
|
79
|
+
new_sha: sha)
|
80
|
+
|
81
|
+
gem.update_gem_gemspec(gem.repo_directory + "/#{gem.name}.gemspec", gem_to_update, version)
|
82
|
+
gem.bundle_install_gem
|
83
|
+
gem.commit_changes("Update #{gem_to_update} to #{version} (#{sha[0..6]})")
|
84
|
+
gem.save # Will nest dependency upudate
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def update_gem_gemspec(gemspec_path, gem_name, version)
|
90
|
+
presenter.set_subtask "updating #{gemspec_path} for #{gem_name}"
|
91
|
+
gemspec = InvocaGems::Gemspec.new(gemspec_path)
|
92
|
+
gemspec_gem = gemspec.find(gem_name)
|
93
|
+
gemspec_gem.update_version(version)
|
94
|
+
gemspec_gem.save!
|
95
|
+
end
|
96
|
+
|
97
|
+
def commit_changes(message)
|
98
|
+
git_repo.commit("#{local_branch_name} #{message}")
|
99
|
+
git_repo.push
|
100
|
+
end
|
101
|
+
|
102
|
+
def update_gemfile_for_github(gemfile_path:, gem_name:, gem_uri:, new_version:, new_sha:)
|
103
|
+
presenter.set_subtask "updating #{gemfile_path} for #{gem_name}"
|
104
|
+
gemfile = InvocaGems::Gemfile.new(gemfile_path)
|
105
|
+
gemfile_gem = gemfile.find(gem_name, allow_missing: true) || gemfile.append(gem_name)
|
106
|
+
gemfile_gem.update_as_github(new_version, gem_uri, new_sha)
|
107
|
+
gemfile_gem.save!
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
def repo_directory
|
112
|
+
WORKING_DIRECTORY + '/' + name
|
113
|
+
end
|
114
|
+
|
115
|
+
def repo_exists?
|
116
|
+
File.directory?(repo_directory)
|
117
|
+
end
|
118
|
+
|
119
|
+
def git_repo
|
120
|
+
create_working_directory
|
121
|
+
unless @git_repo
|
122
|
+
unless repo_exists?
|
123
|
+
presenter.set_subtask "creating #{repo_directory} from #{uri}"
|
124
|
+
InvocaGems::GitRepo.clone(WORKING_DIRECTORY, uri, name, presenter: presenter)
|
125
|
+
end
|
126
|
+
@git_repo = repo_for_path(repo_directory)
|
127
|
+
@git_repo.fetch
|
128
|
+
end
|
129
|
+
@git_repo
|
130
|
+
end
|
131
|
+
|
132
|
+
def repo_for_path(path)
|
133
|
+
InvocaGems::GitRepo.new(presenter, path)
|
134
|
+
end
|
135
|
+
|
136
|
+
def configure_branch
|
137
|
+
git_repo.unsaved_changes? and presenter.stop_with_message "Unsaved changes found in #{repo_directory}"
|
138
|
+
if !git_repo.branch_exists?(local_branch_name)
|
139
|
+
presenter.set_subtask "Creating branch #{local_branch_name}"
|
140
|
+
git_repo.create_branch_at(local_branch_name, sha)
|
141
|
+
end
|
142
|
+
presenter.set_subtask "Using branch #{local_branch_name}"
|
143
|
+
git_repo.checkout_branch(local_branch_name)
|
144
|
+
|
145
|
+
if git_repo.sha != sha
|
146
|
+
presenter.stop_with_message "Commited work not found in gem, use -- mumble mumble to fix."
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def update_gemfile_for_source
|
151
|
+
gemfile = InvocaGems::Gemfile.new('Gemfile')
|
152
|
+
gemfile_gem = gemfile.find(name)
|
153
|
+
gemfile_gem.update_as_path(repo_directory)
|
154
|
+
gemfile_gem.save!
|
155
|
+
end
|
156
|
+
|
157
|
+
def local_branch_name
|
158
|
+
@local_branch_name ||= repo_for_path('.').branch
|
159
|
+
end
|
160
|
+
|
161
|
+
def try_load_from_git_source(bundle_wrapper, gem_name)
|
162
|
+
if result = bundle_wrapper.find_git_source(gem_name)
|
163
|
+
@name = result.name
|
164
|
+
@uri = result.uri
|
165
|
+
@version = result.version
|
166
|
+
@sha = result.ref
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def try_load_from_path_source(bundle_wrapper, gem_name)
|
171
|
+
if !@name && result = bundle_wrapper.find_path_source(gem_name)
|
172
|
+
@name = result.name
|
173
|
+
@path = result.path
|
174
|
+
@version = result.version
|
175
|
+
get_git_statistics_from_path(path)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def get_git_statistics_from_path(path)
|
180
|
+
repo = repo_for_path(path)
|
181
|
+
@uri = repo.uri
|
182
|
+
@sha = repo.sha
|
183
|
+
@branch = repo.branch
|
184
|
+
end
|
185
|
+
|
186
|
+
def configure_appilication
|
187
|
+
unless @application_configured
|
188
|
+
create_working_directory
|
189
|
+
@application_configured = true
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def create_working_directory
|
194
|
+
if File.read(".gitignore") !~ /#{WORKING_DIRECTORY}/m
|
195
|
+
presenter.set_subtask "updating .gitignore"
|
196
|
+
File.open(".gitignore","a") { |f| f.write("# Invoca Gem support\n#{WORKING_DIRECTORY}/**\n") }
|
197
|
+
end
|
198
|
+
|
199
|
+
if !File.directory?(WORKING_DIRECTORY)
|
200
|
+
presenter.set_subtask "creating #{WORKING_DIRECTORY}"
|
201
|
+
Dir.mkdir(WORKING_DIRECTORY)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def bundle_install_application
|
206
|
+
unless @defer_bundle
|
207
|
+
without_ruby_options do
|
208
|
+
shell_command(command: "bundle install --quiet", presenter: presenter)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def bundle_install_gem
|
214
|
+
without_ruby_options do
|
215
|
+
shell_command(command: "bundle install --quiet", path: repo_directory, presenter: presenter)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def without_ruby_options
|
220
|
+
old_opt = ENV.delete("RUBYOPT")
|
221
|
+
yield
|
222
|
+
ensure
|
223
|
+
ENV["RUBYOPT"] = old_opt
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class InvocaGems::Gemfile
|
2
|
+
def initialize(path)
|
3
|
+
@path = path
|
4
|
+
@lines = File.readlines(path).map(&:chomp)
|
5
|
+
end
|
6
|
+
|
7
|
+
def find(gem_name, allow_missing: false)
|
8
|
+
if index = @lines.find_index { |l| l =~ /\A\s*gem\s+.*[\'\"]#{gem_name}[\'\"]/ }
|
9
|
+
InvocaGems::GemfileLine.new(self, @lines[index], index)
|
10
|
+
else
|
11
|
+
allow_missing or InvocaGems::Presenter.stop_with_message "could not find gem #{gem_name}"
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def append(gem_name)
|
17
|
+
InvocaGems::GemfileLine.new(self, "gem '#{gem_name}'", -1)
|
18
|
+
end
|
19
|
+
|
20
|
+
def save!(gemspec)
|
21
|
+
update_gemspec(gemspec)
|
22
|
+
File.open(@path, "w") { |f| f.write(@lines.join("\n") + "\n") }
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def update_gemspec(gemspec)
|
28
|
+
if gemspec.index == -1
|
29
|
+
@lines << gemspec.line
|
30
|
+
else
|
31
|
+
@lines = @lines[0, gemspec.index] + [gemspec.line] + @lines[gemspec.index+1..-1]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class InvocaGems::GemfileLine
|
2
|
+
attr_reader :gemfile, :line, :index
|
3
|
+
attr_reader :gem_name, :gem_version, :gem_ref, :gem_git, :gem_github, :gem_options, :gem_options
|
4
|
+
|
5
|
+
def initialize(gemfile, line, index)
|
6
|
+
@gemfile = gemfile
|
7
|
+
@line = line
|
8
|
+
@index = index
|
9
|
+
@prefix = @line.match(/\A(\s*)gem/)[1]
|
10
|
+
|
11
|
+
instance_eval(line)
|
12
|
+
end
|
13
|
+
|
14
|
+
def save!
|
15
|
+
gemfile.save!(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def gem(name, *args)
|
19
|
+
@gem_name = name
|
20
|
+
@gem_options = args.last.is_a?(Hash) ? args.pop.dup : {}
|
21
|
+
@gem_version = args.first || ">= 0"
|
22
|
+
@gem_branch = @gem_options[:branch] || 'master'
|
23
|
+
@gem_ref = @gem_options.delete(:ref)
|
24
|
+
@gem_git = @gem_options.delete(:git)
|
25
|
+
@gem_github = @gem_options.delete(:github)
|
26
|
+
end
|
27
|
+
|
28
|
+
def update_as_path(path)
|
29
|
+
@line = [
|
30
|
+
"#{@prefix}gem ",
|
31
|
+
"'#{gem_name}',".ljust(24),
|
32
|
+
" path: '#{path}'"
|
33
|
+
].join('')
|
34
|
+
end
|
35
|
+
|
36
|
+
# TODO - Perfer branch before ref.
|
37
|
+
# TODO - handle local branch...
|
38
|
+
def update_as_github(gem_version, uri, sha)
|
39
|
+
@line = [
|
40
|
+
"#{@prefix}gem ",
|
41
|
+
"'#{gem_name}',".ljust(24),
|
42
|
+
" '#{gem_version}', ".ljust(11),
|
43
|
+
"git: '#{uri}',".ljust(56),
|
44
|
+
"ref: '#{sha}'"
|
45
|
+
].join('')
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class InvocaGems::Gemspec
|
2
|
+
def initialize(path)
|
3
|
+
@path = path
|
4
|
+
@lines = File.readlines(path).map(&:chomp)
|
5
|
+
end
|
6
|
+
|
7
|
+
def find(gem_name)
|
8
|
+
index = @lines.find_index { |l| l =~ /\A\s*\S+\s+[\'\"]#{gem_name}[\'\"]/ } or InvocaGems::Presenter.stop_with_message "could not find gem #{gem_name} in #{@path}"
|
9
|
+
InvocaGems::GemspecLine.new(self, gem_name, @lines[index], index)
|
10
|
+
end
|
11
|
+
|
12
|
+
def save!(gemspec)
|
13
|
+
update_gemspec(gemspec)
|
14
|
+
File.open(@path, "w") { |f| f.write(@lines.join("\n") + "\n") }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def update_gemspec(gemspec)
|
20
|
+
@lines = @lines[0, gemspec.index] + [gemspec.line] + @lines[gemspec.index+1..-1]
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class InvocaGems::GemspecLine
|
2
|
+
attr_reader :gemspec, :gem_name, :line, :index, :prefix
|
3
|
+
|
4
|
+
def initialize(gemspec, gem_name, line, index)
|
5
|
+
@gemspec = gemspec
|
6
|
+
@gem_name = gem_name
|
7
|
+
@line = line
|
8
|
+
@index = index
|
9
|
+
@prefix = @line.match(/\A(\s*\S+\s+)[\'\"]/)[1]
|
10
|
+
end
|
11
|
+
|
12
|
+
def save!
|
13
|
+
gemspec.save!(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def update_version(new_version)
|
17
|
+
@line = "#{@prefix}'#{gem_name}', '#{new_version}'"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
class InvocaGems::GitRepo
|
5
|
+
# Encapsulates running git commands in a given directory
|
6
|
+
|
7
|
+
include InvocaGems::ShellCommand
|
8
|
+
attr_accessor :presenter
|
9
|
+
|
10
|
+
def initialize(presenter, repo_root = nil)
|
11
|
+
@presenter = presenter
|
12
|
+
@repo_root = Pathname.new(repo_root || Dir.pwd)
|
13
|
+
end
|
14
|
+
|
15
|
+
def branch
|
16
|
+
git_cmd('rev-parse --abbrev-ref HEAD')
|
17
|
+
end
|
18
|
+
|
19
|
+
def sha
|
20
|
+
git_cmd("rev-parse --verify HEAD")
|
21
|
+
end
|
22
|
+
|
23
|
+
def uri
|
24
|
+
git_cmd("config --get remote.origin.url")
|
25
|
+
end
|
26
|
+
|
27
|
+
def fetch
|
28
|
+
git_cmd("fetch")
|
29
|
+
end
|
30
|
+
|
31
|
+
def commit(message)
|
32
|
+
git_cmd("add -A")
|
33
|
+
git_cmd("commit -m #{Shellwords.escape(message)}")
|
34
|
+
end
|
35
|
+
|
36
|
+
def is_ancestor_commit?(earlier_sha, current_sha)
|
37
|
+
git_cmd("merge-base --is-ancestor #{earlier_sha} #{current_sha}", raise_errors: false)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def branch_exists?(branch_name)
|
42
|
+
branch_name_escaped = Regexp.escape(branch_name)
|
43
|
+
if result = git_cmd("branch -a")
|
44
|
+
result.split("\n").any? do |branch_line|
|
45
|
+
branch_line =~ / #{branch_name_escaped}\z/ || branch_line =~ / remotes\/origin\/#{branch_name_escaped}\z/
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def checkout_branch(branch_name)
|
51
|
+
git_cmd("checkout #{branch_name}")
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def self.clone(root_directory, uri, directory_name, presenter:)
|
56
|
+
git_cmd(root_directory, "clone #{uri} #{directory_name}", presenter: presenter)
|
57
|
+
end
|
58
|
+
|
59
|
+
def unsaved_changes?
|
60
|
+
!git_cmd("diff --quiet", raise_errors: false) || !git_cmd("diff --quiet --cached", raise_errors: false)
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_branch_at(branch_name, sha)
|
64
|
+
git_cmd("branch #{branch_name} #{sha}")
|
65
|
+
end
|
66
|
+
|
67
|
+
def push
|
68
|
+
git_cmd("push -u origin #{branch}")
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def self.git_cmd(path, str, raise_errors: true, presenter: )
|
73
|
+
shell_command(command: "/usr/bin/git #{str}", path: path, raise_errors: raise_errors, presenter: presenter)
|
74
|
+
end
|
75
|
+
|
76
|
+
def git_cmd(str, raise_errors: true)
|
77
|
+
self.class.git_cmd(@repo_root, str, raise_errors: raise_errors, presenter: presenter)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
class InvocaGems::Presenter
|
2
|
+
def set_task(message)
|
3
|
+
clear_task
|
4
|
+
@task = using_mode(:green, message)
|
5
|
+
set_subtask('')
|
6
|
+
end
|
7
|
+
|
8
|
+
def clear_task(keep: true)
|
9
|
+
if @task
|
10
|
+
if keep
|
11
|
+
@new_line_needed = false
|
12
|
+
puts
|
13
|
+
else
|
14
|
+
print reset_line
|
15
|
+
@new_line_needed = false
|
16
|
+
end
|
17
|
+
@task = nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def message(message)
|
22
|
+
puts using_mode(:green, message)
|
23
|
+
end
|
24
|
+
|
25
|
+
def warning(message)
|
26
|
+
puts using_mode(:yellow, "warning: #{message}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def error(message)
|
30
|
+
puts using_mode(:red, "error: #{message}")
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_subtask(message)
|
34
|
+
print "#{reset_line}#{@task}: #{message}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def reset_line
|
38
|
+
"\r\e[K"
|
39
|
+
end
|
40
|
+
|
41
|
+
def puts(*args)
|
42
|
+
unless @silent
|
43
|
+
if @new_line_needed
|
44
|
+
super()
|
45
|
+
@new_line_needed = false
|
46
|
+
end
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def print(*args)
|
52
|
+
unless @silent
|
53
|
+
@new_line_needed = true
|
54
|
+
super
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def silence
|
59
|
+
@silent = true
|
60
|
+
yield
|
61
|
+
ensure
|
62
|
+
@silent = false
|
63
|
+
end
|
64
|
+
|
65
|
+
def set_mode(codes)
|
66
|
+
"\e[#{[codes].flatten.map{ |c| COLOR_CODES[c].to_s }.join(";")}m"
|
67
|
+
end
|
68
|
+
|
69
|
+
def using_mode(codes, message)
|
70
|
+
set_mode(codes) + message + set_mode(:clear)
|
71
|
+
end
|
72
|
+
|
73
|
+
class StopWithMessage < StandardError; end
|
74
|
+
def stop_with_message(message)
|
75
|
+
raise StopWithMessage, message
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.stop_with_message(message)
|
79
|
+
raise StopWithMessage, message
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def self.with_presenter
|
84
|
+
presenter = new
|
85
|
+
begin
|
86
|
+
yield presenter
|
87
|
+
rescue StopWithMessage => ex
|
88
|
+
presenter.error(ex.message)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
COLOR_CODES = {
|
93
|
+
clear: 0,
|
94
|
+
bright: 1,
|
95
|
+
underline: 4,
|
96
|
+
blink: 5,
|
97
|
+
swap: 7,
|
98
|
+
hide: 8,
|
99
|
+
black: 30,
|
100
|
+
red: 31,
|
101
|
+
green: 32,
|
102
|
+
yellow: 33,
|
103
|
+
blue: 34,
|
104
|
+
magenta: 35,
|
105
|
+
white: 37,
|
106
|
+
default: 39,
|
107
|
+
black_background: 40,
|
108
|
+
red_background: 41,
|
109
|
+
blue_background: 40,
|
110
|
+
green_background: 42,
|
111
|
+
blue_background: 44,
|
112
|
+
magenta_background: 45,
|
113
|
+
cyan_background: 46,
|
114
|
+
white_background: 47,
|
115
|
+
default_background: 49
|
116
|
+
}
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module InvocaGems::ShellCommand
|
4
|
+
def self.included(klass)
|
5
|
+
klass.send(:extend, InvocaGems::ShellCommand)
|
6
|
+
end
|
7
|
+
|
8
|
+
# Returns the command output, stripped
|
9
|
+
# Or nil if command failed
|
10
|
+
Response = Struct.new(:stdout, :stderr, :code)
|
11
|
+
def shell_command(command:, path: '.', presenter:, raise_errors: true)
|
12
|
+
presenter.set_subtask "cd #{path}; #{command}"
|
13
|
+
r = Response.new(*Open3.capture3("cd #{path}; #{command}"))
|
14
|
+
if r.code && r.code.success?
|
15
|
+
r.stdout.strip
|
16
|
+
else
|
17
|
+
if raise_errors
|
18
|
+
presenter.stop_with_message "cd #{path}; #{command}: returned error #{r.code.exitstatus}: #{r.stdout}\n#{r.stderr}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: invoca_gems
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bob Smith
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-04-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: thor
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: manage invoca gems as if they were in-app gems
|
84
|
+
email:
|
85
|
+
- bob@ringrevenue.com
|
86
|
+
executables:
|
87
|
+
- invoca_gem
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".ruby_version"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Gemfile
|
95
|
+
- Gemfile.lock
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- exe/invoca_gem
|
99
|
+
- invoca_gems.gemspec
|
100
|
+
- lib/invoca_gems.rb
|
101
|
+
- lib/invoca_gems/bundler.rb
|
102
|
+
- lib/invoca_gems/cli.rb
|
103
|
+
- lib/invoca_gems/gem.rb
|
104
|
+
- lib/invoca_gems/gemfile.rb
|
105
|
+
- lib/invoca_gems/gemfile_line.rb
|
106
|
+
- lib/invoca_gems/gemspec.rb
|
107
|
+
- lib/invoca_gems/gemspec_line.rb
|
108
|
+
- lib/invoca_gems/git_repo.rb
|
109
|
+
- lib/invoca_gems/presenter.rb
|
110
|
+
- lib/invoca_gems/shell_command.rb
|
111
|
+
- lib/invoca_gems/version.rb
|
112
|
+
homepage: http://www.invoca.com
|
113
|
+
licenses: []
|
114
|
+
metadata: {}
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 2.2.2
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: help manage invoca_gems
|
135
|
+
test_files: []
|