starenv 0.0.1

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 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: []