figs 0.1.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "aruba", "~> 0.5"
7
+ gem "coveralls", "~> 0.7", require: false
8
+ gem "rspec", "~> 2.14"
9
+ end
10
+ gem 'git'
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ ## Figs
2
+ [![Gem Version](https://badge.fury.io/rb/figs.png)](http://badge.fury.io/rb/figs)
3
+ [![Build Status](https://travis-ci.org/NYULibraries/figs.png?branch=master)](https://travis-ci.org/NYULibraries/figs)
4
+ [![Code Climate](https://codeclimate.com/github/NYULibraries/figs.png)](https://codeclimate.com/github/NYULibraries/figs)
5
+ [![Coverage Status](https://coveralls.io/repos/NYULibraries/figs/badge.png)](https://coveralls.io/r/NYULibraries/figs)
6
+ [![Dependency Status](https://gemnasium.com/NYULibraries/figs.png)](https://gemnasium.com/NYULibraries/figs)
7
+
8
+ Railsless, herokuless, configurable, barebones figaro with a knack of using git repos for configuration files.
9
+
10
+ Simple app configuration
11
+
12
+ ## What is this for?
13
+
14
+ Figs is for configuring apps, especially open source apps, much like Figaro. Whereas Figaro is great in that it works seamlessly with Rails 3 and 4, Figs also works with non Rails apps providing the same great ENV support, although in a slightly different way.
15
+
16
+ However, much like Figaro, Figs allows you to Open Source your app while keeping private things private.
17
+
18
+ ## How does it work?
19
+
20
+ Figs is identical to Figaro in every way barring a few key differences. It uses `ENV` to store any string key-value pairs. However, sometimes its necessary to store more complex objects, such as arrays. `ENV` doesn't allow for objects, so we provide a souped-up wrapper called `Figs::Env` for this purpose! All keys are converted to strings and all non-string values are marshalled and stored in `ENV`, you can demarshall them yourself using `ENV` or rely on `Figs::Env.key_name` to do it fast and easy!
21
+
22
+ ## Example.
23
+
24
+ Add Figs to your Gemfile then `bundle` command to install it:
25
+
26
+ ```ruby
27
+ gem "figs"
28
+ ```
29
+
30
+ Then you'll have to figsify your project so Figs can find where you keep your environment variables. If a location is not specified, a template will be created in the root directory as application.yml.
31
+
32
+ ```
33
+ figsify
34
+ ```
35
+ or
36
+
37
+ ```
38
+ figsify config/settings1.yml config/settings2.yml config/settings3.yml
39
+ ```
40
+ And finally
41
+
42
+ ```
43
+ figsify git@github.com:GITHUBNAME/REPONAME.git filename1.yml config/filename2.yml
44
+ ```
45
+
46
+ Now Figs will know where to find your environment vars!
47
+
48
+ __IMPORTANT:__ The order in which you load your files matters, as the environment variables perform a merge on the hashes, the right hand arguments taking precedence.
49
+
50
+ Then in ruby
51
+
52
+ ```ruby
53
+ Figs.load()
54
+
55
+ Settings.secret = ENV["SECRET"]
56
+ # OR
57
+ Settings.servers = Figs.env["server"]
58
+ ```
59
+
60
+ ## Thank you!
61
+
62
+ Figs was made possible by the kind folks at [Figaro](https://github.com/laserlemon/figaro)
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/figsify CHANGED
@@ -3,7 +3,9 @@
3
3
  require "figs/install"
4
4
 
5
5
  if ARGV.length > 1
6
- abort "Too many arguments; please specify only the yaml file location/git repo."
6
+ join = ARGV.join(",")
7
+ ARGV.clear
8
+ ARGV.push join
7
9
  end
8
10
 
9
11
  ARGV.push "install[#{ARGV.pop}]"
@@ -0,0 +1,124 @@
1
+ require "erb"
2
+ require "yaml"
3
+
4
+ require "figs/error"
5
+ require "figs/env"
6
+ require "figs/git_handler"
7
+
8
+ module Figs
9
+ class Application
10
+ FIGS_ENV_PREFIX = "_FIGS_"
11
+
12
+ include Enumerable
13
+
14
+ attr_writer :stage, :path
15
+
16
+ def initialize(options = {})
17
+ @figfile = options[:file]
18
+ @stage = options[:stage]
19
+ load_path
20
+ end
21
+
22
+ def locations
23
+ figfile["locations"]
24
+ end
25
+
26
+ def load_path
27
+ if figfile["method"].eql? "git"
28
+ @path = path_from_git(figfile["repo"], figfile["locations"])
29
+ else
30
+ @path = figfile["locations"]
31
+ end
32
+ end
33
+
34
+ def path_from_git(git_path, filenames = nil)
35
+ if(locations.is_a?(Array))
36
+ Figs::GitHandler.location(git_path, filenames)
37
+ else
38
+ Figs::GitHandler.location(git_path, @stage)
39
+ end
40
+ end
41
+
42
+ def figfile
43
+ (@figfile || default_figfile)
44
+ end
45
+
46
+ def path
47
+ (@path || default_path)
48
+ end
49
+
50
+ def stage
51
+ (@stage || default_stage).to_s
52
+ end
53
+
54
+ def configuration
55
+ global_configuration.merge(stage_configuration)
56
+ end
57
+
58
+ def load
59
+ each do |key, value|
60
+ set(key, value) unless skip?(key)
61
+ end
62
+ ensure
63
+ Figs::GitHandler.clear_temp_files
64
+ end
65
+
66
+ def env
67
+ Figs::ENV
68
+ end
69
+
70
+ def each(&block)
71
+ configuration.each(&block)
72
+ end
73
+
74
+ private
75
+
76
+ def default_path
77
+ raise NotImplementedError
78
+ end
79
+
80
+ def default_stage
81
+ "test"
82
+ end
83
+
84
+ def default_figfile
85
+ raise NotImplementedError
86
+ end
87
+
88
+ def raw_configuration
89
+ (@parsed ||= Hash.new { |hash, path| hash[path] = parse(path) })[path]
90
+ end
91
+
92
+ def parse_path(path)
93
+ File.exist?(path) && YAML.load(ERB.new(File.read(path)).result) || {}
94
+ end
95
+
96
+ def parse(paths)
97
+ parse = {}
98
+ paths.is_a?(Array) ? paths.each { |path| parse.merge!(parse_path(path)) } : parse.merge!(parse_path(paths))
99
+ parse
100
+ end
101
+
102
+ def global_configuration
103
+ raw_configuration.reject { |key, value| key.to_s.eql?(stage) && value.is_a?(Hash) }
104
+ end
105
+
106
+ def stage_configuration
107
+ raw_configuration.fetch(stage) { {} }
108
+ end
109
+
110
+ def set(key, value)
111
+ # FigsFigs::ENV.set_array(key, value) unless !value.is_a?(Array)
112
+ Figs::ENV[key] = value
113
+ Figs::ENV[FIGS_ENV_PREFIX + key.to_s] = value
114
+ end
115
+
116
+ def skip?(key)
117
+ Figs::ENV.key?(key.to_s) && !Figs::ENV.key?(FIGS_ENV_PREFIX + key.to_s)
118
+ end
119
+
120
+ def non_string_configuration!(value)
121
+ warn "WARNING: Use strings for Fig configuration. #{value.inspect} was converted to #{value.to_s.inspect}."
122
+ end
123
+ end
124
+ end
data/lib/figs/env.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'hashie'
2
+ module Figs
3
+ module ENV
4
+ extend self
5
+
6
+ def env
7
+ @env ||= ::ENV
8
+ end
9
+
10
+ def set(key,value)
11
+ env[key.to_s] = value.is_a?(String) ? value : YAML::dump(value)
12
+ end
13
+
14
+ def [](key)
15
+ return demarshall(env[key.to_s])
16
+ end
17
+
18
+ def []=(key,value)
19
+ set(key, value)
20
+ end
21
+
22
+ def demarshall(value)
23
+ value.nil? ? nil : YAML::load(value)
24
+ end
25
+
26
+ def method_missing(method, *args, &block)
27
+ if matches_env?(method) then return env.send(method, *args, &block) end
28
+
29
+ key, punctuation = extract_key_from_method(method)
30
+ _, value = env.detect { |k, _| k.upcase == key }
31
+
32
+ value = demarshall(value)
33
+
34
+ case punctuation
35
+ when "!" then value || missing_key!(key)
36
+ when "?" then !!value
37
+ when nil then value
38
+ else super
39
+ end
40
+ end
41
+
42
+ def extract_key_from_method(method)
43
+ method.to_s.upcase.match(/^(.+?)([!?=])?$/).captures
44
+ end
45
+
46
+ def missing_key!(key)
47
+ raise MissingKey.new("Missing required Figaro configuration key #{key.inspect}.")
48
+ end
49
+
50
+ def respond_to?(method, *)
51
+ return true if matches_env?(method)
52
+ key, punctuation = extract_key_from_method(method)
53
+
54
+ case punctuation
55
+ when "!" then env.keys.any? { |k| k.upcase == key } || super
56
+ when "?", nil then true
57
+ else super
58
+ end
59
+ end
60
+
61
+ def matches_env?(method)
62
+ env.respond_to?(method)
63
+ end
64
+ end
65
+ end
data/lib/figs/error.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Figs
2
+ class Error < StandardError; end
3
+ class MissingKey < Error; end
4
+ end
@@ -0,0 +1,14 @@
1
+ module Figs
2
+ class Figfile
3
+ attr_reader :locations, :method, :repo
4
+ def initialize(*args)
5
+ @repo = args.shift if args.first.downcase.end_with?(".git")
6
+ @locations = args
7
+ @method = @repo.nil? ? "path" : "git"
8
+ end
9
+
10
+ def [](key)
11
+ send key
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,49 @@
1
+ require "git"
2
+
3
+ module Figs
4
+ module GitHandler
5
+ extend self
6
+ TMP_GIT_DIR = "tmp/figs/"
7
+
8
+ def location(gitpath, filenames)
9
+ @temp_files = []
10
+ git_clone gitpath
11
+ temp_filenames(([]<< filenames).flatten)
12
+ rescue
13
+ clear_tmp_dir
14
+ clear_temp_files
15
+ end
16
+
17
+ def clear_temp_files
18
+ return unless !@temp_files.nil?
19
+ @temp_files.each { |temp_file| temp_file.close temp_file.unlink }
20
+ end
21
+
22
+ private
23
+
24
+ def temp_filenames(filenames)
25
+ temp_files = []
26
+ filenames.each { |filename| temp_files << copy_to_temp_files(filename) }
27
+ clear_tmp_dir
28
+ temp_files
29
+ end
30
+
31
+ def copy_to_temp_files(filename)
32
+ temp_file = Tempfile.new("#{filename}")
33
+ temp_file.open
34
+ temp_file.write(File.open("#{TMP_GIT_DIR}#{filename}").read)
35
+ temp_file.flush
36
+ @temp_files << temp_file
37
+ temp_file.path
38
+ end
39
+
40
+ def git_clone(gitpath)
41
+ clear_tmp_dir
42
+ ::Git.clone gitpath, TMP_GIT_DIR
43
+ end
44
+
45
+ def clear_tmp_dir
46
+ FileUtils.rm_rf TMP_GIT_DIR
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,28 @@
1
+ require "erb"
2
+ require "yaml"
3
+
4
+ require "figs/error"
5
+ require 'rake'
6
+
7
+
8
+
9
+ module Figs
10
+ class Install < Rake::Application
11
+
12
+ def initialize
13
+ super
14
+
15
+ @name = "figs"
16
+ @rakefiles = [File.expand_path(File.join(File.dirname(__FILE__),'tasks/install.rake'))]
17
+ end
18
+
19
+ def run
20
+ Rake.application = self
21
+ super
22
+ end
23
+
24
+ def default_task_name
25
+ "install"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ require 'erb'
2
+ require 'pathname'
3
+ require 'figs/figfile'
4
+ desc 'Install Fig'
5
+ task :install do |task, args|
6
+ base_dir = Pathname.new('.')
7
+ locations = args.extras.empty? ? "application.yml" : args.extras
8
+ figfile = Figs::Figfile.new(*locations)
9
+
10
+ create_figfile base_dir, figfile
11
+ create_non_existent_yaml(figfile.locations) if figfile.method.eql?("path")
12
+
13
+ puts "[Done] Enjoy your figs sir!"
14
+ end
15
+
16
+ def create_figfile(base_dir, figfile)
17
+ puts "Figsifying #{base_dir}/ ..."
18
+ file = base_dir.join('Figfile')
19
+ File.open(file, 'w+') do |f|
20
+ f.write(figfile.to_yaml)
21
+ end
22
+ end
23
+
24
+ def create_non_existent_yaml(locations)
25
+ locations.each do |file|
26
+ if !File.exists?(file)
27
+ puts "[Add] #{file} does not exist, creating."
28
+ application_yml = File.expand_path("../../templates/application.yml", __FILE__)
29
+ File.open(file, 'w+') do |f|
30
+ f.write(ERB.new(File.read(application_yml)).result(binding))
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ # Add application configuration variables here, as shown below.
2
+ #
3
+ # PUSHER_APP_ID: "2954"
4
+ # PUSHER_KEY: 7381a978f7dd7f9a1117
5
+ # PUSHER_SECRET: abdc3b896a0ffb85d373
6
+ # STRIPE_API_KEY: EdAvEPVEC3LuaTg5Q3z6WbDVqZlcBQ8Z
7
+ # STRIPE_PUBLIC_KEY: pk_BRgD57O8fHja9HxduJUszhef6jCyS
@@ -0,0 +1,3 @@
1
+ module Figs
2
+ VERSION = "1.2.1"
3
+ end
data/lib/figs.rb ADDED
@@ -0,0 +1,31 @@
1
+ require "figs/application"
2
+ require "figs/env"
3
+ require "figs/figfile"
4
+
5
+ module Figs
6
+ extend self
7
+
8
+ attr_writer :backend, :application
9
+
10
+ def env
11
+ application.env
12
+ end
13
+
14
+ def backend
15
+ @backend ||= Figs::Application
16
+ end
17
+
18
+ def application(options = {})
19
+ @application ||= backend.new({:file => figfile, :stage => options[:stage]})
20
+ end
21
+
22
+ def load(options = {})
23
+ application({:stage => options[:stage]}).load
24
+ end
25
+
26
+ private
27
+
28
+ def figfile
29
+ @figfile ||=YAML.load(ERB.new(File.read('Figfile')).result)
30
+ end
31
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: figs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-11 00:00:00.000000000 Z
12
+ date: 2014-03-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -43,6 +43,22 @@ dependencies:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
45
  version: 2.0.5
46
+ - !ruby/object:Gem::Dependency
47
+ name: git
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.2.6
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.2.6
46
62
  description: Simple app configuration using ENV and YAML files
47
63
  email: hab278@nyu.edu
48
64
  executables:
@@ -50,7 +66,20 @@ executables:
50
66
  extensions: []
51
67
  extra_rdoc_files: []
52
68
  files:
69
+ - lib/figs/application.rb
70
+ - lib/figs/env.rb
71
+ - lib/figs/error.rb
72
+ - lib/figs/figfile.rb
73
+ - lib/figs/git_handler.rb
74
+ - lib/figs/install.rb
75
+ - lib/figs/tasks/install.rake
76
+ - lib/figs/templates/application.yml
77
+ - lib/figs/version.rb
78
+ - lib/figs.rb
53
79
  - bin/figsify
80
+ - Rakefile
81
+ - Gemfile
82
+ - README.md
54
83
  homepage: https://github.com/NYULibraries/figs
55
84
  licenses:
56
85
  - MIT
@@ -64,12 +93,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
64
93
  - - ! '>='
65
94
  - !ruby/object:Gem::Version
66
95
  version: '0'
96
+ segments:
97
+ - 0
98
+ hash: 4045786731158848396
67
99
  required_rubygems_version: !ruby/object:Gem::Requirement
68
100
  none: false
69
101
  requirements:
70
102
  - - ! '>='
71
103
  - !ruby/object:Gem::Version
72
104
  version: '0'
105
+ segments:
106
+ - 0
107
+ hash: 4045786731158848396
73
108
  requirements: []
74
109
  rubyforge_project:
75
110
  rubygems_version: 1.8.23