determinator-context 0.1.11
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 +7 -0
- data/.circleci/config.yml +63 -0
- data/.github/workflows/codeql-analysis.yml +49 -0
- data/.github/workflows/codeql-complete.yml +58 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +45 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +83 -0
- data/README.md +77 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/determinator-context.gemspec +27 -0
- data/lib/determinator/context/actors.rb +103 -0
- data/lib/determinator/context/helpers.rb +37 -0
- data/lib/determinator/context/resolver.rb +26 -0
- data/lib/determinator/context/version.rb +5 -0
- data/lib/determinator/context.rb +11 -0
- data/lib/determinator/models/base.rb +46 -0
- data/lib/determinator/models/common/city.rb +13 -0
- data/lib/determinator/models/common/country.rb +13 -0
- data/lib/determinator/models/common/drn.rb +10 -0
- data/lib/determinator/models/common/neighborhood.rb +12 -0
- data/lib/determinator/models/common/zone.rb +13 -0
- data/lib/determinator/models/customer.rb +12 -0
- data/lib/determinator/models/request.rb +29 -0
- data/lib/determinator/models/restaurant.rb +18 -0
- data/lib/determinator/models/rider.rb +15 -0
- data/lib/determinator/models/types.rb +9 -0
- data/lib/determinator/models.rb +14 -0
- metadata +114 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: d189ccc035413e3bbf5706ecee72c50228e9637ff985ca08de82f8b5f9221103
|
|
4
|
+
data.tar.gz: 706b55dfb757e4041b50715d06b071737147ba44fb099c69437182a7e32c4426
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 71aa0e2777a927f0e841e0b78722257955cfcb170dcb403447738d030692629115ac0bbf0a184aeb32aaf0b49db495490bab6fdb289b81e00875580ff1f12bf7
|
|
7
|
+
data.tar.gz: ba87b44ce8cd10363834bfdea75d7f78c36729bd2828723cf49eea742cbb6f9d883f9f6485ecfa8f40036b623bbc601452ea2569c42acc2b94e6f43cf4066daa
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
global_dockerhub_login: &global_dockerhub_login
|
|
2
|
+
run:
|
|
3
|
+
name: Authenticate with hub.docker.com - DockerHub
|
|
4
|
+
command: docker login -u $GLOBAL_DOCKERHUB_USERNAME -p $GLOBAL_DOCKERHUB_PASSWORD
|
|
5
|
+
global_context: &global_context
|
|
6
|
+
context:
|
|
7
|
+
- org-global
|
|
8
|
+
global_remote_docker: &global_remote_docker
|
|
9
|
+
version: 19.03.13
|
|
10
|
+
global_dockerhub_auth: &global_dockerhub_auth
|
|
11
|
+
auth:
|
|
12
|
+
username: $GLOBAL_DOCKERHUB_USERNAME
|
|
13
|
+
password: $GLOBAL_DOCKERHUB_PASSWORD
|
|
14
|
+
version: 2
|
|
15
|
+
jobs:
|
|
16
|
+
build_2.6:
|
|
17
|
+
docker:
|
|
18
|
+
- image: circleci/ruby:2.6
|
|
19
|
+
<<: *global_dockerhub_auth
|
|
20
|
+
steps:
|
|
21
|
+
- checkout
|
|
22
|
+
|
|
23
|
+
- run:
|
|
24
|
+
name: Install bundler
|
|
25
|
+
command: gem install bundler
|
|
26
|
+
|
|
27
|
+
- run:
|
|
28
|
+
name: Bundle Install
|
|
29
|
+
command: bundle install
|
|
30
|
+
|
|
31
|
+
- run:
|
|
32
|
+
name: Run rspec
|
|
33
|
+
command: |
|
|
34
|
+
bundle exec rspec --format documentation
|
|
35
|
+
|
|
36
|
+
build_2.7:
|
|
37
|
+
docker:
|
|
38
|
+
- image: circleci/ruby:2.7
|
|
39
|
+
<<: *global_dockerhub_auth
|
|
40
|
+
steps:
|
|
41
|
+
- checkout
|
|
42
|
+
|
|
43
|
+
- run:
|
|
44
|
+
name: Install bundler
|
|
45
|
+
command: gem install bundler
|
|
46
|
+
|
|
47
|
+
- run:
|
|
48
|
+
name: Bundle Install
|
|
49
|
+
command: bundle install
|
|
50
|
+
|
|
51
|
+
- run:
|
|
52
|
+
name: Run rspec
|
|
53
|
+
command: |
|
|
54
|
+
bundle exec rspec --format documentation
|
|
55
|
+
|
|
56
|
+
workflows:
|
|
57
|
+
version: 2
|
|
58
|
+
test:
|
|
59
|
+
jobs:
|
|
60
|
+
- build_2.6
|
|
61
|
+
|
|
62
|
+
- build_2.7
|
|
63
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: "CodeQL - Minimal incremental analysis"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- "master" # Change this to the branch to default branch
|
|
7
|
+
- "!ignore/branch" # Ignore CodeQL scan for these branches
|
|
8
|
+
- "!test/*" # Ignore CodeQL scan for these branches
|
|
9
|
+
pull_request:
|
|
10
|
+
branches:
|
|
11
|
+
- "master" # Change this to the branch to default branch
|
|
12
|
+
paths-ignore:
|
|
13
|
+
- '**/*.md'
|
|
14
|
+
- '**/*.txt'
|
|
15
|
+
# If your project is not actively developed, consider scheduling CodeQL scans
|
|
16
|
+
#schedule:
|
|
17
|
+
# - cron: '44 22 * * 5' # Run CodeQL scan every Friday at 10:44 PM UTC
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
analyze:
|
|
21
|
+
name: Analyze
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
timeout-minutes: 30 # Set timeout to 30 minutes; Change if your project takes longer to scan
|
|
24
|
+
permissions:
|
|
25
|
+
actions: read
|
|
26
|
+
contents: read
|
|
27
|
+
security-events: write
|
|
28
|
+
|
|
29
|
+
strategy:
|
|
30
|
+
fail-fast: false
|
|
31
|
+
matrix:
|
|
32
|
+
language: [ 'ruby' ]
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- name: Checkout repository
|
|
36
|
+
uses: actions/checkout@v3
|
|
37
|
+
|
|
38
|
+
# Initializes the CodeQL tools for scanning.
|
|
39
|
+
- name: Initialize CodeQL
|
|
40
|
+
uses: github/codeql-action/init@v2
|
|
41
|
+
with:
|
|
42
|
+
languages: ${{ matrix.language }}
|
|
43
|
+
# queries: security-extended,security-and-quality
|
|
44
|
+
# debug: true # Only use this for debugging. It will increase the runtime of the action and take up storage
|
|
45
|
+
|
|
46
|
+
- name: Perform CodeQL Analysis
|
|
47
|
+
uses: github/codeql-action/analyze@v2
|
|
48
|
+
with:
|
|
49
|
+
category: "/language:${{matrix.language}}"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: "CodeQL - Complete analysis"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "44 23 12 * *" # Run CodeQL scan on a day of every month at 11:44 PM UTC
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
analyze:
|
|
9
|
+
name: Analyze
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
timeout-minutes: 30 # Set timeout to 30 minutes; Change if your project takes longer to scan
|
|
12
|
+
permissions:
|
|
13
|
+
actions: read
|
|
14
|
+
contents: read
|
|
15
|
+
security-events: write
|
|
16
|
+
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
language: ["ruby"]
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout repository
|
|
24
|
+
uses: actions/checkout@v3
|
|
25
|
+
|
|
26
|
+
# This step will try to find a Dockerfile in the repository and extract the Ruby version from it.
|
|
27
|
+
# If you don't use Docker, you can remove this step and add the Ruby version directly to the
|
|
28
|
+
# ruby-version parameter in the `ruby/setup-ruby` step below.
|
|
29
|
+
- name: Find Ruby version in Dockerfile
|
|
30
|
+
id: find-ruby-version-in-dockerfile
|
|
31
|
+
run: |
|
|
32
|
+
ruby_version=$(find . -name Dockerfile -exec sed -En 's/^FROM ruby:([0-9.]+)(.*)/\1/p' {} \; | head -1)
|
|
33
|
+
if [ -z "$ruby_version" ]; then
|
|
34
|
+
echo "No Dockerfile found, using default Ruby version"
|
|
35
|
+
ruby_version="2.7"
|
|
36
|
+
else
|
|
37
|
+
echo "Found Dockerfile, using Ruby version $ruby_version"
|
|
38
|
+
fi
|
|
39
|
+
echo USE_RUBY_VERSION=$ruby_version >> $GITHUB_OUTPUT
|
|
40
|
+
- uses: ruby/setup-ruby@v1
|
|
41
|
+
with:
|
|
42
|
+
ruby-version: ${{ steps.find-ruby-version-in-dockerfile.outputs.USE_RUBY_VERSION }} # The version of Ruby to use
|
|
43
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
44
|
+
#env:
|
|
45
|
+
# BUNDLE_GEMFILE: ./path/to/Gemfile # Change this to the path to your Gemfile if not in root
|
|
46
|
+
|
|
47
|
+
# Initializes the CodeQL tools for scanning.
|
|
48
|
+
- name: Initialize CodeQL
|
|
49
|
+
uses: github/codeql-action/init@v2
|
|
50
|
+
with:
|
|
51
|
+
languages: ${{ matrix.language }}
|
|
52
|
+
# queries: security-extended,security-and-quality
|
|
53
|
+
# debug: true # Only use this for debugging. It will increase the runtime of the action and take up storage
|
|
54
|
+
|
|
55
|
+
- name: Perform CodeQL Analysis
|
|
56
|
+
uses: github/codeql-action/analyze@v2
|
|
57
|
+
with:
|
|
58
|
+
category: "/language:${{matrix.language}}"
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# 0.1.10
|
|
2
|
+
|
|
3
|
+
- Add DRNs to main actors
|
|
4
|
+
|
|
5
|
+
# 0.1.9
|
|
6
|
+
|
|
7
|
+
- Add `with` to override model attributes
|
|
8
|
+
|
|
9
|
+
# 0.1.8
|
|
10
|
+
|
|
11
|
+
- Fail gracefully if property is missing
|
|
12
|
+
|
|
13
|
+
# 0.1.7
|
|
14
|
+
|
|
15
|
+
- Bugfix: handle missing features correctly
|
|
16
|
+
|
|
17
|
+
# 0.1.6
|
|
18
|
+
|
|
19
|
+
- Remove error if the feature is not structured and error tracking
|
|
20
|
+
|
|
21
|
+
# 0.1.5
|
|
22
|
+
|
|
23
|
+
- Feature: add `with` method to clone actors
|
|
24
|
+
|
|
25
|
+
# 0.1.4
|
|
26
|
+
|
|
27
|
+
- Bugfix: allow passing nil values to actors
|
|
28
|
+
|
|
29
|
+
# 0.1.3
|
|
30
|
+
|
|
31
|
+
- Call `determinator_actor` helper block in instance context
|
|
32
|
+
- Add `bot` to platforms list.
|
|
33
|
+
|
|
34
|
+
# 0.1.2
|
|
35
|
+
|
|
36
|
+
- Fix dependencies
|
|
37
|
+
|
|
38
|
+
# 0.1.1
|
|
39
|
+
|
|
40
|
+
- Add Determinator::Context::Actors.elements
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# 0.1.0
|
|
44
|
+
|
|
45
|
+
- Initial functionality
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
determinator-context (0.1.11)
|
|
5
|
+
determinator (>= 2.5.4)
|
|
6
|
+
dry-struct (~> 1.0)
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
byebug (11.1.3)
|
|
12
|
+
concurrent-ruby (1.1.10)
|
|
13
|
+
determinator (2.9.1)
|
|
14
|
+
faraday
|
|
15
|
+
semantic (~> 1.6)
|
|
16
|
+
diff-lcs (1.3)
|
|
17
|
+
dry-container (0.10.0)
|
|
18
|
+
concurrent-ruby (~> 1.0)
|
|
19
|
+
dry-core (0.8.0)
|
|
20
|
+
concurrent-ruby (~> 1.0)
|
|
21
|
+
dry-inflector (0.3.0)
|
|
22
|
+
dry-logic (1.2.0)
|
|
23
|
+
concurrent-ruby (~> 1.0)
|
|
24
|
+
dry-core (~> 0.5, >= 0.5)
|
|
25
|
+
dry-struct (1.4.0)
|
|
26
|
+
dry-core (~> 0.5, >= 0.5)
|
|
27
|
+
dry-types (~> 1.5)
|
|
28
|
+
ice_nine (~> 0.11)
|
|
29
|
+
dry-types (1.5.1)
|
|
30
|
+
concurrent-ruby (~> 1.0)
|
|
31
|
+
dry-container (~> 0.3)
|
|
32
|
+
dry-core (~> 0.5, >= 0.5)
|
|
33
|
+
dry-inflector (~> 0.1, >= 0.1.2)
|
|
34
|
+
dry-logic (~> 1.0, >= 1.0.2)
|
|
35
|
+
faraday (1.8.0)
|
|
36
|
+
faraday-em_http (~> 1.0)
|
|
37
|
+
faraday-em_synchrony (~> 1.0)
|
|
38
|
+
faraday-excon (~> 1.1)
|
|
39
|
+
faraday-httpclient (~> 1.0.1)
|
|
40
|
+
faraday-net_http (~> 1.0)
|
|
41
|
+
faraday-net_http_persistent (~> 1.1)
|
|
42
|
+
faraday-patron (~> 1.0)
|
|
43
|
+
faraday-rack (~> 1.0)
|
|
44
|
+
multipart-post (>= 1.2, < 3)
|
|
45
|
+
ruby2_keywords (>= 0.0.4)
|
|
46
|
+
faraday-em_http (1.0.0)
|
|
47
|
+
faraday-em_synchrony (1.0.0)
|
|
48
|
+
faraday-excon (1.1.0)
|
|
49
|
+
faraday-httpclient (1.0.1)
|
|
50
|
+
faraday-net_http (1.0.1)
|
|
51
|
+
faraday-net_http_persistent (1.2.0)
|
|
52
|
+
faraday-patron (1.0.0)
|
|
53
|
+
faraday-rack (1.0.0)
|
|
54
|
+
ice_nine (0.11.2)
|
|
55
|
+
multipart-post (2.2.3)
|
|
56
|
+
rake (12.3.3)
|
|
57
|
+
rspec (3.9.0)
|
|
58
|
+
rspec-core (~> 3.9.0)
|
|
59
|
+
rspec-expectations (~> 3.9.0)
|
|
60
|
+
rspec-mocks (~> 3.9.0)
|
|
61
|
+
rspec-core (3.9.2)
|
|
62
|
+
rspec-support (~> 3.9.3)
|
|
63
|
+
rspec-expectations (3.9.2)
|
|
64
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
65
|
+
rspec-support (~> 3.9.0)
|
|
66
|
+
rspec-mocks (3.9.1)
|
|
67
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
68
|
+
rspec-support (~> 3.9.0)
|
|
69
|
+
rspec-support (3.9.3)
|
|
70
|
+
ruby2_keywords (0.0.5)
|
|
71
|
+
semantic (1.6.1)
|
|
72
|
+
|
|
73
|
+
PLATFORMS
|
|
74
|
+
ruby
|
|
75
|
+
|
|
76
|
+
DEPENDENCIES
|
|
77
|
+
byebug
|
|
78
|
+
determinator-context!
|
|
79
|
+
rake (~> 12.0)
|
|
80
|
+
rspec (~> 3.0)
|
|
81
|
+
|
|
82
|
+
BUNDLED WITH
|
|
83
|
+
2.1.4
|
data/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Determinator Context
|
|
2
|
+
|
|
3
|
+
This is a gem to manage Determinator context objects.
|
|
4
|
+
|
|
5
|
+
It allows you to define the actors that will be determinated upon in a single place in the controller,
|
|
6
|
+
where they can be tested; then, the ID to be determinated upon are decided either by pointing to an attribute
|
|
7
|
+
in code, or with a structured setting in the feature itself.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add this line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
source "https://8Sshw-M7Dp0iGmkGphMxS4s7BCCuI@gem.fury.io/deliveroo/" do
|
|
15
|
+
gem 'determinator-context'
|
|
16
|
+
end
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
And then execute:
|
|
20
|
+
|
|
21
|
+
$ bundle
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
The simplest way to set up a context is to use the included helper in your controllers. For example:
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
class ApplicationController < ActionController::Base
|
|
30
|
+
include Determinator::Context::Helpers
|
|
31
|
+
|
|
32
|
+
determinator_actor(:request) do
|
|
33
|
+
Determinator::Models::Request.new(
|
|
34
|
+
uid: 'abc', customer: {guid: 'foo', sticky_guid: 'bar', session_guid: nil}
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
determinator_actor(:customer) do
|
|
39
|
+
next nil unless current_user.present?
|
|
40
|
+
|
|
41
|
+
Determinator::Models::Customer.new(
|
|
42
|
+
id: current_user.id,
|
|
43
|
+
email: current_user.email,
|
|
44
|
+
employee: current_user.employee
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class MenuController < ApplicationController
|
|
50
|
+
include Determinator::Context::Helpers
|
|
51
|
+
|
|
52
|
+
determinator_actor(:restaurant) do
|
|
53
|
+
# If 'to_determinator' is a method on the model
|
|
54
|
+
# which returns the constructed object
|
|
55
|
+
restaurant.to_determinator
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Then, if the feature has a `structured_bucket` set, you can just use the determinator context to determinate:
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
determinator_context.which_variant('test_feature')
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If the feature is not structured, or for some reason you want to override the structured bucket, you can do:
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
determinator_context.using('request.customer.guid').which_variant('test_feature')
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Development
|
|
74
|
+
|
|
75
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
76
|
+
|
|
77
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to GemFury.
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "determinator/context"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require_relative 'lib/determinator/context/version'
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |spec|
|
|
4
|
+
spec.name = "determinator-context"
|
|
5
|
+
spec.version = Determinator::Context::VERSION
|
|
6
|
+
spec.authors = ["Ivan Pirlik"]
|
|
7
|
+
spec.email = ["ivan.pirlik@deliveroo.co.uk"]
|
|
8
|
+
|
|
9
|
+
spec.summary = %q{Context objects for Determinator}
|
|
10
|
+
spec.description = %q{Helpers to construct Determinator actors.}
|
|
11
|
+
spec.homepage = "https://github.com/deliveroo/determinator-context-rb"
|
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
|
13
|
+
|
|
14
|
+
# Specify which files should be added to the gem when it is released.
|
|
15
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
16
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
17
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
|
+
end
|
|
19
|
+
spec.bindir = "exe"
|
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
21
|
+
spec.require_paths = ["lib"]
|
|
22
|
+
|
|
23
|
+
spec.add_development_dependency "byebug", "~> 11.0"
|
|
24
|
+
|
|
25
|
+
spec.add_dependency "determinator", ">= 2.5.4"
|
|
26
|
+
spec.add_dependency "dry-struct", "~> 1.0"
|
|
27
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
require_relative 'resolver'
|
|
2
|
+
|
|
3
|
+
module Determinator
|
|
4
|
+
module Context
|
|
5
|
+
class Actors
|
|
6
|
+
KEYS = {
|
|
7
|
+
request: Models::Request,
|
|
8
|
+
customer: Models::Customer,
|
|
9
|
+
restaurant: Models::Restaurant,
|
|
10
|
+
rider: Models::Rider
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
attr_reader :id_path
|
|
14
|
+
|
|
15
|
+
def self.elements
|
|
16
|
+
KEYS.map{ |k, v| v.collect_elements("#{k}.") }.flatten(1).to_h
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(controller, actors={})
|
|
20
|
+
@controller = controller
|
|
21
|
+
@actors = {}
|
|
22
|
+
actors.each { |k, v| self[k] = v}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def [](name)
|
|
26
|
+
actors[name]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def []=(name, actor)
|
|
30
|
+
@params = nil # clean cached params
|
|
31
|
+
|
|
32
|
+
if actors[name]
|
|
33
|
+
raise Error.new("#{name} is already set")
|
|
34
|
+
end
|
|
35
|
+
if KEYS[name].nil?
|
|
36
|
+
raise Error.new("#{name} is not an allowed actor")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
return if actor.nil?
|
|
40
|
+
|
|
41
|
+
unless actor.is_a?(KEYS[name])
|
|
42
|
+
raise Error.new("#{name} should be of type #{KEYS[name]}")
|
|
43
|
+
end
|
|
44
|
+
actors[name] = actor
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def has?(name)
|
|
48
|
+
actors.key?(name)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def using(dotted_path)
|
|
52
|
+
Resolver.new(self, controller, dotted_path)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def get(dotted_path)
|
|
56
|
+
return unless dotted_path
|
|
57
|
+
parts = dotted_path.split('.').map(&:to_sym)
|
|
58
|
+
parts.reduce(actors) { |curr, part| curr ? curr[part] : nil }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def to_params
|
|
62
|
+
@params ||= flatten_hash(actors.transform_values(&:to_h))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def which_variant(feature_name)
|
|
66
|
+
retrieve_resolver(feature_name)&.which_variant(feature_name) || false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def feature_flag_on?(feature_name)
|
|
70
|
+
retrieve_resolver(feature_name)&.feature_flag_on?(feature_name) || false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def with(new_actors={})
|
|
74
|
+
self.class.new(controller, actors.merge(new_actors))
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
attr_reader :controller, :actors
|
|
80
|
+
|
|
81
|
+
def retrieve_resolver(feature_name)
|
|
82
|
+
feature = controller.retrieve(feature_name)
|
|
83
|
+
if feature.nil? || feature.is_a?(Determinator::ErrorResponse) || feature.is_a?(Determinator::MissingResponse)
|
|
84
|
+
Determinator.notice_missing_feature(feature_name)
|
|
85
|
+
return
|
|
86
|
+
end
|
|
87
|
+
Resolver.new(self, controller, feature.structured_bucket, feature: feature)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def flatten_hash(hash)
|
|
91
|
+
hash.each_with_object({}) do |(k, v), h|
|
|
92
|
+
if v.is_a? Hash
|
|
93
|
+
flatten_hash(v).map do |h_k, h_v|
|
|
94
|
+
h["#{k}.#{h_k}"] = h_v
|
|
95
|
+
end
|
|
96
|
+
else
|
|
97
|
+
h[k.to_s] = v
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Determinator
|
|
2
|
+
module Context
|
|
3
|
+
module Helpers
|
|
4
|
+
module ClassMethods
|
|
5
|
+
def determinator_actors
|
|
6
|
+
if superclass.respond_to?(:determinator_actors)
|
|
7
|
+
superclass.determinator_actors.merge(@determinator_actors || {})
|
|
8
|
+
else
|
|
9
|
+
@determinator_actors
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def determinator_actor(name, &block)
|
|
14
|
+
@determinator_actors ||= {}
|
|
15
|
+
@determinator_actors[name] = block
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.included(c)
|
|
20
|
+
c.extend(ClassMethods)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def determinator_context
|
|
24
|
+
@determinator_context ||= construct_determinator_actors
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def construct_determinator_actors
|
|
30
|
+
Determinator::Context::Actors.new(
|
|
31
|
+
Determinator.instance,
|
|
32
|
+
self.class.determinator_actors.map{ |k, v| [k, instance_eval(&v)] }.to_h
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Determinator
|
|
2
|
+
module Context
|
|
3
|
+
class Resolver
|
|
4
|
+
attr_reader :actors, :id_path
|
|
5
|
+
|
|
6
|
+
def initialize(actors, controller, id_path, feature: nil)
|
|
7
|
+
@actors = actors
|
|
8
|
+
@controller = controller
|
|
9
|
+
@id_path = id_path
|
|
10
|
+
@feature = feature
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def which_variant(feature_name)
|
|
14
|
+
controller.which_variant(feature_name, id: actors.get(id_path), properties: actors.to_params, feature: feature)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def feature_flag_on?(feature_name)
|
|
18
|
+
controller.feature_flag_on?(feature_name, id: actors.get(id_path), properties: actors.to_params, feature: feature)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
attr_reader :controller, :feature
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'dry-struct'
|
|
2
|
+
|
|
3
|
+
module Determinator
|
|
4
|
+
module Models
|
|
5
|
+
ARGS = [:descr]
|
|
6
|
+
|
|
7
|
+
Element = Struct.new(:type, :description)
|
|
8
|
+
|
|
9
|
+
class Base < Dry::Struct
|
|
10
|
+
class << self
|
|
11
|
+
attr_reader :elements
|
|
12
|
+
|
|
13
|
+
def attribute(name, type, args={})
|
|
14
|
+
super(name, type)
|
|
15
|
+
element(name.to_s.chomp('?').to_sym, type, args)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def attribute?(name, type, args={})
|
|
19
|
+
super(name, type)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def element(name, type, args={})
|
|
23
|
+
if (args.keys - ARGS).length > 0
|
|
24
|
+
raise "Unrecognized arguments #{(args.keys - ARGS).join(', ')}"
|
|
25
|
+
end
|
|
26
|
+
@elements ||= {}
|
|
27
|
+
@elements[name] = Element.new(type, args[:descr])
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def collect_elements(prefix='')
|
|
31
|
+
@elements.map do |k, v|
|
|
32
|
+
if v.type.respond_to?(:collect_elements)
|
|
33
|
+
v.type.collect_elements("#{prefix}#{k}.")
|
|
34
|
+
else
|
|
35
|
+
[["#{prefix}#{k}", v]]
|
|
36
|
+
end
|
|
37
|
+
end.flatten(1)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def with(attributes={})
|
|
42
|
+
self.class.new(attributes.merge(to_h))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require_relative 'drn'
|
|
2
|
+
|
|
3
|
+
module Determinator
|
|
4
|
+
module Models
|
|
5
|
+
module Common
|
|
6
|
+
class City < Base
|
|
7
|
+
attribute :id, Types::Integer
|
|
8
|
+
attribute? :drn, DRN
|
|
9
|
+
attribute :uname, Types::String, descr: 'The unique name (lower case, with dashes)'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require_relative 'drn'
|
|
2
|
+
|
|
3
|
+
module Determinator
|
|
4
|
+
module Models
|
|
5
|
+
module Common
|
|
6
|
+
class Country < Base
|
|
7
|
+
attribute :id, Types::Integer
|
|
8
|
+
attribute? :drn, DRN
|
|
9
|
+
attribute :tld, Types::String, descr: 'The top-level domain for the country'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require_relative 'common/drn'
|
|
2
|
+
|
|
3
|
+
module Determinator
|
|
4
|
+
module Models
|
|
5
|
+
class Customer < Base
|
|
6
|
+
attribute? :drn, Common::DRN
|
|
7
|
+
attribute :id, Types::Integer, descr: 'The Orderweb ID of the customer (user)'
|
|
8
|
+
attribute? :email, Types::String.optional
|
|
9
|
+
attribute :employee, Types::Bool, descr: 'Whether the customer is a Deliveroo employee'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require_relative 'common/country'
|
|
2
|
+
require_relative 'common/city'
|
|
3
|
+
require_relative 'common/zone'
|
|
4
|
+
|
|
5
|
+
module Determinator
|
|
6
|
+
module Models
|
|
7
|
+
class Request < Base
|
|
8
|
+
attribute :uid, Types::String, descr: 'A unique identifier of the request'
|
|
9
|
+
attribute? :country, Common::Country
|
|
10
|
+
attribute? :city, Common::City
|
|
11
|
+
attribute? :zone, Common::Zone
|
|
12
|
+
attribute? :platform, Types::String.constrained(
|
|
13
|
+
included_in: ['bot', 'web', 'ios', 'android', 'signature-api']
|
|
14
|
+
), descr: "Which platform the request is coming from. Can be 'web', 'ios', 'android' or 'bot'."
|
|
15
|
+
attribute? :white_label_brand, Types::String,
|
|
16
|
+
descr: 'The name of the white-label brand the request is coming from, if any'
|
|
17
|
+
attribute? :app_version, Types::String, descr: 'Version of the Android or IOS app'
|
|
18
|
+
attribute? :device_os, Types::String, descr: 'Version of the Device OS'
|
|
19
|
+
attribute? :customer, Determinator.model {
|
|
20
|
+
attribute :guid, Types::String,
|
|
21
|
+
descr: 'Identifies the device. Also known as roo_guid or anonymous_id'
|
|
22
|
+
attribute :session_guid, Types::String.optional,
|
|
23
|
+
descr: 'Identifies a user session. Has different behaviours across platforms, so use with care'
|
|
24
|
+
attribute :sticky_guid, Types::String.optional,
|
|
25
|
+
descr: 'Identifies the user across logouts. Beware of edge cases (see go/track)'
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require_relative 'common/drn'
|
|
2
|
+
require_relative 'common/country'
|
|
3
|
+
require_relative 'common/city'
|
|
4
|
+
require_relative 'common/neighborhood'
|
|
5
|
+
require_relative 'common/zone'
|
|
6
|
+
|
|
7
|
+
module Determinator
|
|
8
|
+
module Models
|
|
9
|
+
class Restaurant < Base
|
|
10
|
+
attribute? :drn, Common::DRN
|
|
11
|
+
attribute? :id, Types::Integer, descr: 'The Orderweb id of the restaurant'
|
|
12
|
+
attribute :country, Common::Country
|
|
13
|
+
attribute :city, Common::City
|
|
14
|
+
attribute :neighborhood, Common::Neighborhood
|
|
15
|
+
attribute :zone, Common::Zone
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require_relative 'common/drn'
|
|
2
|
+
require_relative 'common/country'
|
|
3
|
+
require_relative 'common/zone'
|
|
4
|
+
|
|
5
|
+
module Determinator
|
|
6
|
+
module Models
|
|
7
|
+
class Rider < Base
|
|
8
|
+
attribute? :drn, Common::DRN
|
|
9
|
+
attribute :id, Types::Integer, descr: 'The Orderweb id of the rider'
|
|
10
|
+
attribute :uuid, Types::String
|
|
11
|
+
attribute :zone, Common::Zone
|
|
12
|
+
attribute :country, Common::Country
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Determinator
|
|
2
|
+
def self.model(&block)
|
|
3
|
+
Class.new(Determinator::Models::Base) do
|
|
4
|
+
class_eval(&block)
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'determinator/models/types'
|
|
10
|
+
require 'determinator/models/base'
|
|
11
|
+
require 'determinator/models/customer'
|
|
12
|
+
require 'determinator/models/restaurant'
|
|
13
|
+
require 'determinator/models/request'
|
|
14
|
+
require 'determinator/models/rider'
|
metadata
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: determinator-context
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.11
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ivan Pirlik
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2024-02-05 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: byebug
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '11.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '11.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: determinator
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 2.5.4
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 2.5.4
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: dry-struct
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.0'
|
|
55
|
+
description: Helpers to construct Determinator actors.
|
|
56
|
+
email:
|
|
57
|
+
- ivan.pirlik@deliveroo.co.uk
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- ".circleci/config.yml"
|
|
63
|
+
- ".github/workflows/codeql-analysis.yml"
|
|
64
|
+
- ".github/workflows/codeql-complete.yml"
|
|
65
|
+
- ".gitignore"
|
|
66
|
+
- ".rspec"
|
|
67
|
+
- CHANGELOG.md
|
|
68
|
+
- Gemfile
|
|
69
|
+
- Gemfile.lock
|
|
70
|
+
- README.md
|
|
71
|
+
- Rakefile
|
|
72
|
+
- bin/console
|
|
73
|
+
- bin/setup
|
|
74
|
+
- determinator-context.gemspec
|
|
75
|
+
- lib/determinator/context.rb
|
|
76
|
+
- lib/determinator/context/actors.rb
|
|
77
|
+
- lib/determinator/context/helpers.rb
|
|
78
|
+
- lib/determinator/context/resolver.rb
|
|
79
|
+
- lib/determinator/context/version.rb
|
|
80
|
+
- lib/determinator/models.rb
|
|
81
|
+
- lib/determinator/models/base.rb
|
|
82
|
+
- lib/determinator/models/common/city.rb
|
|
83
|
+
- lib/determinator/models/common/country.rb
|
|
84
|
+
- lib/determinator/models/common/drn.rb
|
|
85
|
+
- lib/determinator/models/common/neighborhood.rb
|
|
86
|
+
- lib/determinator/models/common/zone.rb
|
|
87
|
+
- lib/determinator/models/customer.rb
|
|
88
|
+
- lib/determinator/models/request.rb
|
|
89
|
+
- lib/determinator/models/restaurant.rb
|
|
90
|
+
- lib/determinator/models/rider.rb
|
|
91
|
+
- lib/determinator/models/types.rb
|
|
92
|
+
homepage: https://github.com/deliveroo/determinator-context-rb
|
|
93
|
+
licenses: []
|
|
94
|
+
metadata: {}
|
|
95
|
+
post_install_message:
|
|
96
|
+
rdoc_options: []
|
|
97
|
+
require_paths:
|
|
98
|
+
- lib
|
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 2.3.0
|
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
|
+
requirements:
|
|
106
|
+
- - ">="
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: '0'
|
|
109
|
+
requirements: []
|
|
110
|
+
rubygems_version: 3.1.6
|
|
111
|
+
signing_key:
|
|
112
|
+
specification_version: 4
|
|
113
|
+
summary: Context objects for Determinator
|
|
114
|
+
test_files: []
|