starenv 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d259f537e28341d2ba00408a875e0267b7874cca
4
+ data.tar.gz: 8e1a771716fb1535fd133e01f26202a0d92f796d
5
+ SHA512:
6
+ metadata.gz: 5e546387c1e7ac165fa2c6bc91509f8b8b27b30655553b22e82a65e90872b104b7ac0234ffa2df94cf4ea64b0c99333aa0a792afc4bfb9683f0b1537d1060bb8
7
+ data.tar.gz: 487ef54e34937b2671cff7c9f21feba0307bcbc371787f6ee80e5de782db4202becf7db029d706faf1365510759550f6c694c8cfedb092bd6221d539a9da3c92
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ envs/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in starenv.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,25 @@
1
+ > **Copyright (c) 2015 Chris Keele**
2
+
3
+ MIT License
4
+ -----------
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ *
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ *
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ Starenv
2
+ =======
3
+
4
+ > **Load and manage suites of environment variables.**
5
+
6
+
7
+
8
+ Synopsis
9
+ --------
10
+
11
+ One of the tenants of building [12-factor apps](http://12factor.net/) is loading your [configuration from the environment](http://12factor.net/config).
12
+
13
+ However, developing complicated applications, entirely configured from the environment, comes with some pitfalls:
14
+
15
+ 1. *Environment variables aren't easy to manage*
16
+
17
+ 1. *Environment variables aren't easy to reproduce*
18
+
19
+ 1. *Environment variables aren't easy to reason about*
20
+
21
+ 1. *Environment variables aren't easy to tweak*
22
+
23
+ Starenv was created to alleviate these problems.
24
+
25
+ 1. *Starenv supports multiple, project-defined env files.*
26
+
27
+ 1. *Starenv allows declaring dependencies files.*
28
+
29
+ 1. *Starenv allows conditionally and contextually loading files.*
30
+
31
+ 1. *Starenv comes with rake tasks for managing and documenting environment variables.*
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ desc 'Open a pry console preloaded with this library'
4
+ task console: 'console:pry'
5
+
6
+ namespace :console do
7
+
8
+ task :pry do
9
+ sh 'bundle exec pry -I lib -r starenv.rb'
10
+ end
11
+
12
+ task :irb do
13
+ sh 'bundle exec irb -I lib -r starenv.rb'
14
+ end
15
+
16
+ end
17
+
18
+ require_relative 'lib/starenv/tasks'
data/bin/rake ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
6
+
7
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
8
+
9
+ load Gem.bin_path('rake', 'rake')
10
+
11
+ require 'rake'
12
+ Rake.application.run
@@ -0,0 +1,85 @@
1
+ require 'starenv/results'
2
+
3
+ class EnvFile < Struct.new(:name, :dependencies, :pattern, :hook)
4
+
5
+ def load
6
+ (hook || default_hook).call self do
7
+ Dotenv.load(filename).tap do |results|
8
+ puts info results
9
+ end
10
+ end
11
+ end
12
+
13
+ def filename
14
+ format pattern, name
15
+ end
16
+
17
+ alias_method :to_s, :filename
18
+
19
+ def info(results)
20
+ longest = results.keys.group_by(&:size).max
21
+ length = longest.nil? ? 0 : longest.first
22
+ applied, ignored = results.partition do |key, value|
23
+ ENV[key] == value
24
+ end
25
+ [
26
+ Results.for(:applied).new(self, applied, length),
27
+ Results.for(:ignored).new(self, ignored, length),
28
+ ].map(&:to_s).compact.push("\n").join("\n")
29
+ end
30
+
31
+ private
32
+
33
+ @@default_hook = -> file, &loader { loader.call }
34
+
35
+ def default_hook
36
+ @@default_hook
37
+ end
38
+
39
+ module Utils
40
+
41
+ def without_leading_comments(file)
42
+ file.each_line.drop_while do |line|
43
+ comment? line
44
+ end
45
+ end
46
+
47
+ def comment?(line)
48
+ line.start_with? '#'
49
+ end
50
+
51
+ def variable(line)
52
+ line.match(/^\s*?(?<name>\b.*\b)=(?<value>\b\S*\b)?\s*?$/)
53
+ end
54
+
55
+ end
56
+
57
+ class Template < self
58
+
59
+ include Utils
60
+
61
+ attr_reader :content
62
+
63
+ def initialize(name, pattern = Starenv.pattern, content = [])
64
+ @content = content
65
+ super name, [], pattern, nil
66
+ end
67
+
68
+ def parse
69
+ File.open(filename) do |lines|
70
+ yield without_leading_comments lines
71
+ end
72
+ end
73
+
74
+ def write
75
+ File.open(filename, 'w') do |file|
76
+ content.each do |line|
77
+ line = yield line
78
+ file.puts line if line
79
+ end
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,50 @@
1
+ require 'delegate'
2
+
3
+ module Starenv
4
+ class Environment
5
+
6
+ attr_reader :variables, :applied, :ignored
7
+
8
+ def initialize(source = nil)
9
+ @source = source ? source : ENV
10
+ @variables, @applied, @ignored = {}
11
+ end
12
+
13
+ def [] key
14
+ @source[key].tap do |value|
15
+ @variables[key] ||= Variable.new(key, value) if value
16
+ end
17
+ end
18
+
19
+ def []= key, value
20
+ @source.store(key, value.to_s).tap do |value|
21
+ @variables[key] = Variable.new(key, value)
22
+ end
23
+ end
24
+
25
+ def apply(hash)
26
+ self.tap do |env|
27
+ hash.each do |key, value|
28
+ self[key] ||= value
29
+ end
30
+ end
31
+ end
32
+
33
+ def respond_to_missing?(method)
34
+ @source.respond_to?(method) or super
35
+ end
36
+
37
+ def method_missing(method, *args)
38
+ if @source.respond_to? method
39
+ if block_given?
40
+ @source.send method, *args, &Proc.new
41
+ else
42
+ @source.send method, *args
43
+ end
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,35 @@
1
+ require 'starenv/file'
2
+
3
+ module Starenv
4
+ class File < ::File
5
+ class Node < Struct.new(:name, :dependencies, :hook)
6
+
7
+ attr_reader :environment
8
+
9
+ def initialize(name, dependencies = [], hook = nil)
10
+ super name, dependencies, hook
11
+ end
12
+
13
+ def load
14
+ tap do
15
+ unless loaded?
16
+ (hook || default_hook).call self do
17
+ File.parse(name).environment
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ def loaded?
24
+ !!file
25
+ end
26
+
27
+ private
28
+
29
+ def default_hook
30
+ @@default_hook ||= -> file, &loader { loader.call }
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ require 'starenv/environment'
2
+ require 'starenv/variable'
3
+
4
+ module Starenv
5
+ class File < ::File
6
+ class Parser
7
+
8
+ attr_accessor :lines
9
+
10
+ def initialize(lines)
11
+ @lines = lines
12
+ end
13
+
14
+ def call
15
+ Environment.new(
16
+ Hash[
17
+ lines.map(&:strip).select do |line|
18
+ line =~ Variable.line
19
+ end.compact.map do |line|
20
+ variable = Variable.from line
21
+ [ variable.name, variable ]
22
+ end
23
+ ]
24
+ )
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ require 'tsort'
2
+
3
+ require 'starenv/file/node'
4
+
5
+ module Starenv
6
+ class File < ::File
7
+ class Set < Hash
8
+
9
+ include TSort
10
+
11
+ alias_method :tsort_each_node, :each_key
12
+
13
+ def tsort_each_child(node)
14
+ fetch(node).dependencies.each(&Proc.new)
15
+ end
16
+
17
+ def add(name, dependencies, hook)
18
+ store name, Node.new(name, Array(dependencies).flatten, hook)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ module Starenv
2
+ class File < ::File
3
+ class Template < self
4
+
5
+ def initialize(name, mode = 'r+', *args)
6
+ super name, mode, *args
7
+ end
8
+
9
+ attr_reader :files
10
+
11
+ def header
12
+ %r{^#\sfile:\s(\w+).*?$}mi
13
+ end
14
+
15
+ def parse
16
+ tap do
17
+ unless parsed?
18
+ require 'pry'; binding.pry
19
+ @files = Hash[
20
+ read.split(header).drop(1).each_slice(2).map do |key, value|
21
+ [ key.to_sym, Parser.new(value.strip.lines).call ]
22
+ end
23
+ ]
24
+ end
25
+ end
26
+ end
27
+
28
+ def parsed?
29
+ !!files
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,133 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+
4
+ require 'starenv/file/parser'
5
+
6
+ module Starenv
7
+ class File < ::File
8
+
9
+ class << self
10
+
11
+ def parse(name, *args)
12
+ open name, *args, &:parse
13
+ end
14
+
15
+ def touch(name, *args)
16
+ new(name, *args).touch(*args)
17
+ end
18
+
19
+ end
20
+
21
+ attr_reader :name, :filename, :environment
22
+
23
+ def initialize(name, mode = 'r', *args)
24
+ @name = name
25
+ @filename = Pathname.new Starenv.format @name
26
+ super @filename, mode, *args
27
+ end
28
+
29
+ def parse
30
+ tap do |file|
31
+ unless parsed?
32
+ @environment = Parser.new(each_line).call
33
+ end
34
+ end
35
+ end
36
+
37
+ def parsed?
38
+ !!environment
39
+ end
40
+
41
+ def touch(*args)
42
+ tap do |file|
43
+ FileUtils.mkpath file.filename.dirname, *args
44
+ FileUtils.touch file.filename, *args
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+
51
+ # class EnvFile < Struct.new(:name, :dependencies, :pattern, :hook)
52
+ #
53
+ # def load
54
+ # (hook || default_hook).call self do
55
+ # Dotenv.load(filename).tap do |results|
56
+ # puts info results
57
+ # end
58
+ # end
59
+ # end
60
+ #
61
+ # def filename
62
+ # format pattern, name
63
+ # end
64
+ #
65
+ # alias_method :to_s, :filename
66
+ #
67
+ # def info(results)
68
+ # longest = results.keys.group_by(&:size).max
69
+ # length = longest.nil? ? 0 : longest.first
70
+ # applied, ignored = results.partition do |key, value|
71
+ # ENV[key] == value
72
+ # end
73
+ # [
74
+ # Results.for(:applied).new(self, applied, length),
75
+ # Results.for(:ignored).new(self, ignored, length),
76
+ # ].map(&:to_s).compact.push("\n").join("\n")
77
+ # end
78
+ #
79
+ # private
80
+ #
81
+ # @@default_hook = -> file, &loader { loader.call }
82
+ #
83
+ # def default_hook
84
+ # @@default_hook
85
+ # end
86
+ #
87
+ # module Utils
88
+ #
89
+ # def without_leading_comments(file)
90
+ # file.each_line.drop_while do |line|
91
+ # comment? line
92
+ # end
93
+ # end
94
+ #
95
+ # def comment?(line)
96
+ # line.start_with? '#'
97
+ # end
98
+ #
99
+ # def variable(line)
100
+ # line.match(/^\s*?(?<name>\b.*\b)=(?<value>\b\S*\b)?\s*?$/)
101
+ # end
102
+ #
103
+ # end
104
+ #
105
+ # class Template < self
106
+ #
107
+ # include Utils
108
+ #
109
+ # attr_reader :content
110
+ #
111
+ # def initialize(name, pattern = Starenv.pattern, content = [])
112
+ # @content = content
113
+ # super name, [], pattern, nil
114
+ # end
115
+ #
116
+ # def parse
117
+ # File.open(filename) do |lines|
118
+ # yield without_leading_comments lines
119
+ # end
120
+ # end
121
+ #
122
+ # def write
123
+ # File.open(filename, 'w') do |file|
124
+ # content.each do |line|
125
+ # line = yield line
126
+ # file.puts line if line
127
+ # end
128
+ # end
129
+ # end
130
+ #
131
+ # end
132
+ #
133
+ # end
@@ -0,0 +1,49 @@
1
+ class Results < Struct.new(:file, :variables, :name_length)
2
+
3
+ class << self
4
+ def for(type)
5
+ const_get type.to_s.capitalize
6
+ end
7
+ end
8
+
9
+ def display
10
+ formatted(variables).unshift(header).join("\n") unless variables.empty?
11
+ end
12
+
13
+ def to_s
14
+ display or ''
15
+ end
16
+
17
+ private
18
+
19
+ def formatted(variables)
20
+ variables.map do |name, value|
21
+ format_variable name, value
22
+ end
23
+ end
24
+
25
+ class Applied < self
26
+
27
+ def header
28
+ "Applied variables from #{file}:"
29
+ end
30
+
31
+ def format_variable(name, value)
32
+ format " %-#{name_length}s => %s", name, value
33
+ end
34
+
35
+ end
36
+
37
+ class Ignored < self
38
+
39
+ def header
40
+ 'Ignored already set variables:'
41
+ end
42
+
43
+ def format_variable(name, value)
44
+ format " %-#{name_length}s => %s\n %-#{length-1}s => %s", name, value, 'already', ENV[name]
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,112 @@
1
+ require 'rake' unless defined? Rake
2
+
3
+ require 'highline'
4
+
5
+ require 'starenv'
6
+ require 'starenv/file/template'
7
+
8
+ module Starenv
9
+ module Tasks
10
+
11
+ extend self
12
+ extend Rake::DSL
13
+
14
+ task starenv: 'starenv:load'
15
+
16
+ namespace :starenv do
17
+
18
+ task :require do
19
+ require 'starenv'
20
+ end
21
+
22
+ task load: :require do
23
+ Starenv.load
24
+ end
25
+
26
+ task dry_run: :require do
27
+ Starenv.load Hash.new
28
+ end
29
+
30
+ end
31
+
32
+ namespace :envs do
33
+
34
+ desc "Creates starenv files according to template file."
35
+ task :init, %i[template] => %i[starenv] do |t, args|
36
+ init_from args.with_defaults(template: :example)
37
+ end
38
+ #
39
+ # desc "Adds a new environment variable to starenv."
40
+ # task new: :starenv, %i[name value file] do |t, args|
41
+ # new_variable args.with_defaults(file: Starenv.files.tsort.last)
42
+ # end
43
+ #
44
+ # desc "Sets a starenv variable."
45
+ # task set: :starenv, %i[name value file] do |t, args|
46
+ # set_variable args.with_defaults(file: Starenv.files.tsort.first)
47
+ # end
48
+ #
49
+ # desc "Shows the value of a starenv variable."
50
+ # task get: :starenv, %i[name file] do |t, args|
51
+ # get_variable args.with_defaults(file: Starenv.files.tsort.first)
52
+ # end
53
+
54
+ end
55
+
56
+ def init_from(template: :example, noop: false, verbose: true)
57
+ File::Template.touch(template, noop: noop, verbose: verbose).parse.files.each do |file, env|
58
+ require 'pry'; binding.pry
59
+ end
60
+ end
61
+
62
+ # def init_from(template: :example, pattern: Starenv.pattern)
63
+ # EnvFile::Template.new(file, pattern).parse do |lines|
64
+ # chunk_into_files(lines).each do |file, lines|
65
+ # file = EnvFile::Template.new(file, pattern, lines)
66
+ # if not File.exists?(file.filename) or console.agree(console.color("Do you want to override your current #{file.filename}?", [:bold, :yellow]))
67
+ # console.say "Generating #{file.filename}..."
68
+ # file.write do |line|
69
+ # line.tap do |line|
70
+ # if variable = file.variable(line) and not variable[:value]
71
+ # line[-1] = console.ask("Enter a value for #{variable[:name]}:")
72
+ # end
73
+ # end
74
+ # end
75
+ # end
76
+ # end
77
+ # end
78
+ # end
79
+
80
+ def new_variable(name:, value:, file: Starenv.files.tsort.last || :core)
81
+ file = EnvFile.new(file, [], pattern, nil)
82
+ end
83
+
84
+ def set_variable(name, value:, file: Starenv.files.tsort.last || :core)
85
+ file = EnvFile.new(file, [], pattern, nil)
86
+ end
87
+
88
+ def get_variable(name, value:, file: Starenv.files.tsort.last || :core)
89
+ file = EnvFile.new(file, [], pattern, nil)
90
+ end
91
+
92
+ private
93
+
94
+ def console(*args)
95
+ @@console ||= HighLine.new(*args)
96
+ end
97
+
98
+ def chunk_into_files(lines)
99
+ lines.reduce({initial: []}) do |files, line|
100
+ if file = line[/^#\s+?FILE:\s+?(?<file>\w+)/, :file]
101
+ previous = files[files.keys.last]
102
+ files[file] = []
103
+ files[file] << previous.pop if previous
104
+ files.delete(:initial)
105
+ end
106
+ files[files.keys.last] << line
107
+ files
108
+ end
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,39 @@
1
+ module Starenv
2
+ class Variable < Struct.new(:name, :value, :default)
3
+
4
+ class << self
5
+
6
+ def line
7
+ %r{
8
+ \A
9
+ (?:export\s+)? # optional export
10
+ ([\w\.]+) # key
11
+ (?:\s*=\s*|:\s+?) # separator
12
+ ( # optional value begin
13
+ '(?:\'|[^'])*' # single quoted value
14
+ | # or
15
+ "(?:\"|[^"])*" # double quoted value
16
+ | # or
17
+ [^#\n]+ # unquoted value
18
+ )? # value end
19
+ (?:\s*\#.*)? # optional comment
20
+ \z
21
+ }x
22
+ end
23
+
24
+ def from(input)
25
+ new *line.match(input).captures
26
+ end
27
+
28
+ end
29
+
30
+ def initialize(name, value, default = nil)
31
+ super name, value, default
32
+ end
33
+
34
+ def to_s
35
+ value.to_s
36
+ end
37
+
38
+ end
39
+ end
data/lib/starenv.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'starenv/file/set'
2
+
3
+ module Starenv
4
+
5
+ extend self
6
+
7
+ def format(name)
8
+ Kernel.format pattern, name
9
+ end
10
+
11
+ def pattern
12
+ @@pattern ||= default_pattern
13
+ end
14
+
15
+ def pattern= string
16
+ @@pattern = string.to_s
17
+ end
18
+
19
+ def files
20
+ @@env_files ||= File::Set.new
21
+ end
22
+
23
+ def register(names, dependencies: [])
24
+ Array(names).flatten.each do |name|
25
+ files.add name, dependencies, block_given? ? Proc.new : nil
26
+ end
27
+ end
28
+
29
+ def load(env = nil)
30
+ files.tsort.reduce(Environment.new(env)) do |environment, node|
31
+ environment.apply files[node].load.environment
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def default_pattern
38
+ 'envs/%s.env'
39
+ end
40
+
41
+ end
data/starenv.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "starenv"
7
+ spec.version = '0.0.1'
8
+ spec.authors = ["Chris Keele"]
9
+ spec.email = ["dev@chriskeele.com"]
10
+ spec.summary = 'Load and manage suites of environment variables.'
11
+ spec.description = "Declare multiple '.env' files, set up dynamic load orders between them, and use rake tasks to keep them up to date and documented."
12
+ spec.homepage = "https://github.com/christhekeele/starenv"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ # spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.required_ruby_version = '~> 2.1'
21
+
22
+ spec.add_runtime_dependency "rake"
23
+ spec.add_runtime_dependency "highline"
24
+
25
+ spec.add_development_dependency "bundler", "> 1.3"
26
+ spec.add_development_dependency "pry"
27
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: starenv
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Keele
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: highline
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
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
+ description: Declare multiple '.env' files, set up dynamic load orders between them,
70
+ and use rake tasks to keep them up to date and documented.
71
+ email:
72
+ - dev@chriskeele.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - LICENSE.md
80
+ - README.md
81
+ - Rakefile
82
+ - bin/rake
83
+ - lib/starenv.rb
84
+ - lib/starenv/env_file.rb
85
+ - lib/starenv/environment.rb
86
+ - lib/starenv/file.rb
87
+ - lib/starenv/file/node.rb
88
+ - lib/starenv/file/parser.rb
89
+ - lib/starenv/file/set.rb
90
+ - lib/starenv/file/template.rb
91
+ - lib/starenv/results.rb
92
+ - lib/starenv/tasks.rb
93
+ - lib/starenv/variable.rb
94
+ - starenv.gemspec
95
+ homepage: https://github.com/christhekeele/starenv
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '2.1'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.2.2
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: Load and manage suites of environment variables.
119
+ test_files: []