envandle 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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