metaractor 0.5.0 → 1.1.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
- SHA1:
3
- metadata.gz: 8bdc777077d09ca35ca998b494ce9b74e56883e3
4
- data.tar.gz: 1d1645bd315927baf24ccbf66a7bc8ee18ff5aed
2
+ SHA256:
3
+ metadata.gz: 61aa5597f77391b54b18d7a7d31e6b3cef5d00c844702fc3e1ef06c2dc8b0b1d
4
+ data.tar.gz: 5749efb4aa913aa4e4157e1213abedf689766add06df57544a41ac85aae47b0d
5
5
  SHA512:
6
- metadata.gz: 0309b7ea31e0629a4f3c076ad489a74e3be15e5ff5252f48743371c0ff55f9de1bacff22bd96c8c9d954749000ebbc525077a518bb7e8b963ddfb9755fb9bf1d
7
- data.tar.gz: 80c63031ecbc6553f5e121b7a6eddffbb5051d39b336661c0978a006e2cb628adee35b83324bb427dee68cd6d9a4698322a364682fa6236ff9859f71ebebf3a1
6
+ metadata.gz: 2c0d070919763827f78dee03c6667022faaf0b1882b65d527c1829f287b3ce7fa33efc91b8b55cb85e0edd1e808917b5d1b2e5d6833a151e33728b40f5df64d8
7
+ data.tar.gz: a5969b17f7cbe5c2f447e5b43dca00662e6bf8cdf23f96414fb0257d1b4aec4eaf1c02899dbf06947f582739995e015830d06b3857a65d36cfb8c5a260d259d4
data/Dockerfile CHANGED
@@ -1,48 +1,27 @@
1
- FROM ruby:2.3.1-alpine
1
+ FROM ruby:2.5.1-alpine
2
2
  MAINTAINER Ryan Schlesinger <ryan@outstand.com>
3
3
 
4
- RUN addgroup metaractor && \
5
- adduser -S -G metaractor metaractor
4
+ RUN addgroup -g 1000 -S metaractor && \
5
+ adduser -u 1000 -S -s /bin/ash -G metaractor metaractor && \
6
+ apk add --no-cache \
7
+ ca-certificates \
8
+ tini \
9
+ su-exec \
10
+ build-base \
11
+ git \
12
+ openssh
6
13
 
7
- ENV GOSU_VERSION 1.9
8
- ENV DUMB_INIT_VERSION 1.0.3
9
-
10
- RUN apk add --no-cache ca-certificates gnupg && \
11
- mkdir -p /tmp/build && \
12
- cd /tmp/build && \
13
- gpg --keyserver pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && \
14
- curl -o gosu -SL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64" && \
15
- curl -o gosu.asc -SL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64.asc" && \
16
- gpg --verify gosu.asc && \
17
- chmod +x gosu && \
18
- cp gosu /bin/gosu && \
19
- wget https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_amd64 && \
20
- wget https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/sha256sums && \
21
- grep dumb-init_${DUMB_INIT_VERSION}_amd64$ sha256sums | sha256sum -c && \
22
- chmod +x dumb-init_${DUMB_INIT_VERSION}_amd64 && \
23
- cp dumb-init_${DUMB_INIT_VERSION}_amd64 /bin/dumb-init && \
24
- cd /tmp && \
25
- rm -rf /tmp/build && \
26
- apk del gnupg && \
27
- rm -rf /root/.gnupg
28
-
29
- RUN apk add --no-cache \
30
- build-base \
31
- git \
32
- openssh
33
-
34
- COPY Gemfile metaractor.gemspec /metaractor/
35
- COPY lib/metaractor/version.rb /metaractor/lib/metaractor/
36
- RUN cd /metaractor \
37
- && bundle install \
38
- && git config --global push.default simple
39
- COPY . /metaractor/
14
+ WORKDIR /metaractor
40
15
  RUN chown -R metaractor:metaractor /metaractor
16
+ USER metaractor
41
17
 
42
- WORKDIR /metaractor
18
+ COPY --chown=metaractor:metaractor Gemfile metaractor.gemspec /metaractor/
19
+ COPY --chown=metaractor:metaractor lib/metaractor/version.rb /metaractor/lib/metaractor/
20
+ RUN git config --global push.default simple
21
+ COPY --chown=metaractor:metaractor . /metaractor/
43
22
 
23
+ USER root
44
24
  COPY docker-entrypoint.sh /docker-entrypoint.sh
45
25
 
46
- ENV DUMB_INIT_SETSID 0
47
- ENTRYPOINT ["/docker-entrypoint.sh"]
26
+ ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
48
27
  CMD ["rspec", "spec"]
data/README.md CHANGED
@@ -38,10 +38,67 @@ class HighFiveUser
38
38
  # private
39
39
  # delegate :user, to: context
40
40
  end
41
+
42
+ result = HighFiveUser.call # not passing user or user_id
43
+ result.failure?
44
+ # => true
45
+ result.valid?
46
+ # => false
47
+ result.errors
48
+ # => ["Required parameters: (user_id or user)"]
41
49
  ```
42
50
 
43
51
  See Interactor's [README](https://github.com/collectiveidea/interactor/blob/master/README.md) for more information.
44
52
 
53
+ ### Configuration
54
+ Metaractor is meant to be extensible (hence the 'meta'). You can add additional modules in the following way:
55
+
56
+ ```ruby
57
+ # This is an example from Outstand's production app to add some sidekiq magic.
58
+ # Feel free to place this in start up code or a Rails initializer.
59
+ Metaractor.configure do |config|
60
+ config.prepend_module Metaractor::SidekiqCallbacks
61
+ config.include_module Metaractor::SidekiqBatch
62
+ end
63
+ ```
64
+
65
+ ### Required Parameters
66
+ Metaractor supports complex required parameter statements and you can chain these together in any manner using `and`, `or`, and `xor`.
67
+ ```ruby
68
+ required and: [:token, or: [:recipient_id, :recipient] ]
69
+ ```
70
+
71
+ ### Optional Parameters
72
+ As optional parameters have no enforcement, they are merely advisory.
73
+ ```ruby
74
+ optional :enable_logging
75
+ ```
76
+
77
+ ### Custom Validation
78
+ Metaractor supports doing custom validation before any user supplied before_hooks run.
79
+ ```ruby
80
+ validate_parameters do
81
+ if context.foo == :bar
82
+ require_parameter :bar, message: 'optional missing parameter message'
83
+ end
84
+
85
+ unless context.user.admin?
86
+ add_parameter_error param: :user, message: 'User must be an admin'
87
+ end
88
+ end
89
+ ```
90
+
91
+ If you need to require a parameter from a `before_hook` for any reason, use the bang version of the method:
92
+ ```ruby
93
+ before do
94
+ # Be careful with this approach as some user code may run before the parameter validation
95
+ require_parameter! :awesome if context.mode == :awesome
96
+ end
97
+ ```
98
+
99
+ ### Further Reading
100
+ For more examples of all of the above approaches, please see the specs.
101
+
45
102
  ## Development
46
103
 
47
104
  - `docker build -t outstand/metaractor .`
@@ -50,7 +107,7 @@ See Interactor's [README](https://github.com/collectiveidea/interactor/blob/mast
50
107
  To release a new version:
51
108
  - Update the version number in `version.rb` and commit the result.
52
109
  - `docker build -t outstand/metaractor .`
53
- - `docker run -it --rm -v ~/.gitconfig:/root/.gitconfig -v ~/.gitconfig.user:/root/.gitconfig.user -v ~/.ssh/id_rsa:/root/.ssh/id_rsa -v ~/.gem:/root/.gem outstand/metaractor rake release`
110
+ - `docker run -it --rm -v ~/.gitconfig:/home/metaractor/.gitconfig -v ~/.gitconfig.user:/home/metaractor/.gitconfig.user -v ~/.ssh/id_rsa:/home/metaractor/.ssh/id_rsa -v ~/.gem:/home/metaractor/.gem outstand/metaractor rake release`
54
111
 
55
112
  ## Contributing
56
113
 
@@ -0,0 +1,24 @@
1
+ version: '3.6'
2
+ services:
3
+ metaractor:
4
+ build: .
5
+ image: outstand/metaractor:dev
6
+ stdin_open: true
7
+ tty: true
8
+ volumes:
9
+ - bundler-data:/usr/local/bundle
10
+ - .:/metaractor
11
+ release:
12
+ image: outstand/metaractor:dev
13
+ stdin_open: true
14
+ tty: true
15
+ command: rake release
16
+ volumes:
17
+ - bundler-data:/usr/local/bundle
18
+ - ~/.gitconfig:/home/metaractor/.gitconfig
19
+ - ~/.gitconfig.user:/home/metaractor/.gitconfig.user
20
+ - ~/.ssh/id_rsa:/home/metaractor/.ssh/id_rsa
21
+ - ~/.gem:/home/metaractor/.gem
22
+
23
+ volumes:
24
+ bundler-data:
data/docker-entrypoint.sh CHANGED
@@ -1,12 +1,20 @@
1
- #!/bin/dumb-init /bin/sh
1
+ #!/bin/sh
2
2
  set -e
3
3
 
4
- if [ "$1" = 'rspec' ] || [ "$1" = 'rake' ]; then
5
- set -- bundle exec "$@"
4
+ if [ "$(which "$1")" = '' ]; then
5
+ if [ "$(ls -A /usr/local/bundle/bin)" = '' ]; then
6
+ echo 'command not in path and bundler not initialized'
7
+ echo 'running bundle install'
8
+ su-exec metaractor bundle install
9
+ fi
6
10
  fi
7
11
 
8
12
  if [ "$1" = 'bundle' ]; then
9
- set -- gosu metaractor "$@"
13
+ set -- su-exec metaractor "$@"
14
+ elif ls /usr/local/bundle/bin | grep -q "\b$1\b"; then
15
+ set -- su-exec metaractor bundle exec "$@"
16
+
17
+ su-exec metaractor ash -c 'bundle check || bundle install'
10
18
  fi
11
19
 
12
20
  exec "$@"
@@ -0,0 +1,16 @@
1
+ module Metaractor
2
+ module ChainFailures
3
+ def self.included(base)
4
+ base.class_eval do
5
+ around :chain_nested_failures
6
+ end
7
+ end
8
+
9
+ def chain_nested_failures(interactor)
10
+ interactor.call
11
+ rescue Interactor::Failure => e
12
+ context.fail_from_context(context: e.context)
13
+ raise
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ module Metaractor
2
+ module ContextErrors
3
+ def errors
4
+ if super.nil?
5
+ self.errors = []
6
+ end
7
+
8
+ super
9
+ end
10
+
11
+ def fail_with_error!(message:)
12
+ add_error(message: message)
13
+ fail!
14
+ end
15
+
16
+ def fail_with_errors!(messages:)
17
+ add_errors(messages: messages)
18
+ fail!
19
+ end
20
+
21
+ def add_error(message:)
22
+ add_errors(messages: Array(message))
23
+ end
24
+
25
+ def add_errors(messages:)
26
+ self.errors += messages
27
+ end
28
+
29
+ def error_messages
30
+ errors.join("\n")
31
+ end
32
+ end
33
+ end
34
+
35
+ Interactor::Context.send(:include, Metaractor::ContextErrors)
@@ -1,39 +1,28 @@
1
+ require 'forwardable'
2
+
1
3
  module Metaractor
2
4
  class Error < StandardError; end
3
5
  class InvalidError < Error; end
4
6
 
5
7
  module Errors
6
- def self.included(base)
7
- base.class_eval do
8
- before :initialize_errors_array
9
- end
10
- end
11
-
12
- def initialize_errors_array
13
- context.errors ||= []
14
- end
15
-
16
- def fail_with_error!(message:)
17
- add_error(message: message)
18
- context.fail!
8
+ def fail_with_error!(*args)
9
+ context.fail_with_error!(*args)
19
10
  end
20
11
 
21
- def fail_with_errors!(messages:)
22
- add_errors(messages: messages)
23
- context.fail!
12
+ def fail_with_errors!(*args)
13
+ context.fail_with_errors!(*args)
24
14
  end
25
15
 
26
- def add_error(message:)
27
- add_errors(messages: Array(message))
16
+ def add_error(*args)
17
+ context.add_error(*args)
28
18
  end
29
19
 
30
- def add_errors(messages:)
31
- context.errors ||= []
32
- context.errors += messages
20
+ def add_errors(*args)
21
+ context.add_errors(*args)
33
22
  end
34
23
 
35
24
  def error_messages
36
- context.errors.join("\n")
25
+ context.error_messages
37
26
  end
38
27
  end
39
28
  end
@@ -0,0 +1,13 @@
1
+ module Metaractor
2
+ module FailFromContext
3
+ def fail_from_context(context:)
4
+ return if context.equal?(self)
5
+
6
+ invalidate! if context.invalid?
7
+ add_errors(messages: context.errors)
8
+ @failure = true
9
+ end
10
+ end
11
+ end
12
+
13
+ Interactor::Context.send(:include, Metaractor::FailFromContext)
@@ -99,8 +99,6 @@ module Metaractor
99
99
 
100
100
  case operator
101
101
  when :or
102
- # We can't test for #one? here as that breaks interactors with the same setup sharing a context.
103
- # This happens in almost all of our organizers.
104
102
  return valids.any?, "(#{messages.join(' or ')})"
105
103
  when :xor
106
104
  return valids.one?, "(#{messages.join(' xor ')})"
@@ -1,3 +1,3 @@
1
1
  module Metaractor
2
- VERSION = "0.5.0"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/metaractor.rb CHANGED
@@ -1,9 +1,12 @@
1
1
  require 'metaractor/version'
2
2
  require 'interactor'
3
3
  require 'metaractor/errors'
4
+ require 'metaractor/context_errors'
4
5
  require 'metaractor/parameters'
5
6
  require 'metaractor/run_with_context'
6
7
  require 'metaractor/context_validity'
8
+ require 'metaractor/chain_failures'
9
+ require 'metaractor/fail_from_context'
7
10
 
8
11
  module Metaractor
9
12
  def self.included(base)
@@ -36,7 +39,8 @@ module Metaractor
36
39
  [
37
40
  { module: Metaractor::Errors, method: :include },
38
41
  { module: Metaractor::Parameters, method: :include },
39
- { module: Metaractor::RunWithContext, method: :include }
42
+ { module: Metaractor::RunWithContext, method: :include },
43
+ { module: Metaractor::ChainFailures, method: :include }
40
44
  ]
41
45
  end
42
46
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metaractor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Schlesinger
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-04 00:00:00.000000000 Z
11
+ date: 2018-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: interactor
@@ -80,10 +80,14 @@ files:
80
80
  - LICENSE
81
81
  - README.md
82
82
  - Rakefile
83
+ - docker-compose.yml
83
84
  - docker-entrypoint.sh
84
85
  - lib/metaractor.rb
86
+ - lib/metaractor/chain_failures.rb
87
+ - lib/metaractor/context_errors.rb
85
88
  - lib/metaractor/context_validity.rb
86
89
  - lib/metaractor/errors.rb
90
+ - lib/metaractor/fail_from_context.rb
87
91
  - lib/metaractor/parameters.rb
88
92
  - lib/metaractor/run_with_context.rb
89
93
  - lib/metaractor/version.rb
@@ -108,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
112
  version: '0'
109
113
  requirements: []
110
114
  rubyforge_project:
111
- rubygems_version: 2.6.4
115
+ rubygems_version: 2.7.7
112
116
  signing_key:
113
117
  specification_version: 4
114
118
  summary: Adds parameter validation and error control to interactor