semian-postgres 0.1.1

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
+ SHA256:
3
+ metadata.gz: 4363cbe92367756e749732e77c206c2e270dfce1c076fa704eb3d4dfa32f7c06
4
+ data.tar.gz: bfec19a9865ea7b130564e88242b302d0dc67d8b68bbd685534cac92a2416281
5
+ SHA512:
6
+ metadata.gz: 9325b3f83bee8362219ba95a0d3bd0af58ca184797332bf44b2cf60e4e5e859b1c920d3bcf6015678cfd20617956d88321d1e426c0d999e79b0cd14f9ff69777
7
+ data.tar.gz: e29883327d72551ca75b6cd3d3c2c4e4b3170971e4f33bad9e722308e3011be048dbf4c7d0a4f06ce3e506d72b0c14aa5910aec84e058a91be9e7237a528599b
data/.dockerignore ADDED
@@ -0,0 +1,6 @@
1
+ *
2
+ !lib
3
+ !.rubocop.yml
4
+ !Gemfile*
5
+ !Rakefile
6
+ !semian-postgres.gemspec
data/.gitattributes ADDED
@@ -0,0 +1,3 @@
1
+ Gemfile.lock linguist-generated=true
2
+ *.gemfile.lock linguist-generated=true
3
+ *.gemfile linguist-language=ruby
@@ -0,0 +1,14 @@
1
+ ---
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: github-actions
5
+ directory: /
6
+ schedule:
7
+ interval: daily
8
+ - package-ecosystem: bundler
9
+ directory: /
10
+ open-pull-requests-limit: 10
11
+ insecure-external-code-execution: allow
12
+ registries: "*"
13
+ schedule:
14
+ interval: dails
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: Continuous Integration
3
+
4
+ on:
5
+ push:
6
+ branches: main
7
+ pull_request:
8
+
9
+ concurrency:
10
+ group: ${{ github.ref }}-bundle
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ rubocop:
15
+ name: Rubocop
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v3
20
+
21
+ - uses: ruby/setup-ruby@v1
22
+ with:
23
+ ruby-version: ${{ inputs.ruby }}
24
+ bundler-cache: true
25
+
26
+ - name: Run rubocop
27
+ run: |
28
+ bundle exec rubocop
29
+
30
+ yamllint:
31
+ name: 'Yamllint'
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - name: Checkout
35
+ uses: actions/checkout@v3
36
+
37
+ - name: Yamllint
38
+ uses: karancode/yamllint-github-action@dd59165b84d90d37fc919c3c7dd84c7e37cd6bfb
39
+ with:
40
+ yamllint_comment: true
41
+ env:
42
+ GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43
+ test:
44
+ name: Run specs
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ ruby: ["2.7", "3.0", "3.1"]
49
+ postgres: ["9.6", "10", "11", "12", "13"]
50
+ runs-on: ubuntu-latest
51
+ container:
52
+ image: ruby:${{ matrix.ruby }}
53
+ services:
54
+ postgres:
55
+ image: postgres:${{ matrix.postgres }}
56
+ env:
57
+ POSTGRES_PASSWORD: password
58
+ options: >-
59
+ --health-cmd="pg_isready"
60
+ --health-interval=10s
61
+ --health-timeout=5s
62
+ --health-retries=5
63
+ toxiproxy:
64
+ image: ghcr.io/shopify/toxiproxy:2.5.0
65
+ env:
66
+ CI: "1"
67
+ PGHOST: "postgres"
68
+ PGUSER: "postgres"
69
+ PGPASSWORD: "password"
70
+ TOXIPROXY_HOST: "toxiproxy"
71
+ ImageOS: "ubuntu20"
72
+ steps:
73
+ - name: Checkout
74
+ uses: actions/checkout@v3
75
+
76
+ - name: Cache
77
+ uses: actions/cache@v3
78
+ with:
79
+ path: vendor/bundle
80
+ key: ${{ runner.os }}-ruby-${{ matrix.ruby }}-gems-${{ hashFiles( format('{0}.lock', env.BUNDLE_GEMFILE) ) }}
81
+ restore-keys: |
82
+ ${{ runner.os }}-ruby-${{ matrix.ruby }}-gems-
83
+
84
+ - name: Bundle
85
+ run: |
86
+ bundle config path vendor/bundle
87
+ bundle install
88
+
89
+ - name: Run tests
90
+ run: |
91
+ bundle exec rspec
@@ -0,0 +1,54 @@
1
+ ---
2
+
3
+ name: release-please
4
+
5
+ on:
6
+ push:
7
+ branches: main
8
+
9
+ env:
10
+ GEM_NAME: "semian-postgres"
11
+
12
+ jobs:
13
+ release-please:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v3
18
+
19
+ - uses: google-github-actions/release-please-action@v3
20
+ id: release
21
+ with:
22
+ token: ${{ secrets.GITHUB_TOKEN }}
23
+ release-type: ruby
24
+ bump-minor-pre-major: true
25
+ bump-patch-for-minor-pre-major: true
26
+ prerelease: true
27
+ package-name: ${{ env.GEM_NAME }}
28
+ version-file: "lib/semian/pg/version.rb"
29
+ command: "github-release"
30
+
31
+ - uses: ruby/setup-ruby@v1
32
+ with:
33
+ bundler-cache: true
34
+ if: ${{ steps.release.outputs.release_created }}
35
+
36
+ - name: Build gem
37
+ run: |
38
+ gem build ${{ env.GEM_NAME }}.gemspec -o ${{ env.GEM_NAME }}.gem
39
+ if: ${{ steps.release.outputs.release_created }}
40
+
41
+ release-pr:
42
+ runs-on: ubuntu-latest
43
+ needs:
44
+ - release-please
45
+ steps:
46
+ - uses: google-github-actions/release-please-action@v3
47
+ with:
48
+ token: ${{ secrets.GITHUB_TOKEN }}
49
+ release-type: ruby
50
+ bump-minor-pre-major: true
51
+ bump-patch-for-minor-pre-major: true
52
+ package-name: ${{ env.GEM_NAME }}
53
+ version-file: "lib/semian/pg/version.rb"
54
+ command: "release-pr"
data/.gitignore ADDED
@@ -0,0 +1,31 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /tmp/
10
+
11
+ Used by dotenv library to load environment variables.
12
+ .env
13
+ .idea
14
+
15
+ ## Documentation cache and generated files:
16
+ /.yardoc/
17
+ /_yardoc/
18
+ /doc/
19
+ /rdoc/
20
+
21
+ ## Environment normalization:
22
+ /.bundle/
23
+ /vendor/bundle
24
+ /lib/bundler/man/
25
+
26
+ # Gem packaging
27
+ Gemfile.lock
28
+ .ruby-gemset
29
+ .rvmrc
30
+ .DS_Store
31
+ .rspec_status
@@ -0,0 +1,16 @@
1
+ ---
2
+ repos:
3
+ - repo: https://github.com/pre-commit/pre-commit-hooks
4
+ rev: v4.3.0
5
+ hooks:
6
+ - id: trailing-whitespace
7
+ - id: end-of-file-fixer
8
+ - id: check-yaml
9
+ - repo: https://github.com/mattlqx/pre-commit-ruby
10
+ rev: v1.3.5
11
+ hooks:
12
+ - id: rubocop
13
+ - repo: https://github.com/adrienverge/yamllint.git
14
+ rev: v1.17.0
15
+ hooks:
16
+ - id: yamllint
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,26 @@
1
+ ---
2
+ require:
3
+ - rubocop-rspec
4
+ - rubocop-rake
5
+
6
+ AllCops:
7
+ NewCops: enable
8
+ TargetRubyVersion: 2.7
9
+
10
+ Metrics/MethodLength:
11
+ Enabled: 50
12
+
13
+ RSpec/MultipleExpectations:
14
+ Enabled: false
15
+
16
+ RSpec/ExampleLength:
17
+ Enabled: 25
18
+
19
+ RSpec/MultipleMemoizedHelpers:
20
+ Enabled: 10
21
+
22
+ Layout/LineLength:
23
+ Enabled: 160
24
+
25
+ RSpec/Capybara/FeatureMethods:
26
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.1.2
data/.yamllint ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ extends: default
3
+ rules:
4
+ line-length:
5
+ max: 120
6
+ level: warning
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## [0.1.1](https://github.com/mschoenlaub/semian-postgres/compare/v0.1.0...v0.1.1) (2022-10-31)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * Fix repo URL in gemspec ([8b3e9b0](https://github.com/mschoenlaub/semian-postgres/commit/8b3e9b0aee2ef259ee2f1b0572ff5d561cf993fe))
9
+
10
+ ## 0.1.0 (2022-10-31)
11
+
12
+
13
+ ### Features
14
+
15
+ * initial release ([74885ee](https://github.com/mschoenlaub/semian-postgres/commit/74885ee9b96a1cb42c7dbcb63730b8a68628dd5f))
data/Dockerfile ADDED
@@ -0,0 +1,20 @@
1
+ ARG RUBY_VERSION=3.1.2
2
+ FROM ruby:${RUBY_VERSION} as base
3
+
4
+ # Avoid warnings by switching to noninteractive
5
+ ENV DEBIAN_FRONTEND=noninteractive
6
+
7
+ RUN apt-get update && apt-get install --no-install-recommends -y \
8
+ build-essential \
9
+ libssl-dev \
10
+ postgresql-client \
11
+ libpq-dev \
12
+ netcat \
13
+ && rm -rf /var/lib/apt/lists/* \
14
+ && gem install bundler
15
+
16
+ WORKDIR /app
17
+ COPY . .
18
+ RUN chmod +x scripts/*.sh
19
+ RUN bundle install
20
+ CMD ["/bin/bash"]
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in semian-pg.gemspec
6
+ gemspec
7
+
8
+ gem 'rake', '~> 12.0'
9
+
10
+ group :test do
11
+ gem 'rspec', '~> 3.0'
12
+ gem 'ruby-debug-ide', '~> 0.7.3'
13
+ gem 'timecop', '~> 0.9.1'
14
+ gem 'toxiproxy', '~> 2.0 '
15
+ end
16
+
17
+ group :lint do
18
+ gem 'rubocop', require: false
19
+ gem 'rubocop-rake', require: false
20
+ gem 'rubocop-rspec', require: false
21
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Manuel Schönlaub
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # semian-postgres
2
+
3
+ This library provides a Postgres adapter for [Semian](https://github.com/Shopify/semian) by wrapping the [pg gem](https://rubygems.org/gems/pg)
4
+ Semian is a resiliency toolkit for Ruby applications that provides a way to protect your application from external failures by limiting the number of resources that can be used at a time.
5
+ You can read more about Semian [here](https://github.com/Shopify/semian)).
6
+
7
+ ## Usage
8
+
9
+ Add the gem to your `Gemfile` and require it in your application.
10
+
11
+ ```ruby
12
+ gem 'semian-pg', require: %w(semian semian/pg)
13
+ ```
14
+
15
+
16
+ ## Configuration
17
+
18
+ The adapter is configured by a callback function, which would be ideally defined in some sort of initialization file.
19
+ For Rails applications these would usually live in the `config/initializers/` directory.
20
+
21
+
22
+ ### Minimal example
23
+ The following example configures an adapter to open the circuit after three unsuccessful
24
+ connection attempts and close it after each successful attempt.
25
+
26
+ Bulkheading is disabled, because this is not supported with servers that have a thread-oriented model, such as [Puma](https://github.com/puma/puma)
27
+
28
+ ```ruby
29
+ require "semian"
30
+ require "semian/postgres"
31
+
32
+ SEMIAN_PARAMETERS = {
33
+ circuit_breaker: true,
34
+ success_threshold: 1,
35
+ error_threshold: 3,
36
+ error_timeout: 3,
37
+ bulkhead: false,
38
+ }
39
+
40
+ Semian::PG.semian_configuration = proc do |host, port|
41
+ if host == "localhost" && port == 5432
42
+ return SEMIAN_PARAMETERS
43
+ end
44
+ end
45
+
46
+ conn = PG.connect(host: "example.com", port: 5432)
47
+ conn.exec("SELECT 1")
48
+ ```
49
+
50
+
51
+ ## Development
52
+ Semian, and by extension semian-postgres, currently depends on Linux for **Bulkheading**.
53
+
54
+ The development environment is based on `docker-compose`, spinning up containers for Postgres and Toxiproxy.
55
+ Additionally a `dev` container is spun up. The `Gemfile` contains `ruby-debug-ide` to support remote debugging from the IDE.
56
+
57
+ A typical development workflow would be to run the tests in the `dev` container
58
+ ```bash
59
+ docker compose up -d
60
+ docker compose exec dev bin/setup
61
+ docker compose exec dev rake rubocop spec
62
+ ```
63
+
64
+
65
+ ## Contributing
66
+
67
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/mschoenlaub/semian-postgres).
68
+
69
+
70
+ ## License
71
+
72
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
6
+
7
+ RuboCop::RakeTask.new
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'bundler/setup'
6
+ require 'semian/pg'
7
+
8
+ # You can add fixtures and/or initialization code here to make experimenting
9
+ # with your gem easier. You can also use a different console, if you like.
10
+
11
+ # (If you use this, don't forget to add pry to your Gemfile!)
12
+ # require "pry"
13
+ # Pry.start
14
+
15
+ require 'irb'
16
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,31 @@
1
+ ---
2
+ version: "3.7"
3
+ services:
4
+ dev:
5
+ environment:
6
+ DEBUG: "1"
7
+ PGHOST: "postgres"
8
+ PGUSER: "postgres"
9
+ PGPASSWORD: "password"
10
+ TOXIPROXY_HOST: "toxiproxy"
11
+ build:
12
+ context: ./
13
+ dockerfile: Dockerfile
14
+ container_name: semian-dev
15
+ volumes:
16
+ - .:/app
17
+ command:
18
+ - /bin/bash
19
+ - -c
20
+ - |
21
+ bundle install
22
+ sleep infinity
23
+ toxiproxy:
24
+ image: ghcr.io/shopify/toxiproxy:2.5.0
25
+ container_name: toxiproxy
26
+ depends_on:
27
+ - postgres
28
+ postgres:
29
+ image: postgres
30
+ environment:
31
+ POSTGRES_PASSWORD: password
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Semian
4
+ module PG
5
+ VERSION = '0.1.1'
6
+ end
7
+ end
data/lib/semian/pg.rb ADDED
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'semian/pg/version'
4
+ require 'semian/adapter'
5
+ require 'pg'
6
+
7
+ # We need to patch the actual pg gem to decorate the base errors such as PG::Error
8
+ module PG
9
+ ::PG::Error.include(Semian::AdapterError)
10
+ ::PG::QueryCanceled.class_eval do
11
+ def marks_semian_circuits?
12
+ message != ~/canceling statement due to statement timeout/
13
+ end
14
+ end
15
+
16
+ # This allows us to use semian as a drop-in replacement.
17
+ class SemianError < PG::Error
18
+ def initialize(semian_identifier, *args)
19
+ super(*args)
20
+ @semian_identifier = semian_identifier
21
+ end
22
+ end
23
+
24
+ ResourceBusyError = Class.new(SemianError)
25
+ CircuitOpenError = Class.new(SemianError)
26
+ end
27
+
28
+ module Semian
29
+ # The adapter wraps the PG::Connection class and implements the methods for resource acquisition.
30
+ module PG
31
+ include Semian::Adapter
32
+
33
+ ResourceBusyError = ::PG::ResourceBusyError
34
+ CircuitOpenError = ::PG::CircuitOpenError
35
+
36
+ # This error is raised when the configuration hook is modified more than once.
37
+ class ConfigurationChangedError < RuntimeError
38
+ def initialize(msg = 'Cannot re-initialize semian_configuration')
39
+ super
40
+ end
41
+ end
42
+
43
+ class << self
44
+ attr_accessor :exceptions
45
+ attr_reader :semian_configuration
46
+
47
+ def semian_configuration=(configuration)
48
+ raise ConfigurationChangedError unless @semian_configuration.nil?
49
+
50
+ @semian_configuration = configuration
51
+ end
52
+
53
+ def retrieve_semian_configuration(host, port)
54
+ @semian_configuration.call(host, port) if @semian_configuration.respond_to?(:call)
55
+ end
56
+ end
57
+
58
+ def conninfo_hash
59
+ h = super
60
+ h.merge!(connect_timeout: @connect_timeout) if @connect_timeout
61
+ h
62
+ end
63
+
64
+ def semian_identifier
65
+ @semian_identifier ||= "pg_#{raw_semian_options[:name]}" if raw_semian_options && raw_semian_options[:name]
66
+ @semian_identifier ||= "pg_#{@iopts[:host]}:#{@iopts[:port]}"
67
+ end
68
+
69
+ def raw_semian_options
70
+ @raw_semian_options ||= begin
71
+ @raw_semian_options = Semian::PG.retrieve_semian_configuration(@iopts[:host], @iopts[:port])
72
+ @raw_semian_options = @raw_semian_options.dup unless @raw_semian_options.nil?
73
+ end
74
+ end
75
+
76
+ def disabled?
77
+ raw_semian_options.nil?
78
+ end
79
+
80
+ def resource_exceptions
81
+ [::PG::ConnectionBad, ::PG::QueryCanceled].freeze
82
+ end
83
+
84
+ def async_connect_or_reset(*args)
85
+ acquire_semian_resource(adapter: :pg, scope: :connection) do
86
+ super
87
+ end
88
+ end
89
+
90
+ QUERY_WHITELIST = Regexp.union(
91
+ %r{\A(?:/\*.*?\*/)?\s*ROLLBACK}i,
92
+ %r{\A(?:/\*.*?\*/)?\s*COMMIT}i,
93
+ %r{\A(?:/\*.*?\*/)?\s*RELEASE\s+SAVEPOINT}i
94
+ )
95
+
96
+ QUERY_METHODS = %i[query exec exec_params].freeze
97
+
98
+ def query_whitelisted?(sql)
99
+ QUERY_WHITELIST =~ sql
100
+ rescue ArgumentError
101
+ return false unless sql.valid_encoding?
102
+
103
+ raise
104
+ end
105
+
106
+ QUERY_METHODS.each do |method|
107
+ define_method(method) do |*args|
108
+ return super(*args) if query_whitelisted?(args[0])
109
+
110
+ acquire_semian_resource(adapter: :pg, scope: :query) do
111
+ super(*args)
112
+ end
113
+ end
114
+ end
115
+
116
+ def with_resource_timeout(temp_timeout)
117
+ prev_conn_timeout = conninfo_hash[:connect_timeout]
118
+ begin
119
+ @connect_timeout = temp_timeout
120
+ yield
121
+ ensure
122
+ @connect_timeout = prev_conn_timeout
123
+ end
124
+ end
125
+
126
+ # The pg gem defines some necessary methods on class level, which is why we have to hook into them.
127
+ module ClassMethods
128
+ def connect_start(*args)
129
+ conn = super
130
+ conn.instance_variable_set(:@iopts, _iopts(*args))
131
+ conn
132
+ end
133
+
134
+ private
135
+
136
+ def _iopts(*args) # rubocop:disable Metrics/AbcSize
137
+ option_string = parse_connect_args(*args)
138
+ iopts = conninfo_parse(option_string).each_with_object({}) do |h, o|
139
+ o[h[:keyword].to_sym] = h[:val] if h[:val]
140
+ end
141
+ conndefaults.each_with_object({}) { |h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }.merge(iopts)
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ ::PG::Connection.prepend(Semian::PG)
148
+ ::PG::Connection.singleton_class.prepend(Semian::PG::ClassMethods)
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/semian/pg/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'semian-postgres'
7
+ spec.version = Semian::PG::VERSION
8
+ spec.homepage = 'https://github.com/mschoenlaub/semian-postgres'
9
+ spec.authors = ['Manuel Schönlaub']
10
+ spec.email = ['manuel.schonlaub@prodigygame.com']
11
+
12
+ spec.summary = 'Semian adapter for Postgres'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = Gem::Requirement.new('>=2.7.0')
15
+
16
+ spec.add_runtime_dependency 'pg', '~> 1.4.0'
17
+ spec.add_runtime_dependency 'semian', '~> 0.16.0'
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = spec.homepage
21
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/main/CHANGELOG.md"
22
+
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.require_paths = ['lib']
27
+ spec.metadata['rubygems_mfa_required'] = 'true'
28
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: semian-postgres
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Manuel Schönlaub
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-10-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pg
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.4.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: semian
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.16.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.16.0
41
+ description:
42
+ email:
43
+ - manuel.schonlaub@prodigygame.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".dockerignore"
49
+ - ".gitattributes"
50
+ - ".github/.dependabot.yml"
51
+ - ".github/workflows/ci.yml"
52
+ - ".github/workflows/release.yml"
53
+ - ".gitignore"
54
+ - ".pre-commit-config.yaml"
55
+ - ".rspec"
56
+ - ".rubocop.yml"
57
+ - ".ruby-version"
58
+ - ".yamllint"
59
+ - CHANGELOG.md
60
+ - Dockerfile
61
+ - Gemfile
62
+ - LICENSE.txt
63
+ - README.md
64
+ - Rakefile
65
+ - bin/console
66
+ - bin/setup
67
+ - docker-compose.yml
68
+ - lib/semian/pg.rb
69
+ - lib/semian/pg/version.rb
70
+ - semian-postgres.gemspec
71
+ homepage: https://github.com/mschoenlaub/semian-postgres
72
+ licenses:
73
+ - MIT
74
+ metadata:
75
+ homepage_uri: https://github.com/mschoenlaub/semian-postgres
76
+ source_code_uri: https://github.com/mschoenlaub/semian-postgres
77
+ changelog_uri: https://github.com/mschoenlaub/semian-postgres/main/CHANGELOG.md
78
+ rubygems_mfa_required: 'true'
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: 2.7.0
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubygems_version: 3.3.7
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Semian adapter for Postgres
98
+ test_files: []