envandle 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ca4f6faadb9b5212f25212d23ab42ab36d9e1c5
4
- data.tar.gz: 00da2b9a9de635373d09654e47f52c391b28b6ba
3
+ metadata.gz: ff69392778f46788da2d586a57395dd909d84936
4
+ data.tar.gz: 601ea8bffd72c9460f953b6356702cda831f1ec3
5
5
  SHA512:
6
- metadata.gz: 98977a5f9a1f7b29e0b1222693cf6f04cb8ea409ab1c31aa3ac67bf7fed328cda2b6818f31c6690ce62395f937c76754ecce5388d0514b1804c851639b4c50ab
7
- data.tar.gz: 2f70f6b8b345f854c8fffe4791ba47e56b432d7602136c1f91c4cb523dc9d702db1ffd03be287b8fa67d1f451b5f03f50801389ff7915a7aa9870df2f547bdcf
6
+ metadata.gz: 70fe6bade653580f5351ebd44ab4bb8ddd476dcd2ccd0a3f85efc05c0f5ef95894d98eb3990c973f6a9d397ea122db4d0559221f13ed739560677c5a194461e6
7
+ data.tar.gz: 1794974ec6611b2e511e599939da7c9c03a7cea7064f241f45a08b8f1a281587bf90c2034f0eb858e8ceb0026a6a622e7a3171aa6fdc4c7db747d3c71d05ef38
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.3.1
4
+ - 2.3.3
5
5
  before_install: gem install bundler -v 1.13.6
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A rubygem for enabling Gemfiles to specify gem locations from environment variables.
4
4
 
5
+ [![Build Status](https://travis-ci.org/mosop/envandle.svg?branch=master)](https://travis-ci.org/mosop/envandle)
6
+
5
7
  ## Installation
6
8
 
7
9
  ```sh
@@ -10,14 +12,14 @@ $ gem install envandle
10
12
 
11
13
  ## Usage
12
14
 
13
- Write a Gemfile.
15
+ Enclose your Gemfile's code with an envandle block.
14
16
 
15
17
  ```ruby
16
18
  require "envandle"
17
19
 
18
- source "https://rubygems.org"
20
+ binding.envandle do
21
+ source "https://rubygems.org"
19
22
 
20
- binding.envandle do |bundle|
21
23
  bundle.gem "mygem", "~> 1.0"
22
24
  end
23
25
  ```
@@ -45,8 +47,10 @@ For example,
45
47
  ```ruby
46
48
  ENV["ENVANDLE_GEM_PATH"] = "mygem:/path/to/mygem"
47
49
 
48
- binding.envandle do |bundle|
49
- bundle.gem "mygem", "~> 1.0"
50
+ binding.envandle do
51
+ source "https://rubygems.org"
52
+
53
+ gem "mygem", "~> 1.0"
50
54
  end
51
55
  ```
52
56
 
@@ -61,8 +65,10 @@ If the variable is not set,
61
65
  ```ruby
62
66
  ENV["ENVANDLE_GEM_PATH"] = ""
63
67
 
64
- binding.envandle do |bundle|
65
- bundle.gem "mygem", "~> 1.0"
68
+ binding.envandle do
69
+ source "https://rubygems.org"
70
+
71
+ gem "mygem", "~> 1.0"
66
72
  end
67
73
  ```
68
74
 
@@ -81,8 +87,10 @@ For example,
81
87
  ```ruby
82
88
  ENV["ENVANDLE_GEM_GIT_BRANCH"] = "mygem:https://github.com/mosop/mygem.git#edge"
83
89
 
84
- binding.envandle do |bundle|
85
- bundle.gem "mygem", "~> 1.0"
90
+ envandle do
91
+ source "https://rubygems.org"
92
+
93
+ gem "mygem", "~> 1.0"
86
94
  end
87
95
  ```
88
96
 
@@ -97,8 +105,10 @@ If the variable is not set,
97
105
  ```ruby
98
106
  ENV["ENVANDLE_GEM_GIT_BRANCH"] = ""
99
107
 
100
- binding.envandle do |bundle|
101
- bundle.gem "mygem", "~> 1.0"
108
+ binding.envandle do
109
+ source "https://rubygems.org"
110
+
111
+ gem "mygem", "~> 1.0"
102
112
  end
103
113
  ```
104
114
 
@@ -117,8 +127,10 @@ For example, if your gem's name is "mygem", the gemspec refers the a, b and c ge
117
127
  ```ruby
118
128
  ENV["ENVANDLE_GEM_PATH"] = "a:/path/to/a;b:/path/to/b"
119
129
 
120
- binding.envandle do |bundle|
121
- bundle.gemspec
130
+ binding.envandle do
131
+ source "https://rubygems.org"
132
+
133
+ gemspec
122
134
  end
123
135
  ```
124
136
 
@@ -138,8 +150,10 @@ For example, if a Gemfile refers the gem a that depends on the gem b, Envandle a
138
150
  ```ruby
139
151
  ENV["ENVANDLE_GEM_PATH"] = "a:/path/to/a;b:/path/to/b"
140
152
 
141
- binding.envandle do |bundle|
142
- bundle.gem "a", "~> 1.0"
153
+ binding.envandle do
154
+ source "https://rubygems.org"
155
+
156
+ gem "a", "~> 1.0"
143
157
  end
144
158
  ```
145
159
 
@@ -0,0 +1,61 @@
1
+ module Envandle
2
+ class Argset
3
+ def initialize(context, *args, &block)
4
+ @context = context
5
+ @args = args
6
+ h = Envandle.options!(args)
7
+ @options = {}
8
+ h.each do |k, v|
9
+ @options[k.to_s.to_sym] = v
10
+ end
11
+ @block = block
12
+ end
13
+
14
+ attr_reader :args, :options, :block
15
+
16
+ def dup
17
+ Argset.new(@context, *@args.dup, @options.dup, &@block)
18
+ end
19
+
20
+ def clear_reference
21
+ @args = [@args[0]]
22
+ @options.delete :path
23
+ @options.delete :git
24
+ @options.delete :github
25
+ @options.delete :ref
26
+ @options.delete :branch
27
+ @options.delete :tag
28
+ end
29
+
30
+ def args_and_options
31
+ @args_and_options ||= begin
32
+ if @options.empty?
33
+ [*@args]
34
+ else
35
+ [*@args, @options]
36
+ end
37
+ end
38
+ end
39
+
40
+ def to_s
41
+ a = [@context, *args_and_options]
42
+ a << @block if @block
43
+ a.to_s
44
+ end
45
+
46
+ def send_to(o)
47
+ o.__send__ @context, *args_and_options, &@block
48
+ end
49
+
50
+ def contextual_groups
51
+ @contextual_groups ||= get_contexutual_groups
52
+ end
53
+
54
+ def get_contexutual_groups
55
+ if option = @options[:groups] || @options[:group]
56
+ return option.is_a?(Array) ? option : [option]
57
+ end
58
+ @context.groups_or_default
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,16 @@
1
+ module Envandle
2
+ module AsContext
3
+ def self.extended(mod)
4
+ mod.class_eval do
5
+ def gemfile
6
+ @context.gemfile
7
+ end
8
+
9
+ def groups_or_default
10
+ a = groups
11
+ a.empty? ? [nil] : a
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ module Envandle
2
+ module AsDsl
3
+ def self.extended(mod)
4
+ mod.class_eval do
5
+ def initialize(e)
6
+ @element = e
7
+ end
8
+ end
9
+ end
10
+
11
+ def dsl_method(name)
12
+ name = name.to_s
13
+ class_name = Envandle.pascal(name)
14
+ block_class_name = "#{class_name}Block"
15
+ define_method name do |*args, &block|
16
+ klass = ::Envandle::Elements.const_get(block ? block_class_name : class_name)
17
+ o = klass.new(::Envandle.loc, @element, *args, &block)
18
+ @element << o
19
+ o.draw
20
+ end
21
+ end
22
+ end
23
+ end
@@ -5,7 +5,7 @@ module Envandle
5
5
  attr_reader :group, :name
6
6
 
7
7
  def key
8
- @key ||= ReferenceCache.key(group, name)
8
+ @key ||= ::Envandle.reference_key(group, name)
9
9
  end
10
10
  end
11
11
  end
@@ -1,12 +1,7 @@
1
1
  require "envandle/lib"
2
2
 
3
3
  class Binding
4
- def envandle
5
- /^(.+?):(\d+)(?::in `(.*)')?/ =~ caller(1, 1).first
6
- yield ::Envandle::BundleDsl.new(::Envandle::Gemfile.new($1, self))
7
- end
8
-
9
- def gem(*args)
10
- receiver.__send__ :gem, *args
4
+ def envandle(&block)
5
+ ::Envandle::Elements::Gemfile.new(::Envandle.loc.file, self).draw &block
11
6
  end
12
7
  end
@@ -0,0 +1,61 @@
1
+ module Envandle
2
+ class Element
3
+ def initialize(loc, context, *args, &block)
4
+ @loc = loc
5
+ @context = context
6
+ @args = Argset.new(self, *args, &block)
7
+ end
8
+
9
+ def parse_string_value(v, type)
10
+ if v
11
+ v = v.to_s.strip
12
+ Envandle.arg! @loc, type if v.empty?
13
+ v
14
+ end
15
+ end
16
+
17
+ def parse_string_option(name, type)
18
+ parse_string_value(@args.options[name], type)
19
+ end
20
+
21
+ def gemfile
22
+ @context.gemfile
23
+ end
24
+
25
+ def groups_or_default
26
+ @context.groups_or_default
27
+ end
28
+
29
+ def dsl
30
+ self.class::Dsl.new(self)
31
+ end
32
+
33
+ def draw(&block)
34
+ block ||= @args.block
35
+ dsl.instance_exec &block if block
36
+ end
37
+
38
+ def children
39
+ @children ||= []
40
+ end
41
+
42
+ def children_by_type(type = nil)
43
+ if type
44
+ (@children_by_type ||= {})[type] ||= []
45
+ else
46
+ @children_by_type ||= {}
47
+ end
48
+ end
49
+
50
+ def <<(child)
51
+ children << child
52
+ children_by_type(child.type) << child
53
+ end
54
+
55
+ def exec(context)
56
+ executable_argsets.each do |i|
57
+ i.send_to context
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,30 @@
1
+ module Envandle
2
+ module Elements
3
+ class Gem < Element
4
+ def initialize(*)
5
+ super
6
+ @name = parse_string_value(@args.args[0].to_s, "gem name")
7
+ end
8
+
9
+ def type
10
+ :gem
11
+ end
12
+
13
+ def extract_executable_argsets(a, cache)
14
+ found = false
15
+ @args.contextual_groups.each do |group|
16
+ if gemfile.references.extract_executable_argsets(@args, group, @name, a, cache)
17
+ found = true
18
+ end
19
+ end
20
+ a << Argset.new(:gem, *@args.args_and_options) unless found
21
+ end
22
+
23
+ def executable_argsets
24
+ @executable_argsets ||= [].tap do |a|
25
+ extract_executable_argsets a, {}
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,71 @@
1
+ module Envandle
2
+ module Elements
3
+ class Gemfile < Element
4
+ extend AsContext
5
+
6
+ class Dsl
7
+ extend AsDsl
8
+
9
+ dsl_method :source
10
+ dsl_method :group
11
+ dsl_method :gem
12
+ dsl_method :gemspec
13
+ dsl_method :git_source
14
+ end
15
+
16
+ def initialize(file, binding, config_dir = nil)
17
+ super Location.new(file, 1), nil
18
+ @binding = binding
19
+ @config_dir = config_dir
20
+ end
21
+
22
+ def binding_receiver
23
+ @binding.receiver
24
+ end
25
+
26
+ def draw(&block)
27
+ super
28
+ exec
29
+ end
30
+
31
+ def exec
32
+ receiver = @binding.receiver
33
+ children.each do |child|
34
+ child.exec receiver
35
+ end
36
+ end
37
+
38
+ def dir
39
+ @dir ||= File.dirname(@loc.file)
40
+ end
41
+
42
+ def config_dir
43
+ @config_dir ||= File.join(dir, ".envandle")
44
+ end
45
+
46
+ def gemfile
47
+ self
48
+ end
49
+
50
+ def references
51
+ @references ||= ReferenceCache.new(self)
52
+ end
53
+
54
+ def gemspecs
55
+ @gemspecs ||= GemspecCache.new(File.join(config_dir, "cache", "gemspecs"))
56
+ end
57
+
58
+ def sources
59
+ children_by_type(:source)
60
+ end
61
+
62
+ def source_urls
63
+ sources.map{|i| i.url}
64
+ end
65
+
66
+ def groups
67
+ []
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,37 @@
1
+ module Envandle
2
+ module Elements
3
+ class Gemspec < Element
4
+ extend AsContext
5
+
6
+ def initialize(*)
7
+ super
8
+ dev_group = parse_string_option(:development_group, "gemspec's development group") || :development
9
+ @development_group = dev_group ? dev_group.to_s.to_sym : :development
10
+ @name = parse_string_option(:name, "gemspec's name")
11
+ @path = parse_string_option(:path, "gemspec's path")
12
+ end
13
+
14
+ def type
15
+ :gemspec
16
+ end
17
+
18
+ def executable_argsets
19
+ @executable_argsets ||= begin
20
+ [].tap do |a|
21
+ path = @path || ::Envandle::Gemspec.find_file(gemfile.dir, name: @name)
22
+ spec = ::Envandle::Gemspec.new(path)
23
+ a << Argset.new(:gem, spec.name, path: ".")
24
+ found = {}
25
+ spec.dependencies.each do |i|
26
+ group = i.type == :development ? @development_group : nil
27
+ argset = Argset.new(nil, i.name, *i.requirements_list)
28
+ argset.options[:group] = group if group
29
+ gem = Gem.new(@loc, @context, *argset.args_and_options)
30
+ gem.extract_executable_argsets a, found
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ module Envandle
2
+ module Elements
3
+ class GitSourceBlock < Element
4
+ def draw
5
+ end
6
+
7
+ def type
8
+ :git_source_block
9
+ end
10
+
11
+ def executable_argsets
12
+ @executable_argsets ||= [].tap do |a|
13
+ a << Argset.new(:git_source, *@args.args_and_options, &@args.block)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ module Envandle
2
+ module Elements
3
+ class GroupBlock < Element
4
+ extend AsContext
5
+
6
+ class Dsl
7
+ extend AsDsl
8
+
9
+ dsl_method :gem
10
+ end
11
+
12
+ def initialize(*)
13
+ super
14
+ Envandle.arg! @loc, "No group names." if @args.args.empty?
15
+ end
16
+
17
+ def type
18
+ :group_block
19
+ end
20
+
21
+ def groups
22
+ @groups ||= @args.args.dup
23
+ end
24
+
25
+ def executable_argsets
26
+ @executable_argsets ||= [].tap do |a|
27
+ a << Argset.new(:group, *@args.args_and_options) do
28
+ children.each do |child|
29
+ child.exec gemfile.binding_receiver
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ module Envandle
2
+ class IllegalElement
3
+ def initialize(loc, *)
4
+ Envandle.legal! loc, type
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ module Envandle
2
+ class GemBlock < IllegalElement
3
+ def type
4
+ "gem with block"
5
+ end
6
+ end
7
+
8
+ class GemspecBlock < IllegalElement
9
+ def type
10
+ "gemspec with block"
11
+ end
12
+ end
13
+
14
+ class GitSource < IllegalElement
15
+ def type
16
+ "git_source without block"
17
+ end
18
+ end
19
+
20
+ class Group < IllegalElement
21
+ def type
22
+ "group without block"
23
+ end
24
+ end
25
+
26
+ class SourceBlock < UnsupportedElement
27
+ def type
28
+ "source with block"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ module Envandle
2
+ module Elements
3
+ class Source < Element
4
+ def type
5
+ :source
6
+ end
7
+
8
+ def executable_argsets
9
+ @executable_argsets ||= [].tap do |a|
10
+ a << Argset.new(:source, *@args.args_and_options)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Envandle
2
+ class UnsupportedElement
3
+ def initialize(loc, *)
4
+ Envandle.support! loc, type
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require "envandle/elements/element"
2
+ require "envandle/elements/illegal_element"
3
+ require "envandle/elements/unsupported_element"
4
+ require "envandle/elements/gem"
5
+ require "envandle/elements/gemfile"
6
+ require "envandle/elements/gemspec"
7
+ require "envandle/elements/git_source_block"
8
+ require "envandle/elements/group_block"
9
+ require "envandle/elements/illegals_and_unsupporteds"
10
+ require "envandle/elements/source"
@@ -0,0 +1,13 @@
1
+ module Envandle
2
+ def self.arg!(loc, type)
3
+ raise ArgumentError.new("Missing argument: #{type} (#{loc})")
4
+ end
5
+
6
+ def self.legal!(loc, type)
7
+ raise ArgumentError.new("Illegal element: #{type} (#{loc})")
8
+ end
9
+
10
+ def self.support!(loc, type)
11
+ raise NotImplementedError.new("Unsupported element: #{type} (#{loc})")
12
+ end
13
+ end
@@ -0,0 +1,64 @@
1
+ module Envandle
2
+ class GemspecCache
3
+ @@mutex = Mutex.new
4
+
5
+ def initialize(path)
6
+ @path = path
7
+ FileUtils.mkdir_p @path
8
+ end
9
+
10
+ def with_file
11
+ path = File.join(@path, "list")
12
+ @@mutex.synchronize do
13
+ File.open(path, File::RDWR | File::CREAT) do |f|
14
+ f.flock File::LOCK_EX
15
+ yield f
16
+ end
17
+ end
18
+ end
19
+
20
+ def append(url, dir)
21
+ with_file do |f|
22
+ data = YAML.load(f.read) || {}
23
+ data[url] = dir
24
+ f.rewind
25
+ f.write data.to_yaml
26
+ f.flush
27
+ f.truncate f.pos
28
+ end
29
+ end
30
+
31
+ def load
32
+ with_file do |f|
33
+ YAML.load(f.read) || {}
34
+ end
35
+ end
36
+
37
+ def find(url)
38
+ if dir = load[url]
39
+ File.join(@path, dir)
40
+ end
41
+ end
42
+
43
+ def reserve
44
+ Reserved.new(@path)
45
+ end
46
+
47
+ class Reserved
48
+ def initialize(cache_path)
49
+ @cache_path = cache_path
50
+ @path = Dir.mktmpdir(nil, cache_path)
51
+ end
52
+
53
+ attr_reader :path
54
+
55
+ def url=(v)
56
+ @url = v
57
+ end
58
+
59
+ def save
60
+ GemspecCache.new(@cache_path).append @url, @path[(@cache_path.size+1)..-1]
61
+ end
62
+ end
63
+ end
64
+ end
data/lib/envandle/git.rb CHANGED
@@ -1,15 +1,50 @@
1
1
  module Envandle
2
- GIT = `which git`.chomp
2
+ GIT_BIN = `which git`.chomp
3
3
 
4
- def self.git_pull(url, ref, branch)
5
- raise "No git installed." if GIT.empty?
6
- Dir.mktmpdir do |tmp|
7
- Dir.chdir(tmp) do
8
- sh "#{GIT} init"
9
- sh "#{GIT} remote add origin #{url}"
10
- sh "#{GIT} checkout -b #{branch}"
11
- sh "#{GIT} pull origin #{ref}:#{branch}"
12
- yield tmp
4
+ def self.raise_if_no_git_installed
5
+ raise "No git installed." if GIT_BIN.empty?
6
+ end
7
+
8
+ def self.git_init(dir, url, &block)
9
+ unless dir
10
+ Dir.mktmpdir do |tmpdir|
11
+ git_init tmpdir, url, &block
12
+ end
13
+ else
14
+ raise_if_no_git_installed
15
+ Dir.chdir(dir) do
16
+ sh "#{GIT_BIN} init"
17
+ sh "#{GIT_BIN} remote add origin #{url}"
18
+ yield dir if block_given?
19
+ end
20
+ end
21
+ end
22
+
23
+ def self.git_ls_remote_sha(dir, q)
24
+ Dir.chdir(dir) do
25
+ data = sh("#{GIT_BIN} ls-remote origin #{q}").chomp
26
+ data = if data.empty?
27
+ []
28
+ else
29
+ data.split("\n").map{|i| i.split(/\s+/)[0] }
30
+ end
31
+ if block_given?
32
+ yield data
33
+ else
34
+ data
35
+ end
36
+ end
37
+ end
38
+
39
+ def self.git_pull(dir, ref, branch)
40
+ Dir.chdir(dir) do
41
+ sh "#{GIT_BIN} checkout -b #{branch}"
42
+ sh "#{GIT_BIN} pull origin #{ref}:#{branch}"
43
+ sha = sh("#{GIT_BIN} rev-parse HEAD").chomp
44
+ if block_given?
45
+ yield sha
46
+ else
47
+ sha
13
48
  end
14
49
  end
15
50
  end
@@ -2,21 +2,41 @@ module Envandle
2
2
  class GitBranchReference
3
3
  extend AsGitReference
4
4
 
5
- def initialize(group, name, url, ref)
5
+ def initialize(context, group, name, url, ref)
6
+ @context = context
6
7
  @group = group
7
8
  @name = name
8
9
  @url = url
9
10
  @ref = ref
10
11
  end
11
12
 
12
- def to_gem(args, options)
13
- Gem.new(@group, @name, [], {git: @url, branch: @ref})
14
- end
15
-
16
13
  def spec
17
- Envandle.git_pull(@url, @ref, @ref) do |dir|
14
+ @spec ||= begin
15
+ cache = @context.gemfile.gemspecs
16
+ shas = Envandle.git_init(nil, @url) do |dir|
17
+ Envandle.git_ls_remote_sha(dir, "refs/heads/#{@ref}")
18
+ end
19
+ sha = shas[0]
20
+ cache_url = "#{@url}##{sha}"
21
+ raise "Can't get a git commit. (url: #{@url}, branch: #{@ref})" unless sha
22
+ dir = cache.find(cache_url) || begin
23
+ reserve = cache.reserve
24
+ Envandle.git_init reserve.path, @url
25
+ sha = Envandle.git_pull(reserve.path, @ref, "master")
26
+ reserve.url = cache_url
27
+ reserve.save
28
+ reserve.path
29
+ end
18
30
  Gemspec.new(File.join(dir, "#{@name}.gemspec"))
19
31
  end
20
32
  end
33
+
34
+ def to_executable_argset(base)
35
+ args = base.dup
36
+ args.clear_reference
37
+ args.options[:git] = @url
38
+ args.options[:branch] = @ref
39
+ Argset.new(:gem, *args.args_and_options)
40
+ end
21
41
  end
22
42
  end
@@ -0,0 +1,22 @@
1
+ module Envandle
2
+ def self.options!(args)
3
+ args.last.is_a?(Hash) ? args.pop : {}
4
+ end
5
+
6
+ def self.loc(level = 2)
7
+ /^(.+?):(\d+)(?::in `(.*)')?/ =~ caller(level, 1).first
8
+ Location.new($1, $2.to_i)
9
+ end
10
+
11
+ def self.pascal(s)
12
+ s.split("_").map{|i| i.capitalize}.join("")
13
+ end
14
+
15
+ def self.reference_key(group, name)
16
+ if group
17
+ "#{name}@#{group}"
18
+ else
19
+ name
20
+ end
21
+ end
22
+ end
data/lib/envandle/lib.rb CHANGED
@@ -1,14 +1,21 @@
1
+ require "open3"
2
+ require "thread"
1
3
  require "tmpdir"
4
+ require "yaml"
2
5
  require "envandle/version"
3
- require "envandle/as_reference"
6
+ require "envandle/helper"
7
+ require "envandle/exceptions"
8
+ require "envandle/as_context"
9
+ require "envandle/as_dsl"
4
10
  require "envandle/as_git_reference"
5
- require "envandle/bundle_dsl"
6
- require "envandle/gem"
7
- require "envandle/gemfile"
11
+ require "envandle/as_reference"
12
+ require "envandle/argset"
13
+ require "envandle/elements"
14
+ require "envandle/location"
8
15
  require "envandle/gemspec"
16
+ require "envandle/gemspec_cache"
9
17
  require "envandle/git"
10
18
  require "envandle/git_branch_reference"
11
- require "envandle/group_dsl"
12
19
  require "envandle/path_reference"
13
20
  require "envandle/shell"
14
21
  require "envandle/reference_cache"
@@ -0,0 +1,12 @@
1
+ class Location
2
+ def initialize(file, line)
3
+ @file = file
4
+ @line = line
5
+ end
6
+
7
+ attr_reader :file, :line
8
+
9
+ def to_s
10
+ "#{@file}:#{@line}"
11
+ end
12
+ end
@@ -2,18 +2,22 @@ module Envandle
2
2
  class PathReference
3
3
  extend AsReference
4
4
 
5
- def initialize(group, name, path)
5
+ def initialize(context, group, name, path)
6
+ @context = context
6
7
  @group = group
7
8
  @name = name
8
9
  @path = path
9
10
  end
10
11
 
11
- def to_gem(args, options)
12
- Gem.new(@group, @name, [], {path: @path})
13
- end
14
-
15
12
  def spec
16
13
  @spec ||= Gemspec.new(Gemspec.find_file(@path, name: @name))
17
14
  end
15
+
16
+ def to_executable_argset(base)
17
+ args = base.dup
18
+ args.clear_reference
19
+ args.options[:path] = @path
20
+ Argset.new(:gem, *args.args_and_options)
21
+ end
18
22
  end
19
23
  end
@@ -1,14 +1,11 @@
1
1
  module Envandle
2
2
  class ReferenceCache
3
- def self.key(group, name)
4
- if group
5
- "#{name}@#{group}"
6
- else
7
- name
8
- end
3
+ def initialize(context)
4
+ @context = context
9
5
  end
10
6
 
11
- def find(key, name)
7
+ def find(group, name)
8
+ key = Envandle.reference_key(group, name)
12
9
  paths[key] ||
13
10
  git_branches[key] ||
14
11
  paths[name] ||
@@ -49,7 +46,7 @@ module Envandle
49
46
  name = a[0].to_s.strip
50
47
  path = a[1..-1].join(":").to_s.strip
51
48
  raise "No gem path (#{env}): #{ENV[env]}" if path.empty?
52
- klass.new(*parse_group_and_name(env, name), path)
49
+ klass.new(@context, *parse_group_and_name(env, name), path)
53
50
  end
54
51
 
55
52
  def parse_git(klass, env, v)
@@ -63,7 +60,26 @@ module Envandle
63
60
  ref = url_and_ref[1].to_s.strip
64
61
  raise "No gem git url (#{env}): #{ENV[env]}" if url.empty?
65
62
  raise "No gem git ref/branch/tag (#{env}): #{ENV[env]}" if ref.empty?
66
- klass.new(*parse_group_and_name(env, name), url, ref)
63
+ klass.new(@context, *parse_group_and_name(env, name), url, ref)
64
+ end
65
+
66
+ def extract_executable_argsets(base, group, name, argsets, found = {})
67
+ key = Envandle.reference_key(group, name)
68
+ return true if found.key?(key)
69
+ found[key] = true
70
+ if ref = find(group, name)
71
+ ref.spec.runtime_dependencies.each do |i|
72
+ if ref2 = find(nil, i.name)
73
+ extract_executable_argsets base, nil, i.name, argsets, found
74
+ end
75
+ end
76
+ args = base.dup
77
+ args.args[0] = name
78
+ argsets << ref.to_executable_argset(args)
79
+ true
80
+ else
81
+ false
82
+ end
67
83
  end
68
84
  end
69
85
  end
@@ -1,6 +1,8 @@
1
1
  module Envandle
2
2
  def self.sh(cmd)
3
- system cmd, out: "/dev/null", err: "/dev/null"
4
- raise "Command error: #{cmd}" unless $?.success?
3
+ # output, status = Open3.capture2(cmd)
4
+ output, error, status = Open3.capture3(cmd)
5
+ raise "Command error: #{cmd}" unless status.success?
6
+ output
5
7
  end
6
8
  end
@@ -1,3 +1,3 @@
1
1
  module Envandle
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: envandle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mosop
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-14 00:00:00.000000000 Z
11
+ date: 2017-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -68,17 +68,31 @@ files:
68
68
  - bin/setup
69
69
  - envandle.gemspec
70
70
  - lib/envandle.rb
71
+ - lib/envandle/argset.rb
72
+ - lib/envandle/as_context.rb
73
+ - lib/envandle/as_dsl.rb
71
74
  - lib/envandle/as_git_reference.rb
72
75
  - lib/envandle/as_reference.rb
73
76
  - lib/envandle/binding.rb
74
- - lib/envandle/bundle_dsl.rb
75
- - lib/envandle/gem.rb
76
- - lib/envandle/gemfile.rb
77
+ - lib/envandle/elements.rb
78
+ - lib/envandle/elements/element.rb
79
+ - lib/envandle/elements/gem.rb
80
+ - lib/envandle/elements/gemfile.rb
81
+ - lib/envandle/elements/gemspec.rb
82
+ - lib/envandle/elements/git_source_block.rb
83
+ - lib/envandle/elements/group_block.rb
84
+ - lib/envandle/elements/illegal_element.rb
85
+ - lib/envandle/elements/illegals_and_unsupporteds.rb
86
+ - lib/envandle/elements/source.rb
87
+ - lib/envandle/elements/unsupported_element.rb
88
+ - lib/envandle/exceptions.rb
77
89
  - lib/envandle/gemspec.rb
90
+ - lib/envandle/gemspec_cache.rb
78
91
  - lib/envandle/git.rb
79
92
  - lib/envandle/git_branch_reference.rb
80
- - lib/envandle/group_dsl.rb
93
+ - lib/envandle/helper.rb
81
94
  - lib/envandle/lib.rb
95
+ - lib/envandle/location.rb
82
96
  - lib/envandle/path_reference.rb
83
97
  - lib/envandle/reference_cache.rb
84
98
  - lib/envandle/shell.rb
@@ -103,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
117
  version: '0'
104
118
  requirements: []
105
119
  rubyforge_project:
106
- rubygems_version: 2.5.1
120
+ rubygems_version: 2.5.2
107
121
  signing_key:
108
122
  specification_version: 4
109
123
  summary: A library for enabling Gemfiles to specify gem locations from environment
@@ -1,31 +0,0 @@
1
- module Envandle
2
- class BundleDsl
3
- def initialize(gemfile)
4
- @gemfile = gemfile
5
- end
6
-
7
- def gem(*args)
8
- @gemfile.gem nil, *args
9
- end
10
-
11
- def group(name)
12
- yield GroupDsl.new(@gemfile, name)
13
- end
14
-
15
- def gemspec(development_group: "development", path: nil, name: nil)
16
- development_group = development_group.to_s.strip
17
- raise "No gemspec's development group." if development_group.empty?
18
- name = name.to_s.strip if name
19
- raise "No gemspec's name." if name && name.empty
20
- path ||= Gemspec.find_file(@gemfile.dir, name: name)
21
- path = path.to_s.strip
22
- raise "No gemspec's path." if path.empty?
23
- spec = Gemspec.new(path)
24
- @gemfile.gem nil, spec.name, path: "."
25
- spec.dependencies.each do |i|
26
- group = i.type == :development ? development_group : nil
27
- @gemfile.gem group, i.name, *i.requirements_list
28
- end
29
- end
30
- end
31
- end
data/lib/envandle/gem.rb DELETED
@@ -1,20 +0,0 @@
1
- module Envandle
2
- class Gem
3
- def initialize(group, name, args, options)
4
- @group = group
5
- @name = name
6
- @args = args
7
- @options = options
8
- end
9
-
10
- def args
11
- h = @group ? {group: @group} : {}
12
- h.merge! @options
13
- if h.empty?
14
- [@name, *@args]
15
- else
16
- [@name, *@args, h]
17
- end
18
- end
19
- end
20
- end
@@ -1,48 +0,0 @@
1
- module Envandle
2
- class Gemfile
3
- def initialize(path, binding)
4
- @path = path
5
- @binding = binding
6
- end
7
-
8
- def dir
9
- @dir ||= File.dirname(@path)
10
- end
11
-
12
- def gems
13
- @gems ||= {}
14
- end
15
-
16
- def references
17
- @references ||= ReferenceCache.new
18
- end
19
-
20
- def append(group, name, args, options)
21
- key = ReferenceCache.key(group, name)
22
- gems[key] || begin
23
- if ref = references.find(key, name)
24
- gem = ref.to_gem(args, options)
25
- gems[key] = gem
26
- ref.spec.runtime_dependencies.each do |i|
27
- append nil, i.name, [], {}
28
- end
29
- @binding.gem *gem.args
30
- else
31
- gems[key] = gem = Gem.new(group, name, args, options)
32
- @binding.gem *gem.args
33
- end
34
- end
35
- end
36
-
37
- def gem(group, *args)
38
- h = args.last.is_a?(Hash) ? args.pop : {}
39
- options = {}
40
- h.each do |k, v|
41
- options[k.to_s.to_sym] = v
42
- end
43
- name = args.shift.to_s.strip
44
- raise "No gem name." if name.empty?
45
- append group, name, args, options
46
- end
47
- end
48
- end
@@ -1,14 +0,0 @@
1
- module Envandle
2
- class GroupDsl
3
- def initialize(world, name)
4
- @world = world
5
- name = name.to_s.strip
6
- raise "No group name." if name.empty?
7
- @name = name
8
- end
9
-
10
- def gem(*args)
11
- world.gem @name, *args
12
- end
13
- end
14
- end