hesburgh-lib 0.1.0

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: 19be6eece64491b61c05c61eb9d8deb705d2b6c2
4
+ data.tar.gz: cf13adff46b6df8cc67b20cb83860e8c50942aca
5
+ SHA512:
6
+ metadata.gz: dd540b822d3f937261a94a1463443130214b936e7ce56e6de0dd8aacc6c68288b5a9ceb56d892f86a7a950ab06aa88d4d15e66bb4fe0b8787d376e17d06bc620
7
+ data.tar.gz: 52541e39a80a3a5a4945b9e24c5363a204a10d332f115069ddfa19abc06c263512c31d69f37657096b5c6975fdd0902af6fe0ee6845a4add8eef39ab389abb86
data/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ ##########################################################################
2
+ # Copyright 2014 University of Notre Dame
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
data/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # Hesburgh::Lib
2
+
3
+ [![Build Status](https://travis-ci.org/ndlib/hesburgh-lib.png?branch=master)](https://travis-ci.org/ndlib/hesburgh-lib)
4
+ [![Code Climate](https://codeclimate.com/github/ndlib/hesburgh-lib.png)](https://codeclimate.com/github/ndlib/hesburgh-lib)
5
+ [![Coverage Status](https://img.shields.io/coveralls/ndlib/hesburgh-lib.svg)](https://coveralls.io/r/ndlib/hesburgh-lib)
6
+ [![Documentation Status](http://inch-ci.org/github/ndlib/hesburgh-lib.svg?branch=master)](http://inch-ci.org/github/ndlib/hesburgh-lib)
7
+ [![APACHE 2 License](http://img.shields.io/badge/APACHE2-license-blue.svg)](./LICENSE)
8
+
9
+ A toolbox of code that may be reusable.
10
+
11
+ ## Usage
12
+
13
+ None of the classes in this gem should be autoloaded.
14
+ It is up to *you, the developer,* to explicitly require the class.
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env ruby -wU
2
+
3
+ # *****************************************************************************
4
+ #
5
+ # CONFIGURATION OPTIONS
6
+ #
7
+ # *****************************************************************************
8
+
9
+ CONFIG_KEYS = [:REPOSITORY_PATH].freeze
10
+
11
+ REPOSITORY_PATH = ENV.fetch('REPOSITORY_PATH') { Dir.pwd }
12
+
13
+ # *****************************************************************************
14
+ #
15
+ # HELP OPTIONS
16
+ #
17
+ # *****************************************************************************
18
+
19
+ if ARGV.grep(/^-+h(elp)?$/i).size > 0
20
+ $stdout.puts ""
21
+ $stdout.puts "$ #{File.basename(__FILE__)} <gem1> <gem2>"
22
+ $stdout.puts ""
23
+ $stdout.puts "This script will update the given gem dependency, one at a time, and commit the"
24
+ $stdout.puts "change."
25
+ $stdout.puts ""
26
+ $stdout.puts "Current Configuration:"
27
+ CONFIG_KEYS.each do |key|
28
+ $stdout.puts "\t#{key}='#{Object.const_get(key)}'"
29
+ end
30
+ $stdout.puts ""
31
+ $stdout.puts "You can override the configuration option by adding the corresponding"
32
+ $stdout.puts "ENV variable."
33
+ $stdout.puts ""
34
+ $stdout.puts "Example:"
35
+ $stdout.puts "$ REPOSITORY_PATH=/path/to/repository #{File.basename(__FILE__)}"
36
+ exit(0)
37
+ end
38
+
39
+ # *****************************************************************************
40
+ #
41
+ # GUARD CONDITIONS
42
+ #
43
+ # *****************************************************************************
44
+
45
+ GEM_NAMES = ARGV
46
+
47
+ # Guard that we have a clean working directory
48
+ if `cd #{REPOSITORY_PATH} && git status --porcelain`.strip.size > 0
49
+ $stderr.puts "Repository @ #{REPOSITORY_PATH} did not have a clean working directory"
50
+ exit!(2)
51
+ end
52
+
53
+ GEM_NAMES.each do |gem_name|
54
+ # Guard that the update can happen
55
+ unless system("cd #{REPOSITORY_PATH} && bundle update #{gem_name}")
56
+ $stderr.puts "Unable to update #{gem_name}. See previous output."
57
+ exit!(3)
58
+ end
59
+
60
+ # Commit the changes
61
+ `cd #{REPOSITORY_PATH}; git add Gemfile.lock`
62
+
63
+ path_to_commit_message = File.expand_path(File.join(REPOSITORY_PATH, '../COMMIT.msg'))
64
+ begin
65
+ File.open(path_to_commit_message, 'w+') do |file|
66
+ file.puts "Updating #{gem_name} dependency"
67
+ file.puts ""
68
+
69
+ message = "`$ #{File.basename(__FILE__)} #{gem_name}`"
70
+ CONFIG_KEYS.each_with_object(message) do |key, mem|
71
+ mem = "#{key}=\"#{ENV[key.to_s]}\" #{mem}" if ENV.key?(key.to_s)
72
+ mem
73
+ end
74
+ file.puts message
75
+ end
76
+ $stdout.puts `cd #{REPOSITORY_PATH} && git commit -F #{path_to_commit_message}`
77
+ ensure
78
+ begin
79
+ File.unlink(path_to_commit_message)
80
+ rescue true
81
+ # If it doesn't exist don't worry
82
+ end
83
+ end
84
+ end
@@ -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
+ require 'hesburgh/lib/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hesburgh-lib"
8
+ spec.version = Hesburgh::Lib::VERSION
9
+ spec.authors = ["Jeremy Friesen"]
10
+ spec.email = ["jeremy.n.friesen@gmail.com"]
11
+ spec.summary = %q{A toolbox of code that may be reusable.}
12
+ spec.description = %q{A toolbox of code that may be reusable.}
13
+ spec.homepage = "https://github.com/ndlib/hesburgh-lib"
14
+ spec.license = "APACHE2"
15
+
16
+ spec.files = `git ls-files -z -- bin/* lib/* LICENSE README.md hesburgh-lib.gemspec`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rspec", "~> 3.0"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec-given", "~> 3.5"
25
+ spec.add_development_dependency "rubocop", "~> 0.27"
26
+ spec.add_development_dependency "activesupport", ">= 3.0"
27
+ end
@@ -0,0 +1,78 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/class/attribute'
3
+ require 'active_support/core_ext/string/inflections'
4
+
5
+ module Hesburgh
6
+ module Lib
7
+ # Exposes a way for connecting a set of Runners into your application.
8
+ # A runner allows you to tease out Action level logic into its own custom
9
+ # class.
10
+ #
11
+ # @see Hesburgh::Lib::Runner
12
+ module ControllerWithRunner
13
+ extend ActiveSupport::Concern
14
+
15
+ included do
16
+ # Because yardoc's scope imperative does not appear to work, I'm pushing the
17
+ # comments into the class definition
18
+ class << self
19
+ # @!attribute [rw] runner_container
20
+ # So you can specify where you will be finding an action's Runner
21
+ # class.
22
+ #
23
+ # @see #run
24
+ end
25
+ class_attribute :runner_container
26
+ end
27
+
28
+ # So you can more easily decouple the controller's command behavior and
29
+ # response behavior.
30
+ #
31
+ # @example
32
+ # def index
33
+ # run(specific_params) do |on|
34
+ # on.success { |collection|
35
+ # @collection = collection
36
+ # respond_with(@collection)
37
+ # }
38
+ # end
39
+ # end
40
+ #
41
+ # @see .runner_container for customization
42
+ def run(*args, &block)
43
+ runner.run(self, *args, &block)
44
+ end
45
+
46
+ # A query to lookup the appropriate Runner class
47
+ def runner(runner_name = nil)
48
+ return @runner if @runner # For Dependency Injection
49
+ runner_name = action_name.classify unless runner_name
50
+ if runner_container.const_defined?(runner_name)
51
+ runner_container.const_get(runner_name)
52
+ else
53
+ fail RunnerNotFoundError, container: runner_container, name: runner_name
54
+ end
55
+ end
56
+
57
+ # Exposed for purposes of Dependency Injection.
58
+ def runner=(object)
59
+ fail(ImproperRunnerError, runner: object, method_name: :run) unless object.respond_to?(:run)
60
+ @runner = object
61
+ end
62
+
63
+ # Raised when a Runner is not found
64
+ class RunnerNotFoundError < RuntimeError # :nodoc:
65
+ def initialize(options = {})
66
+ super("Unable to find #{options.fetch(:name)} in #{options.fetch(:container)}")
67
+ end
68
+ end
69
+
70
+ # Raised when a Runner is not found
71
+ class ImproperRunnerError < RuntimeError # :nodoc:
72
+ def initialize(options = {})
73
+ super("Expected #{options.fetch(:runner)} to respond_to #{options.fetch(:method_name)}")
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,67 @@
1
+ module Hesburgh
2
+ module Lib
3
+ # A class to assist in circumventing the seething underlayer of potential
4
+ # runners and cut quick to the working with the callbacks.
5
+ #
6
+ # @example
7
+ #
8
+ # context = []
9
+ # runner = MockRunner.new(context: context, run_with: :input, yields: :yielded_value, callback_name: :success)
10
+ # runner.run(:input) do |on|
11
+ # on.success {|output| context << output }
12
+ # end
13
+ # context == [:yielded_value]
14
+ # => true
15
+ #
16
+ # @see Hesrbugh::Lib::Runner
17
+ # @see Hesrbugh::Lib::NamedCallbacks
18
+ class MockRunner
19
+ # Raised when the actual :run_with parameter is different than the
20
+ # expected
21
+ class RunWithMismatchError < RuntimeError
22
+ def initialize(actual: nil, expected: nil)
23
+ super("RunWith Mismatch Error:\nActual: #{actual.inspect}\nExpected: #{expected.inspect}\n")
24
+ end
25
+ end
26
+
27
+ def initialize(options = {})
28
+ @yields = options.fetch(:yields)
29
+ @callback_name = options.fetch(:callback_name)
30
+ @run_with = __wrap__(options.fetch(:run_with))
31
+
32
+ # Because the context may automatically be getting assigned by the
33
+ # controller.
34
+ @run_with.unshift(options[:context]) if options.key?(:context)
35
+ end
36
+
37
+ def run(*args)
38
+ if @run_with == args
39
+ if block_given?
40
+ return yield(self)
41
+ else
42
+ return @callback_name, *@yields
43
+ end
44
+ else
45
+ fail RunWithMismatchError, actual: args, expected: @run_with
46
+ end
47
+ end
48
+
49
+ def method_missing(method_name, &_block)
50
+ super unless @callback_name.to_s == method_name.to_s
51
+ return @callback_name, *yield(@yields)
52
+ end
53
+
54
+ private
55
+
56
+ def __wrap__(object)
57
+ if object.nil?
58
+ []
59
+ elsif object.respond_to?(:to_ary)
60
+ object.to_ary || [object]
61
+ else
62
+ [object]
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,24 @@
1
+ module Hesburgh
2
+ module Lib
3
+ # Responsible for registering blocks used for callbacks.
4
+ class NamedCallbacks
5
+ def initialize
6
+ @callbacks = {}
7
+ end
8
+
9
+ def method_missing(callback_name, *_args, &block)
10
+ @callbacks[callback_name] = block
11
+ end
12
+
13
+ def respond_to_missing?(callback_name)
14
+ @callbacks[callback_name]
15
+ end
16
+
17
+ def call(callback_name, *args)
18
+ callback_name = callback_name.to_sym
19
+ callback = @callbacks[callback_name]
20
+ callback ? callback.call(*args) : true
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,50 @@
1
+ module Hesburgh
2
+ module Lib
3
+ # A Runner is responsible for performing the guts of what might traditionally
4
+ # be a controller's action.
5
+ #
6
+ # It exists for two reasons, though this is not considered exhaustive:
7
+ # * Controllers are extremely over-worked (parameter negotiation,
8
+ # authentication, authorization, marshalling an object, user messages via
9
+ # flash, and http response determination)
10
+ # * The inner method content of a controller's action is subject to change
11
+ # especially as other implementors look to change the behavior.
12
+ #
13
+ # So, the Runner provides a seem in the code in which you can more readily
14
+ # make changes to the "inner method" of a route. In some ways, I see this as
15
+ # a separation of state change and response; a somewhat analogous separation
16
+ # to the Command/Query separation principle.
17
+ #
18
+ # @see Hesrbugh::Lib::MockRunner
19
+ class Runner
20
+ def self.run(context, *args, &block)
21
+ new(context, &block).run(*args)
22
+ end
23
+
24
+ attr_reader :context
25
+ protected :context
26
+
27
+ def initialize(context, callbacks: nil)
28
+ @callbacks = callbacks || default_callbacks
29
+ @context = context
30
+ yield(@callbacks) if block_given?
31
+ end
32
+
33
+ def callback(name, *args)
34
+ @callbacks.call(name, *args)
35
+ return name, *args
36
+ end
37
+
38
+ def run(*_args)
39
+ fail NotImplementedError, ("You must define #{self.class}#run")
40
+ end
41
+
42
+ private
43
+
44
+ def default_callbacks
45
+ require 'hesburgh/lib/named_callbacks'
46
+ NamedCallbacks.new
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ module Hesburgh
2
+ module Lib
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ require "hesburgh/lib/version"
2
+
3
+ module Hesburgh
4
+ # The namespaced container for a toolbox of code that may be reusable.
5
+ module Lib
6
+ # Your code goes here...
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hesburgh-lib
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Friesen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-given
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.5'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.27'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.27'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ description: A toolbox of code that may be reusable.
98
+ email:
99
+ - jeremy.n.friesen@gmail.com
100
+ executables:
101
+ - update-dependency
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - LICENSE
106
+ - README.md
107
+ - bin/update-dependency
108
+ - hesburgh-lib.gemspec
109
+ - lib/hesburgh/lib.rb
110
+ - lib/hesburgh/lib/controller_with_runner.rb
111
+ - lib/hesburgh/lib/mock_runner.rb
112
+ - lib/hesburgh/lib/named_callbacks.rb
113
+ - lib/hesburgh/lib/runner.rb
114
+ - lib/hesburgh/lib/version.rb
115
+ homepage: https://github.com/ndlib/hesburgh-lib
116
+ licenses:
117
+ - APACHE2
118
+ metadata: {}
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.4.7
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: A toolbox of code that may be reusable.
139
+ test_files: []