ecogem 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +143 -0
- data/Rakefile +2 -0
- data/bin/ecogem +6 -0
- data/ecogem.gemspec +23 -0
- data/lib/ecogem.rb +36 -0
- data/lib/ecogem/cli.rb +21 -0
- data/lib/ecogem/cli/args.rb +35 -0
- data/lib/ecogem/cli/commands/install.rb +22 -0
- data/lib/ecogem/cli/commands/update.rb +22 -0
- data/lib/ecogem/config.rb +11 -0
- data/lib/ecogem/config/entries.rb +10 -0
- data/lib/ecogem/config/entries/git_sources.rb +11 -0
- data/lib/ecogem/config/git_source.rb +17 -0
- data/lib/ecogem/env.rb +34 -0
- data/lib/ecogem/gemfile.rb +95 -0
- data/lib/ecogem/gemfile/dependency.rb +64 -0
- data/lib/ecogem/gemfile/marshal.rb +35 -0
- data/lib/ecogem/gemfile/source.rb +58 -0
- data/lib/ecogem/git.rb +56 -0
- data/lib/ecogem/gitsfile.rb +19 -0
- data/lib/ecogem/gitsfile/entries.rb +10 -0
- data/lib/ecogem/gitsfile/entries/keys.rb +15 -0
- data/lib/ecogem/util.rb +8 -0
- data/lib/ecogem/util/config.rb +62 -0
- data/lib/ecogem/util/config/entry.rb +19 -0
- data/lib/ecogem/util/config/value.rb +8 -0
- data/lib/ecogem/util/config/value_container.rb +86 -0
- data/lib/ecogem/version.rb +3 -0
- data/lib/ecogem/workspace.rb +65 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 60fc0a280bf16df9aa4c75207a8ab7932f30fc82
|
4
|
+
data.tar.gz: 4bd3bd7d9bbc67fd304fab346b9a673250e3029d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b48b9f03002c2e445cce5f3130548a49f3253b532597f93437d05b3549fd4e77d16db8b17d68b050249aca1ff6b4875c9f1ac94f126ff4ae2efd83976a1971b5
|
7
|
+
data.tar.gz: b8da5d7c670404b81c4bf107ff78a8ee9be4b7a1051eab7003b6be90dac01e6e79e03a794a43b549a75ddfa5b75a222824b682259a4a94019ef452bfb782e8f3
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 mosop
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# Ecogem
|
2
|
+
|
3
|
+
Supplements Bundler for installing private gems.
|
4
|
+
|
5
|
+
## Preface
|
6
|
+
|
7
|
+
When the gem A depends on my private gem B whose source is served from GitHub, I can write Gemfile with _:git_ option.
|
8
|
+
|
9
|
+
A's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
source 'https://rubygems.org'
|
13
|
+
gem 'gem-b', git: 'git@github.com:me/gem-b.git'
|
14
|
+
gemspec
|
15
|
+
```
|
16
|
+
|
17
|
+
It's cool. So, I also want to privately put A's source onto GitHub and use A in my application.
|
18
|
+
|
19
|
+
My application's Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
source 'https://rubygems.org'
|
23
|
+
gem 'gem-a', git: 'git@github.com:me/gem-a.git'
|
24
|
+
```
|
25
|
+
|
26
|
+
Then `bundle install` prints:
|
27
|
+
|
28
|
+
Could not find gem 'gem-b (>= 0) ruby', which is required by gem 'gem-a (>= 0) ruby', in any of the sources.
|
29
|
+
|
30
|
+
Oh, my! Bundler does not resolve such deep dependencies.
|
31
|
+
|
32
|
+
To solve this, I need to:
|
33
|
+
|
34
|
+
* add the dependency again like:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
gem 'gem-a', git: 'git@github.com:me/gem-a.git'
|
38
|
+
gem 'gem-b', git: 'git@github.com:me/gem-b.git'
|
39
|
+
```
|
40
|
+
|
41
|
+
It's terrible. Where is DRY?
|
42
|
+
|
43
|
+
* host my private Gem server
|
44
|
+
|
45
|
+
The regular Gem server protocol is not suitable to exchange private resources because it has no sophisticated authentication method such as SSH.
|
46
|
+
|
47
|
+
* subscribe to Gemfury
|
48
|
+
|
49
|
+
Better than self hosting, however, there is still the problem about authentication.
|
50
|
+
|
51
|
+
* make Rubygems accept Git sources
|
52
|
+
|
53
|
+
* make Bundler resolve nested Git dependencies
|
54
|
+
|
55
|
+
These two seem to take forever.
|
56
|
+
|
57
|
+
Okay. The last option is Ecogem.
|
58
|
+
|
59
|
+
## Dependencies
|
60
|
+
|
61
|
+
* fork(2) and UNIX domain socket
|
62
|
+
* Windows and several other platforms are not supported.
|
63
|
+
|
64
|
+
* Ruby >= 2.1 and ~> 2.2
|
65
|
+
* Tested on 2.1.5 (MRI)
|
66
|
+
|
67
|
+
* Bundler >= 1.7.9
|
68
|
+
* Tested on 1.7.9
|
69
|
+
|
70
|
+
## Installation
|
71
|
+
|
72
|
+
Install the gem:
|
73
|
+
|
74
|
+
$ gem install ecogem
|
75
|
+
|
76
|
+
Also install Bundler if not installed:
|
77
|
+
|
78
|
+
$ gem install bundler
|
79
|
+
|
80
|
+
## Usage
|
81
|
+
|
82
|
+
Rename your Gemfile to Ecogemfile and execute:
|
83
|
+
|
84
|
+
$ ecogem install
|
85
|
+
|
86
|
+
## Example
|
87
|
+
|
88
|
+
When
|
89
|
+
|
90
|
+
* My application depends on gem-a whose source is served from GitHub
|
91
|
+
* gem-a depends on gem-b whose source is served from GitHub
|
92
|
+
|
93
|
+
Then `ecogem install` will:
|
94
|
+
|
95
|
+
1. parse Ecogemfile
|
96
|
+
|
97
|
+
Ecogemfile:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
source 'https://rubygems.org'
|
101
|
+
gem 'gem-a', git: 'git@github.com:me/gem-a.git'
|
102
|
+
gem 'rake' # from rubygems.org
|
103
|
+
```
|
104
|
+
|
105
|
+
1. fetch gem-a's Gemfile
|
106
|
+
|
107
|
+
gem-a's Gemfile:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
source 'https://rubygems.org'
|
111
|
+
gem 'gem-b', git: 'git@github.com:me/gem-b.git'
|
112
|
+
gemspec
|
113
|
+
```
|
114
|
+
|
115
|
+
1. fetch gem-b's Gemfile
|
116
|
+
|
117
|
+
gem-b's Gemfile:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
source 'https://rubygems.org'
|
121
|
+
gemspec
|
122
|
+
```
|
123
|
+
|
124
|
+
1. create a new Gemfile file
|
125
|
+
|
126
|
+
Gemfile:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
source 'https://rubygems.org'
|
130
|
+
gem 'gem-b', '>= 0', git: 'git@github.com:me/gem-b.git', branch: 'master'
|
131
|
+
gem 'gem-a', '>= 0', git: 'git@github.com:me/gem-a.git', branch: 'master'
|
132
|
+
gem 'rake', '>= 0'
|
133
|
+
```
|
134
|
+
|
135
|
+
1. and finally execute `bundle install` with the new Gemfile
|
136
|
+
|
137
|
+
## Contributing
|
138
|
+
|
139
|
+
1. Fork it ( https://github.com/[my-github-username]/ecogem/fork )
|
140
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
141
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
142
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
143
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/ecogem
ADDED
data/ecogem.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ecogem/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ecogem"
|
8
|
+
spec.version = Ecogem::VERSION
|
9
|
+
spec.authors = ["mosop"]
|
10
|
+
spec.email = [""]
|
11
|
+
spec.summary = %q{Supplements Bundler for installing private gems.}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
end
|
data/lib/ecogem.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'ecogem/version'
|
2
|
+
|
3
|
+
Object.autoload :Bundler, 'bundler' unless Object.const_defined?(:Bundler, false)
|
4
|
+
|
5
|
+
module Ecogem
|
6
|
+
%w[cli config env gemfile git gitsfile util workspace].each do |name|
|
7
|
+
pascal = name.split(/_/).map{|i| i[0].upcase + i[1..-1]}.join('')
|
8
|
+
autoload pascal, ::File.expand_path("../ecogem/#{name}", __FILE__)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.workspaces
|
12
|
+
::Thread.current[:ecogem_workspaces] ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.workspace
|
16
|
+
workspaces.last
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.new_workspace(args, options = {}, &block)
|
20
|
+
Workspace.new(args, options) do |ws|
|
21
|
+
begin
|
22
|
+
::Thread.current[:ecogem_workspaces] ||= []
|
23
|
+
workspaces << ws
|
24
|
+
break block.call(ws)
|
25
|
+
ensure
|
26
|
+
workspaces.pop
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.git_path(key)
|
32
|
+
new_workspace(nil, readonly: true) do |ws|
|
33
|
+
break ws.gitsfile.dir_of(key)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/ecogem/cli.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'cli/args'
|
2
|
+
|
3
|
+
module Ecogem
|
4
|
+
class Cli
|
5
|
+
def self.start(argv)
|
6
|
+
self.new(argv).execute
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(argv)
|
10
|
+
@args = ::Ecogem::Cli::Args.new(argv)
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
raise "Unknown command: #{@args.command}" unless %w[install update].include?(@args.command)
|
15
|
+
require_relative "cli/commands/#{@args.command}"
|
16
|
+
klass_name = @args.command.split(/_/).map{|i| i[0].upcase + i[1..-1]}.join('')
|
17
|
+
klass = ::Ecogem::Cli::Commands.const_get(klass_name, false)
|
18
|
+
klass.new(@args).execute
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Ecogem
|
2
|
+
class Cli
|
3
|
+
class Args
|
4
|
+
attr_reader :command
|
5
|
+
|
6
|
+
def initialize(argv)
|
7
|
+
@argv = argv.dup
|
8
|
+
parse
|
9
|
+
end
|
10
|
+
|
11
|
+
def options
|
12
|
+
@options ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def bundler_args
|
16
|
+
@argv
|
17
|
+
end
|
18
|
+
|
19
|
+
private def parse
|
20
|
+
@command = @argv.shift
|
21
|
+
extract_options
|
22
|
+
@argv.freeze
|
23
|
+
end
|
24
|
+
|
25
|
+
private def extract_options
|
26
|
+
%i[file port].each do |key|
|
27
|
+
if found = @argv.find_index("--ecogem-#{key}")
|
28
|
+
name, value = @argv.slice(found, 2)
|
29
|
+
options[key] = value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
|
3
|
+
module Ecogem
|
4
|
+
class Cli
|
5
|
+
module Commands
|
6
|
+
class Install
|
7
|
+
def initialize(args)
|
8
|
+
@args = args
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
::Ecogem.new_workspace(@args) do |ws|
|
13
|
+
gemfile = "--gemfile=#{ws.gemfile.write.inspect}"
|
14
|
+
args = [*@args.bundler_args, gemfile].join(' ')
|
15
|
+
command = "bundle install #{args}"
|
16
|
+
system command
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
|
3
|
+
module Ecogem
|
4
|
+
class Cli
|
5
|
+
module Commands
|
6
|
+
class Update
|
7
|
+
def initialize(args)
|
8
|
+
@args = args
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
::Ecogem.new_workspace(@args) do |ws|
|
13
|
+
gemfile = "--gemfile=#{ws.gemfile.write.inspect}"
|
14
|
+
args = [*@args.bundler_args, gemfile].join(' ')
|
15
|
+
command = "bundle update #{args}"
|
16
|
+
system command
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Ecogem
|
2
|
+
class Config < ::Ecogem::Util::Config
|
3
|
+
%w[entries git_source].each do |name|
|
4
|
+
pascal = name.split(/_/).map{|i| i[0].upcase + i[1..-1]}.join('')
|
5
|
+
autoload pascal, ::File.expand_path("../config/#{name}", __FILE__)
|
6
|
+
end
|
7
|
+
|
8
|
+
entry_namespace Entries
|
9
|
+
entry :git_sources
|
10
|
+
end
|
11
|
+
end
|
data/lib/ecogem/env.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Ecogem
|
4
|
+
class Env
|
5
|
+
%w[git_source].each do |name|
|
6
|
+
pascal = name.split(/_/).map{|i| i[0].upcase + i[1..-1]}.join('')
|
7
|
+
autoload pascal, ::File.expand_path("../env/#{name}", __FILE__)
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :dir
|
11
|
+
|
12
|
+
def initialize(base, dir)
|
13
|
+
@base = base
|
14
|
+
@dir = ::File.expand_path(dir)
|
15
|
+
end
|
16
|
+
|
17
|
+
private def config_path
|
18
|
+
@config_path ||= "#{dir}/config"
|
19
|
+
end
|
20
|
+
|
21
|
+
def config
|
22
|
+
@config ||= ::Ecogem::Config.new(@base && @base.config, config_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def git_sources
|
26
|
+
@git_sources ||= ::Hash[config.values.git_sources.map{|i| [i.uri, i]}]
|
27
|
+
end
|
28
|
+
|
29
|
+
def git_source_uri_to_alias(uri)
|
30
|
+
source = git_sources[uri]
|
31
|
+
(source && source.uri_alias) || uri
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Ecogem
|
2
|
+
class Gemfile
|
3
|
+
%w[dependency marshal source].each do |name|
|
4
|
+
pascal = name.split(/_/).map{|i| i[0].upcase + i[1..-1]}.join('')
|
5
|
+
autoload pascal, ::File.expand_path("../gemfile/#{name}", __FILE__)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(path)
|
9
|
+
@path = path
|
10
|
+
end
|
11
|
+
|
12
|
+
def dir
|
13
|
+
@dir ||= ::File.dirname(@pah)
|
14
|
+
end
|
15
|
+
|
16
|
+
private def dependencies
|
17
|
+
@dependencies ||= data.dependencies.map{|i| ::Ecogem::Gemfile::Dependency.new(self, i)}
|
18
|
+
end
|
19
|
+
|
20
|
+
private def extracted_dependencies
|
21
|
+
@extracted_dependencies ||= extract_dependencies([], [], false)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected def extract_dependencies(into, gits, git_only)
|
25
|
+
dependencies.each do |d|
|
26
|
+
if d.source.git?
|
27
|
+
unless gits.include?(d.source.git.key)
|
28
|
+
gits << d.source.git.key
|
29
|
+
d.source.git.gemfile.extract_dependencies into, gits, true if d.source.git.gemfile
|
30
|
+
end
|
31
|
+
into << d
|
32
|
+
else
|
33
|
+
into << d unless git_only
|
34
|
+
end
|
35
|
+
end
|
36
|
+
into
|
37
|
+
end
|
38
|
+
|
39
|
+
private def sources
|
40
|
+
@sources ||= data.sources.instance_variable_get(:@rubygems_aggregate).remotes.map{|i| i.to_s}
|
41
|
+
end
|
42
|
+
|
43
|
+
def code
|
44
|
+
@code ||= begin
|
45
|
+
a = []
|
46
|
+
a << 'require "ecogem"'
|
47
|
+
a << sources.reverse.map{|i| "source #{i.inspect}"}.join("\n")
|
48
|
+
a << extracted_dependencies.map{|i| i.code}.uniq.join("\n")
|
49
|
+
a.join("\n\n")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def write(dir = nil, name = nil)
|
54
|
+
dir ||= ::File.dirname(@path)
|
55
|
+
name ||= 'Gemfile'
|
56
|
+
path = "#{dir}/#{name}"
|
57
|
+
::File.write "#{dir}/#{name}", code
|
58
|
+
path
|
59
|
+
end
|
60
|
+
|
61
|
+
private def data
|
62
|
+
@data ||= load
|
63
|
+
end
|
64
|
+
|
65
|
+
private def load
|
66
|
+
in_r, in_w, out_r, out_w = []
|
67
|
+
|
68
|
+
begin
|
69
|
+
in_r, in_w = ::IO.pipe
|
70
|
+
out_r, out_w = ::IO.pipe
|
71
|
+
|
72
|
+
params = {
|
73
|
+
path: @path
|
74
|
+
}
|
75
|
+
::Marshal.dump({path: @path}, in_w)
|
76
|
+
|
77
|
+
pid = ::Process.fork do
|
78
|
+
params = ::Marshal.load(in_r)
|
79
|
+
|
80
|
+
dsl = ::Bundler::Dsl.new
|
81
|
+
dsl.eval_gemfile(params[:path])
|
82
|
+
result = ::Ecogem::Gemfile::Marshal.new(dsl).to_data
|
83
|
+
|
84
|
+
::Marshal.dump(result, out_w)
|
85
|
+
::Process.exit!
|
86
|
+
end
|
87
|
+
::Process.waitpid(pid)
|
88
|
+
|
89
|
+
::Marshal.load(out_r)
|
90
|
+
ensure
|
91
|
+
[in_r, in_w, out_r, out_w].each{|i| i.close if i}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Ecogem
|
2
|
+
class Gemfile
|
3
|
+
class Dependency
|
4
|
+
def initialize(gemfile, data)
|
5
|
+
@gemfile = gemfile
|
6
|
+
@data = data
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
@data.name
|
11
|
+
end
|
12
|
+
|
13
|
+
def source
|
14
|
+
@source ||= ::Ecogem::Gemfile::Source.new(self, @data.instance_variable_get(:@source))
|
15
|
+
end
|
16
|
+
|
17
|
+
def versions
|
18
|
+
@versions ||= @data.requirement.requirements.map{|i| "#{i[0]} #{i[1]}"}
|
19
|
+
end
|
20
|
+
|
21
|
+
def platforms
|
22
|
+
@platforms ||= @data.instance_variable_get(:@platforms).dup
|
23
|
+
end
|
24
|
+
|
25
|
+
def groups
|
26
|
+
@groups ||= @data.instance_variable_get(:@groups).dup
|
27
|
+
end
|
28
|
+
|
29
|
+
def code
|
30
|
+
@code ||= begin
|
31
|
+
a = ["gem \"#{name}\""]
|
32
|
+
|
33
|
+
if !(versions.size == 1 && versions[0] == '>= 0')
|
34
|
+
a << versions.map{|i| "\"#{i}\""}.join(', ')
|
35
|
+
end
|
36
|
+
|
37
|
+
if platforms.size > 0
|
38
|
+
s = if platforms.size == 1
|
39
|
+
":#{platforms[0]}"
|
40
|
+
else
|
41
|
+
'[' + platforms.map{|i| ":#{i}"}.join(', ') + ']'
|
42
|
+
end
|
43
|
+
a << "platform: #{s}"
|
44
|
+
end
|
45
|
+
|
46
|
+
if groups.size > 0 && !(groups.size == 1 && groups[0] == :default)
|
47
|
+
s = if groups.size == 1
|
48
|
+
":#{groups[0]}"
|
49
|
+
else
|
50
|
+
'[' + groups.map{|i| ":#{i}"}.join(', ') + ']'
|
51
|
+
end
|
52
|
+
a << "group: #{s}"
|
53
|
+
end
|
54
|
+
|
55
|
+
if s = source.code
|
56
|
+
a << s
|
57
|
+
end
|
58
|
+
|
59
|
+
a.join(', ')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Ecogem
|
2
|
+
class Gemfile
|
3
|
+
class Marshal
|
4
|
+
def initialize(dsl)
|
5
|
+
@dsl = dsl
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_data
|
9
|
+
h = {
|
10
|
+
dependencies: @dsl.dependencies,
|
11
|
+
sources: @dsl.instance_variable_get(:@sources)
|
12
|
+
}
|
13
|
+
Data.new(h)
|
14
|
+
end
|
15
|
+
|
16
|
+
class Data
|
17
|
+
def initialize(hash)
|
18
|
+
@hash = hash
|
19
|
+
end
|
20
|
+
|
21
|
+
def dependencies
|
22
|
+
@hash[:dependencies]
|
23
|
+
end
|
24
|
+
|
25
|
+
def groups
|
26
|
+
@hash[:groups]
|
27
|
+
end
|
28
|
+
|
29
|
+
def sources
|
30
|
+
@hash[:sources]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Ecogem
|
4
|
+
class Gemfile
|
5
|
+
class Source
|
6
|
+
attr_reader :git
|
7
|
+
|
8
|
+
def initialize(dependency, data)
|
9
|
+
@dependency = dependency
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
def git?
|
14
|
+
@data && @data.options.key?('git')
|
15
|
+
end
|
16
|
+
|
17
|
+
def path?
|
18
|
+
@data && @data.options.key?('path')
|
19
|
+
end
|
20
|
+
|
21
|
+
def source?
|
22
|
+
@data && @data.options.key?('remotes')
|
23
|
+
end
|
24
|
+
|
25
|
+
def git_uri
|
26
|
+
@data.options['git']
|
27
|
+
end
|
28
|
+
|
29
|
+
def path
|
30
|
+
@data.options['path']
|
31
|
+
end
|
32
|
+
|
33
|
+
def source
|
34
|
+
@data.options['remotes'][0]
|
35
|
+
end
|
36
|
+
|
37
|
+
def ref
|
38
|
+
@data.ref
|
39
|
+
end
|
40
|
+
|
41
|
+
def git
|
42
|
+
@git ||= ::Ecogem::Git.new(git_uri, ref)
|
43
|
+
end
|
44
|
+
|
45
|
+
def code
|
46
|
+
@code ||= begin
|
47
|
+
if git?
|
48
|
+
"path: Ecogem.git_path(#{git.key.inspect})"
|
49
|
+
elsif path?
|
50
|
+
"path: #{path.to_s.inspect}"
|
51
|
+
elsif source?
|
52
|
+
"source: #{source.inspect}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/ecogem/git.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Ecogem
|
4
|
+
class Git
|
5
|
+
def initialize(uri, ref)
|
6
|
+
@uri = uri
|
7
|
+
@ref = ref || 'master'
|
8
|
+
end
|
9
|
+
|
10
|
+
def key
|
11
|
+
@key ||= "#{@uri} #{@ref}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def dir
|
15
|
+
@dir ||= ::Ecogem.workspace.gitsfile.dir_of(key)
|
16
|
+
end
|
17
|
+
|
18
|
+
def uri_alias
|
19
|
+
@uri_alias ||= ::Ecogem.workspace.env.git_source_uri_to_alias(@uri)
|
20
|
+
end
|
21
|
+
|
22
|
+
def exec(cmd)
|
23
|
+
puts "git: #{cmd}"
|
24
|
+
cmd = "git #{cmd}"
|
25
|
+
system("cd \"#{dir}\"; #{cmd}")
|
26
|
+
end
|
27
|
+
|
28
|
+
private def load
|
29
|
+
unless @loaded
|
30
|
+
::FileUtils.rm_rf dir
|
31
|
+
::FileUtils.mkdir_p dir
|
32
|
+
self.exec "init -q"
|
33
|
+
self.exec "remote add origin \"#{uri_alias}\""
|
34
|
+
self.exec "fetch -q origin #{@ref}"
|
35
|
+
raise CommandError unless $?.success?
|
36
|
+
self.exec "checkout -q FETCH_HEAD"
|
37
|
+
raise CommandError unless $?.success?
|
38
|
+
@loaded = true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private def gemfile_path
|
43
|
+
@gemfile_path ||= ::File.expand_path("#{dir}/Ecogemfile")
|
44
|
+
end
|
45
|
+
|
46
|
+
def gemfile
|
47
|
+
@gemfile ||= begin
|
48
|
+
load
|
49
|
+
::Ecogem::Gemfile.new(gemfile_path) if ::File.file?(gemfile_path)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class CommandError < ::StandardError
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Ecogem
|
2
|
+
class Gitsfile < ::Ecogem::Util::Config
|
3
|
+
%w[entries].each do |name|
|
4
|
+
pascal = name.split(/_/).map{|i| i[0].upcase + i[1..-1]}.join('')
|
5
|
+
autoload pascal, ::File.expand_path("../gitsfile/#{name}", __FILE__)
|
6
|
+
end
|
7
|
+
|
8
|
+
entry_namespace Entries
|
9
|
+
entry :keys
|
10
|
+
|
11
|
+
def dir_of(key)
|
12
|
+
i = values.keys.find_index(key) || begin
|
13
|
+
values.keys << key
|
14
|
+
values.keys.size - 1
|
15
|
+
end
|
16
|
+
"#{dir}/#{i+1}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/ecogem/util.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Ecogem
|
4
|
+
module Util
|
5
|
+
class Config
|
6
|
+
%w[entry value value_container].each do |name|
|
7
|
+
pascal = name.split(/_/).map{|i| i[0].upcase + i[1..-1]}.join('')
|
8
|
+
autoload pascal, ::File.expand_path("../config/#{name}", __FILE__)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.entry_namespaces
|
12
|
+
@entry_namespaces ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.entry_namespace(ns)
|
16
|
+
entry_namespaces << ns
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.entry(key)
|
20
|
+
e = ::Ecogem::Util::Config::Entry.create(self, key)
|
21
|
+
entries[key] = e
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.find_entry_class(key)
|
25
|
+
pascal = key.to_s.split(/_/).map{|i| i[0].upcase + i[1..-1]}.join('')
|
26
|
+
entry_namespaces.reverse.each do |ns|
|
27
|
+
return ns.const_get(pascal, false) if ns.const_defined?(pascal, false)
|
28
|
+
end
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.entries
|
33
|
+
@entries ||= {}
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(base, path)
|
37
|
+
@base = base
|
38
|
+
@path = ::File.expand_path(path)
|
39
|
+
end
|
40
|
+
|
41
|
+
def dir
|
42
|
+
@dir ||= ::File.dirname(@path)
|
43
|
+
end
|
44
|
+
|
45
|
+
protected def value_container
|
46
|
+
@value_conatiner ||= ::Ecogem::Util::Config::ValueContainer.new(@base && @base.value_container, self, load || {})
|
47
|
+
end
|
48
|
+
|
49
|
+
def values
|
50
|
+
@values ||= value_container.proxy
|
51
|
+
end
|
52
|
+
|
53
|
+
private def load
|
54
|
+
::YAML.load(::File.read(@path)) if ::File.file?(@path)
|
55
|
+
end
|
56
|
+
|
57
|
+
def save
|
58
|
+
::File.write @path, value_container.values_to_h.to_yaml
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Ecogem
|
2
|
+
module Util
|
3
|
+
class Config
|
4
|
+
class Entry
|
5
|
+
attr_reader :key
|
6
|
+
|
7
|
+
def initialize(config, key)
|
8
|
+
@config = config
|
9
|
+
@key = key
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.create(config, key, options = {})
|
13
|
+
klass = options[:class] || config.find_entry_class(key)
|
14
|
+
klass.new(config, key)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Ecogem
|
2
|
+
module Util
|
3
|
+
class Config
|
4
|
+
class ValueContainer
|
5
|
+
def initialize(base, config, default_data)
|
6
|
+
@base = base
|
7
|
+
@config = config
|
8
|
+
@default_data = default_data
|
9
|
+
end
|
10
|
+
|
11
|
+
def proxy
|
12
|
+
@proxy ||= Proxy.new(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def values
|
16
|
+
@values ||= h_to_values(@default_data || {})
|
17
|
+
end
|
18
|
+
|
19
|
+
def h_to_values(h)
|
20
|
+
values = {}
|
21
|
+
h.each do |k, v|
|
22
|
+
k = k.to_sym
|
23
|
+
entry = @config.class.entries[k]
|
24
|
+
values[k] = entry.parse(v) if entry
|
25
|
+
end
|
26
|
+
values
|
27
|
+
end
|
28
|
+
|
29
|
+
def values_to_h
|
30
|
+
h = {}
|
31
|
+
values.each do |k, v|
|
32
|
+
entry = @config.class.entries[k]
|
33
|
+
h[k.to_s] = entry.unparse(v)
|
34
|
+
end
|
35
|
+
h
|
36
|
+
end
|
37
|
+
|
38
|
+
def resolve_method(name, *args, &block)
|
39
|
+
key = name.to_s.sub(/(=)$/, '').to_sym
|
40
|
+
assign = $1
|
41
|
+
entry = @config.class.entries[key]
|
42
|
+
if entry
|
43
|
+
if assign
|
44
|
+
return values[key] = args.first
|
45
|
+
else
|
46
|
+
begin
|
47
|
+
return find_value(key)
|
48
|
+
rescue NotFoundError
|
49
|
+
value = entry.parse(nil)
|
50
|
+
values[key] = value
|
51
|
+
return value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
raise UnresolvedError
|
56
|
+
end
|
57
|
+
|
58
|
+
def find_value(key)
|
59
|
+
return values[key] if values.key?(key)
|
60
|
+
return @base.find_value(key) if @base
|
61
|
+
raise NotFoundError
|
62
|
+
end
|
63
|
+
|
64
|
+
class NotFoundError < ::StandardError
|
65
|
+
end
|
66
|
+
|
67
|
+
class UnresolvedError < ::StandardError
|
68
|
+
end
|
69
|
+
|
70
|
+
class Proxy
|
71
|
+
def initialize(container)
|
72
|
+
@container = container
|
73
|
+
end
|
74
|
+
|
75
|
+
def method_missing(name, *args, &block)
|
76
|
+
begin
|
77
|
+
return @container.resolve_method(name, *args, &block)
|
78
|
+
rescue ::Ecogem::Util::Config::ValueContainer::UnresolvedError
|
79
|
+
end
|
80
|
+
super
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Ecogem
|
6
|
+
class Workspace
|
7
|
+
def initialize(args, options = {}, &block)
|
8
|
+
@args = args || ::Ecogem::Cli::Args.new([])
|
9
|
+
options = {}.merge(options)
|
10
|
+
new_tmpdir do |dir|
|
11
|
+
begin
|
12
|
+
@workdir = dir
|
13
|
+
block.call self
|
14
|
+
unless options[:readonly]
|
15
|
+
gitsfile.save
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def global_env
|
22
|
+
@global_env ||= ::Ecogem::Env.new(nil, ::File.expand_path(::Dir.home + '/.ecogem'))
|
23
|
+
end
|
24
|
+
|
25
|
+
def env
|
26
|
+
@env ||= ::Ecogem::Env.new(global_env, env_path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def gitsfile
|
30
|
+
@gitsfile ||= ::Ecogem::Gitsfile.new(nil, global_env.dir + '/gits/keys')
|
31
|
+
end
|
32
|
+
|
33
|
+
private def env_path
|
34
|
+
@env_path ||= begin
|
35
|
+
path = ::File.expand_path(@args.options[:env] || ::File.dirname(gemfile_path) + '/.ecogem')
|
36
|
+
raise "file exists: #{path}" if ::File.file?(path)
|
37
|
+
::FileUtils.mkdir_p path unless ::File.exist?(path)
|
38
|
+
path
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private def gemfile_path
|
43
|
+
@gemfile_path ||= ::File.expand_path(@args.options[:gemfile] || ::Dir.pwd + '/Ecogemfile')
|
44
|
+
end
|
45
|
+
|
46
|
+
def gemfile
|
47
|
+
@gemfile ||= ::Ecogem::Gemfile.new(gemfile_path)
|
48
|
+
end
|
49
|
+
|
50
|
+
private def tmp_path
|
51
|
+
@tmp_path ||= begin
|
52
|
+
path = File.expand_path(@args.options[:tmpdir] || "#{env_path}/tmp")
|
53
|
+
raise "file exists: #{path}" if ::File.file?(path)
|
54
|
+
path
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def new_tmpdir(&block)
|
59
|
+
::FileUtils.mkdir_p tmp_path unless ::File.exist?(tmp_path)
|
60
|
+
::Dir.mktmpdir(nil, tmp_path) do |dir|
|
61
|
+
return block.call(dir)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ecogem
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mosop
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-12 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.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
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
|
+
description: ''
|
42
|
+
email:
|
43
|
+
- ''
|
44
|
+
executables:
|
45
|
+
- ecogem
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE.txt
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- bin/ecogem
|
55
|
+
- ecogem.gemspec
|
56
|
+
- lib/ecogem.rb
|
57
|
+
- lib/ecogem/cli.rb
|
58
|
+
- lib/ecogem/cli/args.rb
|
59
|
+
- lib/ecogem/cli/commands/install.rb
|
60
|
+
- lib/ecogem/cli/commands/update.rb
|
61
|
+
- lib/ecogem/config.rb
|
62
|
+
- lib/ecogem/config/entries.rb
|
63
|
+
- lib/ecogem/config/entries/git_sources.rb
|
64
|
+
- lib/ecogem/config/git_source.rb
|
65
|
+
- lib/ecogem/env.rb
|
66
|
+
- lib/ecogem/gemfile.rb
|
67
|
+
- lib/ecogem/gemfile/dependency.rb
|
68
|
+
- lib/ecogem/gemfile/marshal.rb
|
69
|
+
- lib/ecogem/gemfile/source.rb
|
70
|
+
- lib/ecogem/git.rb
|
71
|
+
- lib/ecogem/gitsfile.rb
|
72
|
+
- lib/ecogem/gitsfile/entries.rb
|
73
|
+
- lib/ecogem/gitsfile/entries/keys.rb
|
74
|
+
- lib/ecogem/util.rb
|
75
|
+
- lib/ecogem/util/config.rb
|
76
|
+
- lib/ecogem/util/config/entry.rb
|
77
|
+
- lib/ecogem/util/config/value.rb
|
78
|
+
- lib/ecogem/util/config/value_container.rb
|
79
|
+
- lib/ecogem/version.rb
|
80
|
+
- lib/ecogem/workspace.rb
|
81
|
+
homepage: ''
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.2.2
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Supplements Bundler for installing private gems.
|
105
|
+
test_files: []
|