prodder 1.7.6 → 1.8.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 +4 -4
- data/.github/workflows/ci.yml +55 -0
- data/config/database.yml.github-actions +8 -0
- data/features/commit.feature +3 -3
- data/features/dump.feature +7 -7
- data/features/support/prodder__blog_prod.sql +1 -0
- data/lib/prodder/pg.rb +1 -3
- data/lib/prodder/prodder.rake +9 -9
- data/lib/prodder/project.rb +1 -4
- data/lib/prodder/version.rb +1 -1
- metadata +19 -6
- data/.travis.yml +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e8921f51e1bb936a99eaccc98d04bcd34ff72acbe20cb5547f6e680f8e4106a
|
4
|
+
data.tar.gz: 0e47795334cfcd4944d877dd5c24ab72e4fa5b082d66400b5c0a318228ba0f5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12817961230a0fd95776ff3bdf4a95b62fb8b961bbf2db9d93413f8cf93c32a9f11c4e036ffd89b0e4e5c0807ef40cf5d342706b0cd7a1f214c1f9c3a840547b
|
7
|
+
data.tar.gz: 34c918bd1587a1c055ffd76866028a5cd7e7c371c42cec0381e01294af4f308b5478d59f2406a8d5dea73755e5c16cb0d33b2b206e8a450448cceca6b5a2b748
|
@@ -0,0 +1,55 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
workflow_dispatch:
|
5
|
+
push:
|
6
|
+
branches:
|
7
|
+
- main
|
8
|
+
pull_request:
|
9
|
+
|
10
|
+
permissions:
|
11
|
+
contents: read
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
test:
|
15
|
+
runs-on: ubuntu-latest
|
16
|
+
strategy:
|
17
|
+
matrix:
|
18
|
+
ruby-version: [2.6, 2.7, 3.0]
|
19
|
+
services:
|
20
|
+
postgres:
|
21
|
+
image: postgres:12.1-alpine
|
22
|
+
ports:
|
23
|
+
- 5432:5432
|
24
|
+
env:
|
25
|
+
POSTGRES_USER: postgres
|
26
|
+
POSTGRES_PASSWORD: postgres
|
27
|
+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
28
|
+
steps:
|
29
|
+
- name: Checkout Project
|
30
|
+
uses: actions/checkout@v3
|
31
|
+
|
32
|
+
- name: Set up Ruby
|
33
|
+
uses: ruby/setup-ruby@v1
|
34
|
+
with:
|
35
|
+
ruby-version: ${{ matrix.ruby-version }}
|
36
|
+
bundler-cache: true
|
37
|
+
|
38
|
+
- name: Install Library Dependencies
|
39
|
+
run: sudo apt-get install libpq-dev
|
40
|
+
|
41
|
+
- name: Setup Database
|
42
|
+
run: |
|
43
|
+
cp config/database.yml.github-actions config/database.yml
|
44
|
+
env:
|
45
|
+
RAILS_ENV: test
|
46
|
+
POSTGRES_USER: postgres
|
47
|
+
POSTGRES_PASSWORD: postgres
|
48
|
+
|
49
|
+
- name: Test with RSpec
|
50
|
+
env:
|
51
|
+
RAILS_ENV: "test"
|
52
|
+
POSTGRES_USER: postgres
|
53
|
+
POSTGRES_PASSWORD: postgres
|
54
|
+
run: |
|
55
|
+
bundle exec rspec
|
data/features/commit.feature
CHANGED
@@ -29,7 +29,7 @@ Feature: Commiting updated dumps to a project's repository
|
|
29
29
|
And I run `prodder dump -c prodder.yml`
|
30
30
|
And I run `prodder commit -c prodder.yml`
|
31
31
|
And 2 commits by "prodder auto-commit" should be in the "blog" repository
|
32
|
-
And the latest commit should have changed "db/structure.sql" to contain "CREATE TABLE linkbacks"
|
32
|
+
And the latest commit should have changed "db/structure.sql" to contain "CREATE TABLE public.linkbacks"
|
33
33
|
And the latest commit should not have changed "db/seeds.sql"
|
34
34
|
And the latest commit should not have changed "db/quality_checks.sql"
|
35
35
|
|
@@ -52,7 +52,7 @@ Feature: Commiting updated dumps to a project's repository
|
|
52
52
|
And I run `prodder dump -c prodder.yml`
|
53
53
|
And I run `prodder commit -c prodder.yml`
|
54
54
|
Then 2 commits by "prodder auto-commit" should be in the "blog" repository
|
55
|
-
And the latest commit should have changed "db/structure.sql" to contain "CREATE TABLE captchas"
|
55
|
+
And the latest commit should have changed "db/structure.sql" to contain "CREATE TABLE public.captchas"
|
56
56
|
And the latest commit should have changed "db/seeds.sql" to contain "Bob McBobbington"
|
57
57
|
And the latest commit should not have changed "db/quality_checks.sql"
|
58
58
|
|
@@ -64,6 +64,6 @@ Feature: Commiting updated dumps to a project's repository
|
|
64
64
|
And I run `prodder dump -c prodder.yml`
|
65
65
|
And I run `prodder commit -c prodder.yml`
|
66
66
|
And 2 commits by "prodder auto-commit" should be in the "blog" repository
|
67
|
-
And the latest commit should have changed "db/permissions.sql" to contain "GRANT ALL ON TABLE gotchas TO prodder"
|
67
|
+
And the latest commit should have changed "db/permissions.sql" to contain "GRANT ALL ON TABLE public.gotchas TO prodder"
|
68
68
|
And the latest commit should not have changed "db/seeds.sql"
|
69
69
|
And the latest commit should not have changed "db/quality_checks.sql"
|
data/features/dump.feature
CHANGED
@@ -6,11 +6,10 @@ Feature: prodder dump
|
|
6
6
|
Scenario: Happy path: dump structure.sql, listed seed tables, quality_checks.sql, permissions.sql and settings.sql
|
7
7
|
When I run `prodder dump -c prodder.yml`
|
8
8
|
Then the exit status should be 0
|
9
|
-
And the workspace file "blog/db/structure.sql" should match /CREATE TABLE posts/
|
10
|
-
And the workspace file "blog/db/structure.sql" should match /CREATE TABLE authors/
|
11
|
-
And the workspace file "blog/db/seeds.sql" should match /COPY posts/
|
12
|
-
And the workspace file "blog/db/seeds.sql" should match /COPY authors/
|
13
|
-
And the workspace file "blog/db/quality_checks.sql" should match /SET search_path/
|
9
|
+
And the workspace file "blog/db/structure.sql" should match /CREATE TABLE public.posts/
|
10
|
+
And the workspace file "blog/db/structure.sql" should match /CREATE TABLE public.authors/
|
11
|
+
And the workspace file "blog/db/seeds.sql" should match /COPY public.posts/
|
12
|
+
And the workspace file "blog/db/seeds.sql" should match /COPY public.authors/
|
14
13
|
And the workspace file "blog/db/quality_checks.sql" should match /CREATE TRIGGER /
|
15
14
|
And the workspace file "blog/db/permissions.sql" should match /GRANT /
|
16
15
|
And the workspace file "blog/db/settings.sql" should match /ALTER DATABASE /
|
@@ -123,6 +122,7 @@ Feature: prodder dump
|
|
123
122
|
Given I add a custom parameter "c.p" with value "v" in the "blog" project's database
|
124
123
|
When I run `prodder dump -c prodder.yml`
|
125
124
|
Then the workspace file "blog/db/settings.sql" should match /ALTER DATABASE :DBNAME SET c.p=v;/
|
125
|
+
And the workspace file "blog/db/settings.sql" should match /ALTER DATABASE :DBNAME SET search_path=foo,bar,public;/
|
126
126
|
|
127
127
|
Scenario: Verify empty db setting is quoted
|
128
128
|
Given I add a custom parameter "empty.setting" with value "" in the "blog" project's database
|
@@ -184,8 +184,8 @@ Feature: prodder dump
|
|
184
184
|
"""
|
185
185
|
When I run `prodder dump -c prodder.yml`
|
186
186
|
Then the exit status should be 0
|
187
|
-
And the workspace file "blog/db/seeds.sql" should match /COPY posts/
|
188
|
-
But the workspace file "blog/db/seeds.sql" should not match /COPY authors/
|
187
|
+
And the workspace file "blog/db/seeds.sql" should match /COPY public.posts/
|
188
|
+
But the workspace file "blog/db/seeds.sql" should not match /COPY public.authors/
|
189
189
|
|
190
190
|
Scenario: YAML file listing seed tables does not exist
|
191
191
|
Given the prodder config in "prodder.yml" says to read the "blog" seed tables from "db/seeds.yml"
|
data/lib/prodder/pg.rb
CHANGED
@@ -125,7 +125,6 @@ module Prodder
|
|
125
125
|
ACL_REVOKE = /^REVOKE /
|
126
126
|
DEFAULT_PRIVILEGES = /^ALTER DEFAULT PRIVILEGES /
|
127
127
|
SET_OBJECT_OWNERSHIP = /.* OWNER TO /
|
128
|
-
SEARCH_PATH = /SET search_path = .*/
|
129
128
|
|
130
129
|
def dump_db_access_control(db_name, user_list, options)
|
131
130
|
perm_out_sql = ""
|
@@ -153,8 +152,7 @@ module Prodder
|
|
153
152
|
if line.match(ACL_GRANT) ||
|
154
153
|
line.match(ACL_REVOKE) ||
|
155
154
|
line.match(DEFAULT_PRIVILEGES) ||
|
156
|
-
line.match(SET_OBJECT_OWNERSHIP)
|
157
|
-
line.match(SEARCH_PATH)
|
155
|
+
line.match(SET_OBJECT_OWNERSHIP)
|
158
156
|
|
159
157
|
unless irrelevant_login_roles.include?(line.match(/ (\S*);$/)[1])
|
160
158
|
perm_out_sql << line
|
data/lib/prodder/prodder.rake
CHANGED
@@ -169,7 +169,7 @@ namespace :db do
|
|
169
169
|
end
|
170
170
|
as("superuser", in: environments) do
|
171
171
|
ActiveRecord::Tasks::DatabaseTasks.create_current
|
172
|
-
|
172
|
+
Rails.configuration.database_configuration.each do |env, config|
|
173
173
|
if environments.include?(env) && config["migration_user"] && config['database']
|
174
174
|
set_psql_env config
|
175
175
|
`psql --no-psqlrc --command "ALTER DATABASE #{config['database']} OWNER TO #{config['migration_user']}" #{Shellwords.escape(config['database'])}`
|
@@ -182,7 +182,7 @@ namespace :db do
|
|
182
182
|
task :all => dependencies do
|
183
183
|
as("superuser") do
|
184
184
|
ActiveRecord::Tasks::DatabaseTasks.create_all
|
185
|
-
|
185
|
+
Rails.configuration.database_configuration.each do |env, config|
|
186
186
|
if config["migration_user"] && config['database']
|
187
187
|
set_psql_env config
|
188
188
|
`psql --no-psqlrc --command "ALTER DATABASE #{config['database']} OWNER TO #{config['migration_user']}" #{Shellwords.escape(config['database'])}`
|
@@ -204,7 +204,7 @@ namespace :db do
|
|
204
204
|
desc "Load db/structure.sql into the current environment's database"
|
205
205
|
task :load => dependencies do
|
206
206
|
as("superuser", in: ENV['RAILS_ENV'] || Rails.env) do
|
207
|
-
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env]
|
207
|
+
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env].with_indifferent_access
|
208
208
|
set_psql_env config
|
209
209
|
puts "Loading db/structure.sql into database '#{config['database']}'"
|
210
210
|
`psql --no-psqlrc -f db/structure.sql #{Shellwords.escape(config['database'])}`
|
@@ -217,7 +217,7 @@ namespace :db do
|
|
217
217
|
task :seed => dependencies do
|
218
218
|
if File.exist?('db/seeds.sql')
|
219
219
|
as("superuser", in: ENV['RAILS_ENV'] || Rails.env) do
|
220
|
-
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env]
|
220
|
+
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env].with_indifferent_access
|
221
221
|
set_psql_env config
|
222
222
|
puts "Loading db/seeds.sql into database '#{config['database']}'"
|
223
223
|
`psql --no-psqlrc -f db/seeds.sql #{Shellwords.escape(config['database'])}`
|
@@ -232,7 +232,7 @@ namespace :db do
|
|
232
232
|
task :quality_check => dependencies do
|
233
233
|
if File.exist?('db/quality_checks.sql')
|
234
234
|
as("superuser", in: ENV['RAILS_ENV'] || Rails.env) do
|
235
|
-
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env]
|
235
|
+
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env].with_indifferent_access
|
236
236
|
set_psql_env config
|
237
237
|
puts "Loading db/quality_checks.sql into database '#{config['database']}'"
|
238
238
|
`psql --no-psqlrc -f db/quality_checks.sql #{Shellwords.escape(config['database'])}`
|
@@ -247,7 +247,7 @@ namespace :db do
|
|
247
247
|
task :permission => dependencies do
|
248
248
|
if File.exist?('db/permissions.sql')
|
249
249
|
as("superuser", in: ENV['RAILS_ENV'] || Rails.env) do
|
250
|
-
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env]
|
250
|
+
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env].with_indifferent_access
|
251
251
|
set_psql_env config
|
252
252
|
puts "Loading db/permissions.sql into database '#{config['database']}'"
|
253
253
|
result = ActiveRecord::Base.connection.execute(<<-SQL).first
|
@@ -268,7 +268,7 @@ namespace :db do
|
|
268
268
|
task :settings => dependencies do
|
269
269
|
if File.exist?('db/settings.sql')
|
270
270
|
as("superuser", in: ENV['RAILS_ENV'] || Rails.env) do
|
271
|
-
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env]
|
271
|
+
config = ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env].with_indifferent_access
|
272
272
|
set_psql_env config
|
273
273
|
puts "Loading db/settings.sql into database '#{config['database']}'"
|
274
274
|
result = ActiveRecord::Base.connection.execute(<<-SQL).first
|
@@ -362,7 +362,7 @@ namespace :db do
|
|
362
362
|
|
363
363
|
def as(user, opts = {}, &block)
|
364
364
|
if File.exist?('db/permissions.sql')
|
365
|
-
config, config_was =
|
365
|
+
config, config_was = Rails.configuration.database_configuration, ActiveRecord::Base.configurations.deep_dup
|
366
366
|
in_env = Array(opts[:in]) || config.keys
|
367
367
|
if config.all? { |env, config_hash| in_env.include?(env) ? config_hash[user] : true }
|
368
368
|
disconnect
|
@@ -393,5 +393,5 @@ end
|
|
393
393
|
|
394
394
|
# Yes, I really want migrations to run against the test DB.
|
395
395
|
Rake::Task['db:migrate'].actions.unshift(proc {
|
396
|
-
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env])
|
396
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ENV['RAILS_ENV'] || Rails.env].with_indifferent_access)
|
397
397
|
})
|
data/lib/prodder/project.rb
CHANGED
@@ -45,11 +45,8 @@ module Prodder
|
|
45
45
|
contents = File.readlines(structure_file_name)
|
46
46
|
rgx = /^\-\- .* Type: INDEX; |^\-\- .* Type: TRIGGER; |^\-\- .* Type: FK CONSTRAINT; /
|
47
47
|
structure, *quality = contents.slice_before(rgx).to_a
|
48
|
-
# the first search path setting for constraints gets left over
|
49
|
-
# in the structure, so we need to *attempt* to grab that
|
50
|
-
quality_checks = (structure.grep(/SET search_path/).last || '') + quality.join
|
51
48
|
|
52
|
-
File.open(quality_check_file_name, 'w') { |f| f.write(
|
49
|
+
File.open(quality_check_file_name, 'w') { |f| f.write(quality.join) }
|
53
50
|
File.open(structure_file_name, 'w') { |f| f.write(structure.join) }
|
54
51
|
end
|
55
52
|
|
data/lib/prodder/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prodder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Hargraves
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deject
|
@@ -32,13 +32,14 @@ executables:
|
|
32
32
|
extensions: []
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
|
+
- ".github/workflows/ci.yml"
|
35
36
|
- ".gitignore"
|
36
|
-
- ".travis.yml"
|
37
37
|
- Gemfile
|
38
38
|
- LICENSE.txt
|
39
39
|
- README.md
|
40
40
|
- Rakefile
|
41
41
|
- bin/prodder
|
42
|
+
- config/database.yml.github-actions
|
42
43
|
- features/commit.feature
|
43
44
|
- features/dump.feature
|
44
45
|
- features/init.feature
|
@@ -81,10 +82,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
82
|
- !ruby/object:Gem::Version
|
82
83
|
version: '0'
|
83
84
|
requirements: []
|
84
|
-
|
85
|
-
rubygems_version: 2.7.7
|
85
|
+
rubygems_version: 3.0.3.1
|
86
86
|
signing_key:
|
87
87
|
specification_version: 4
|
88
88
|
summary: Maintain your Rails apps' structure, seed and quality_checks files using
|
89
89
|
production dumps
|
90
|
-
test_files:
|
90
|
+
test_files:
|
91
|
+
- features/commit.feature
|
92
|
+
- features/dump.feature
|
93
|
+
- features/init.feature
|
94
|
+
- features/lint.feature
|
95
|
+
- features/prodder.feature
|
96
|
+
- features/push.feature
|
97
|
+
- features/step_definitions/git_steps.rb
|
98
|
+
- features/step_definitions/prodder_steps.rb
|
99
|
+
- features/support/blog.git.tgz
|
100
|
+
- features/support/env.rb
|
101
|
+
- features/support/prodder__blog_prod.sql
|
102
|
+
- spec/config_spec.rb
|
103
|
+
- spec/spec_helper.rb
|
data/.travis.yml
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
cache: bundler
|
3
|
-
|
4
|
-
rvm:
|
5
|
-
- 2.4.2
|
6
|
-
- 2.3.5
|
7
|
-
- 2.2.8
|
8
|
-
|
9
|
-
env:
|
10
|
-
matrix:
|
11
|
-
- PG_VERSION=9.3
|
12
|
-
- PG_VERSION=9.4
|
13
|
-
- PG_VERSION=9.5
|
14
|
-
|
15
|
-
before_install:
|
16
|
-
- git config --global user.name "Prodder In Travis-CI"
|
17
|
-
- git config --global user.email "prodder@example.com"
|
18
|
-
# install postgresql v9.5
|
19
|
-
- if [[ "$PG_VERSION" = "9.5" ]]; then echo "installing pg9.5"; sudo /etc/init.d/postgresql stop; sudo apt-get -y autoremove; sudo apt-key adv --keyserver keys.gnupg.net --recv-keys 7FCC7D46ACCC4CF8; sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main 9.5" >> /etc/apt/sources.list.d/postgresql.list'; sudo apt-get update; sudo apt-get -y install postgresql-9.5; sudo cp /etc/postgresql/9.4/main/pg_hba.conf /etc/postgresql/9.5/main/pg_hba.conf; sudo sed -i 's/5433/5432/' /etc/postgresql/9.5/main/postgresql.conf; sudo /etc/init.d/postgresql restart; else echo "not installing pg9.5"; fi
|
20
|
-
# setup travis user
|
21
|
-
- if [[ "$PG_VERSION" = "9.5" ]]; then echo "setting up users for pg9.5"; PGUSER=postgres createuser --superuser travis || echo role travis already exists.; fi
|
22
|
-
# setup pg_dump
|
23
|
-
- sudo ln -sfn /usr/lib/postgresql/$PG_VERSION/bin/pg_dump /usr/bin/pg_dump
|
24
|
-
# start up the specific version of PG
|
25
|
-
- sudo -E sh -c 'service postgresql stop'
|
26
|
-
- sleep 5s
|
27
|
-
- sudo -E sh -c 'service postgresql start $PG_VERSION'
|
28
|
-
- psql -U postgres -d postgres -c 'select setting from pg_settings where name = $m$server_version$m$;'
|
29
|
-
|
30
|
-
script:
|
31
|
-
- psql --version
|
32
|
-
- pg_lsclusters
|
33
|
-
- psql -U postgres -d postgres -c 'select 1;'
|
34
|
-
- ls -al `which pg_dump`
|
35
|
-
- bundle exec rake spec
|
36
|
-
- bundle exec rake cucumber
|
37
|
-
|
38
|
-
deploy:
|
39
|
-
provider: rubygems
|
40
|
-
api_key:
|
41
|
-
secure: "UhUkPFhEuI1dLPa4skTUdOBcGY2SEkRP3N9jLDQad04DflV+GutcjrfN1iQxWk59gVt3zqird5FS8SdwCFuOn8DAU9ACtg73xiPPWRRTdzma4Qw+4thuOHcdwPBz3762YFTRyH7IbRTAlxaD6qPz6US3BnYAkJU7C8c30rHLX6cZutjLV4FsvWonkzxcjyEUViVEdBM0kzI+tdBnQovpcM67a9AfxxBZITJLIfIcah1qc/RANpLkUFJCwNyH9oARWsGIvpIKcQEJBhsl04tvbNRLpiMCk1e1RS1bjMdbbx/rVm3C7dvAjUznbr3ON9abgoe6QDDYr6kXPJbylmxFUzA7ftBWjz2nNruRncsohx08LaM4ADRJWKB3XbP5BXkwUgE672Fi20+Z78LwWfjrr3iRVm7u9Mt9pZHG6Ih8Jy64Uq3647kdVZu9APPfn1NZETFG7vLAMZUtPXv7HBkujlq23XdYXax1XYYbYsM0LOlnG6ol2y6OrBrxWIqC+E8UmLXf/+/MS4j3v2RAe7jXh6fFlw+5MjLr3HXqZ12CrAChp22NRPp1OY4Hac4zzRwGeVOgewknpOK7qQfVFFaQoQksU6VaenSx+TxcYOZYuQdrQjfbO6c+Q/vvZ1RoPOEwH0AelkrW2eGqQTNVWIbH5vvfhys68SA8ov8gNnIzMtU="
|
42
|
-
gem: prodder
|
43
|
-
on:
|
44
|
-
tags: true
|
45
|
-
repo: enova/prodder
|