From bb43150903922f24788f69eea68e6649c3ae66da Mon Sep 17 00:00:00 2001 From: simon reilly Date: Fri, 25 Oct 2019 17:19:02 +0100 Subject: [PATCH 01/11] Implement a wroking docker file for ruby,rails,pg version compatability testing --- .ruby-version | 1 - Dockerfile | 17 +++++++++++++++++ Gemfile | 2 +- Makefile | 9 +++++++++ penthouse.gemspec | 13 +++++++------ spec/activerecord_helper.rb | 4 +++- spec/spec_helper.rb | 5 +++-- 7 files changed, 40 insertions(+), 11 deletions(-) delete mode 100644 .ruby-version create mode 100644 Dockerfile create mode 100644 Makefile diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index 276cbf9..0000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.3.0 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..93937be --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +ARG RUBY_VERSION=2.5 +ARG RAILS_VERSION=5.1.4 +ARG PG_VERSION=1.1.4 + +FROM ruby:$RUBY_VERSION-alpine + +RUN apk add --update build-base postgresql-dev tzdata git +RUN gem install bundler -v '2.0.2' + +ENV RUBY_VERSION=$RUBY_VERSION +ENV RAILS_VERSION=$RAILS_VERSION +ENV PG_VERSION=$PG_VERSION + +WORKDIR /app +ADD ./ /app/ + +ENTRYPOINT ["bundle", "exec"] diff --git a/Gemfile b/Gemfile index 3c893fc..f035be8 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ source 'https://rubygems.org' -ruby '2.3.0' +ruby ENV.fetch('RUBY_VERSION', '2.3.0') gemspec diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5217258 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +build: + docker build --build-arg RUBY_VERSION=$(ruby) -t penthouse/ruby-$(ruby) . + +run: + docker run penthouse/ruby-$(ruby) -e "RUBY_VERSION=$(ruby)" ${args} + +bundle-install: + make run ruby=$(ruby) rails=$(rails) pg=$(pg) args="bundle exec install" + diff --git a/penthouse.gemspec b/penthouse.gemspec index b6d9820..4557880 100644 --- a/penthouse.gemspec +++ b/penthouse.gemspec @@ -17,23 +17,24 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] - spec.add_dependency 'bundler', '~> 1.11' + spec.add_dependency 'bundler', '>= 1.11' - spec.add_development_dependency 'bundler', '~> 1.11' + spec.add_development_dependency 'bundler', '>= 1.11' spec.add_development_dependency 'rake', '~> 10.0' spec.add_development_dependency 'yard', '~> 0.8.7.6' # testing spec.add_development_dependency 'rspec', '~> 3.4.0' spec.add_development_dependency 'simplecov', '~> 0.11.2' spec.add_development_dependency 'rubocop', '~> 0.38' + spec.add_development_dependency 'standardrb' # web spec.add_development_dependency 'rack', '~> 1.6.4' # db spec.add_development_dependency 'ar-octopus', '~> 0.8.6' - spec.add_development_dependency 'activesupport', '~> 4.2.6' - spec.add_development_dependency 'activerecord', '~> 4.2.6' - spec.add_development_dependency 'pg' - + spec.add_development_dependency 'activesupport', "~> #{ENV.fetch('RAILS_VERSION', '4.2.2')}" + spec.add_development_dependency 'activerecord', "~> #{ENV.fetch('RAILS_VERSION', '4.2.2')}" + spec.add_development_dependency 'pg', "~> #{ENV.fetch('PG_VERSION', '0.19.0')}" + spec.add_development_dependency 'guard-rspec' spec.add_development_dependency 'pry' end diff --git a/spec/activerecord_helper.rb b/spec/activerecord_helper.rb index 0d81c33..68405e2 100644 --- a/spec/activerecord_helper.rb +++ b/spec/activerecord_helper.rb @@ -1,5 +1,7 @@ -require 'active_record' require 'yaml' require 'pg' +require 'active_record' + +puts ActiveRecord.version ActiveRecord::Base.establish_connection YAML.load_file(File.join(File.dirname(__FILE__), "support/database.yml")).fetch("test") diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 09f2bc5..b2edfbe 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,7 @@ add_filter "/spec/" end -require 'rspec' +require 'bundler/setup' +Bundler.setup + require 'penthouse' -require 'pry' \ No newline at end of file From 6d0f78bfc96c15493c3752d32d2de43a90616e83 Mon Sep 17 00:00:00 2001 From: "simonireilly@gmail.com" Date: Sat, 26 Oct 2019 16:49:29 +0100 Subject: [PATCH 02/11] Continue work on version support through docker --- .dockerignore | 1 + Dockerfile | 17 --------------- Dockerfile.test | 22 ++++++++++++++++++++ Makefile | 24 ++++++++++++++++------ README.md | 32 +++++++++++++++++++++++++++++ docker-compose.yml | 29 ++++++++++++++++++++++++++ lib/penthouse/tenants/migratable.rb | 4 ++-- penthouse.gemspec | 8 ++++---- spec/activerecord_helper.rb | 13 ++++++++++-- spec/octopus_helper.rb | 2 +- spec/support/database.test.yml | 12 +++++++++++ spec/support/octopus.test.yml | 18 ++++++++++++++++ spec/support/structure.sql | 6 +++--- 13 files changed, 153 insertions(+), 35 deletions(-) create mode 100644 .dockerignore delete mode 100644 Dockerfile create mode 100644 Dockerfile.test create mode 100644 docker-compose.yml create mode 100644 spec/support/database.test.yml create mode 100644 spec/support/octopus.test.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b844b14 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +Gemfile.lock diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 93937be..0000000 --- a/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -ARG RUBY_VERSION=2.5 -ARG RAILS_VERSION=5.1.4 -ARG PG_VERSION=1.1.4 - -FROM ruby:$RUBY_VERSION-alpine - -RUN apk add --update build-base postgresql-dev tzdata git -RUN gem install bundler -v '2.0.2' - -ENV RUBY_VERSION=$RUBY_VERSION -ENV RAILS_VERSION=$RAILS_VERSION -ENV PG_VERSION=$PG_VERSION - -WORKDIR /app -ADD ./ /app/ - -ENTRYPOINT ["bundle", "exec"] diff --git a/Dockerfile.test b/Dockerfile.test new file mode 100644 index 0000000..80f19ef --- /dev/null +++ b/Dockerfile.test @@ -0,0 +1,22 @@ +ARG RUBY_VERSION="2.5" + +FROM ruby:$RUBY_VERSION-alpine + +ARG RUBY_VERSION="2.5" +ARG RAILS_VERSION="5.1.4" +ARG PG_VERSION="1.1.4" + +RUN apk add --update build-base postgresql-dev tzdata git + +WORKDIR /app +ADD ./ /app/ + +RUN gem install bundler -v '1.17' + +ENV RUBY_VERSION=$RUBY_VERSION +ENV RAILS_VERSION=$RAILS_VERSION +ENV PG_VERSION=$PG_VERSION + +RUN RUBY_VERSION=$RUBY_VERSION RAILS_VERSION=$RAILS_VERSION PG_VERSION=$PG_VERSION bundle install --jobs=4 --quiet --no-cache + +ENTRYPOINT ["bundle", "exec", "rspec"] diff --git a/Makefile b/Makefile index 5217258..68189af 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,21 @@ -build: - docker build --build-arg RUBY_VERSION=$(ruby) -t penthouse/ruby-$(ruby) . +test-4.2.11.1: # Test rails 4 LTS + RUBY_VERSION=2.3.0 RAILS_VERSION=4.2.11.1 PG_VERSION=0.21.0 docker-compose build + RUBY_VERSION=2.3.0 RAILS_VERSION=4.2.11.1 PG_VERSION=0.21.0 docker-compose run penthouse -run: - docker run penthouse/ruby-$(ruby) -e "RUBY_VERSION=$(ruby)" ${args} +test-5.1.7: # Test rails 5 before migration context + RUBY_VERSION=2.4.0 RAILS_VERSION=5.1.7 PG_VERSION=0.21.0 docker-compose build + RUBY_VERSION=2.4.0 RAILS_VERSION=5.1.7 PG_VERSION=0.21.0 docker-compose run penthouse -bundle-install: - make run ruby=$(ruby) rails=$(rails) pg=$(pg) args="bundle exec install" +test-5.2.3: # Test rails 5 with migration context + RUBY_VERSION=2.5.0 RAILS_VERSION=5.2.3 PG_VERSION=1.1.4 docker-compose build + RUBY_VERSION=2.5.0 RAILS_VERSION=5.2.3 PG_VERSION=1.1.4 docker-compose run penthouse +test-6.0.0: # Test rails 6 + RUBY_VERSION=2.6.0 RAILS_VERSION=6.0.0 PG_VERSION=1.1.4 docker-compose build + RUBY_VERSION=2.6.0 RAILS_VERSION=6.0.0 PG_VERSION=1.1.4 docker-compose run penthouse + +test: + make test-4.2.11.1 + make test-5.1.7 + make test-5.2.3 + make test-6.0.0 diff --git a/README.md b/README.md index 95f39dc..f5e06cf 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,19 @@ +# Penthouse + [![Codeship Status](https://codeship.com/projects/c6513ab0-cc05-0133-94c6-0666c337ff82/status?branch=master)](https://codeship.com/projects/140114) [![Code Climate](https://codeclimate.com/github/ryantownsend/penthouse/badges/gpa.svg)](https://codeclimate.com/github/ryantownsend/penthouse) [![RubyDocs](https://img.shields.io/badge/rubydocs-click_here-blue.svg)](http://www.rubydoc.info/github/ryantownsend/penthouse) Penthouse is an alternative to the excellent [Apartment gem](https://github.com/influitive/apartment) – however Penthouse is more of a framework for multi-tenancy than a library, in that it provides less out-of-the-box functionality, but should make for easier customisation. +- [Penthouse](#penthouse) + - [Installation](#installation) + - [Basic Usage](#basic-usage) + - [Octopus (shard) Usage](#octopus-shard-usage) + - [ActiveJob](#activejob) + - [Sidekiq](#sidekiq) + - [Dictionary](#dictionary) + - [Contributing](#contributing) + - [Testing](#testing) + ## Installation Add this line to your application's Gemfile: @@ -80,3 +92,23 @@ require 'penthouse/sidekiq' ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/ryantownsend/penthouse. + +### Testing + +Docker is used for isolated testing. To test all supported versions run: + +``` +make test +``` + +For specific versions see the `Makefile`. + +Alternatively you can tets any version locally with: + +``` +export RUBY_VERSION=2.5.0 +rbenv local $RUBY_VERSION + +RUBY_VERSION=$RUBY_VERSION RAILS_VERSION=4.2.11.1 PG_VERSION=0.21.0 bundle install +RUBY_VERSION=$RUBY_VERSION RAILS_VERSION=4.2.11.1 PG_VERSION=0.21.0 bundle exec rsepc +``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..91a0269 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3.5' + +services: + postgres: + image: postgres:10.5-alpine + ports: + - 5432 + networks: + penthouse: + default: + + penthouse: + build: + context: . + dockerfile: Dockerfile.test + args: + RUBY_VERSION: ${RUBY_VERSION:-2.5.0} + RAILS_VERSION: ${RAILS_VERSION:-5.1.7} + PG_VERSION: ${PG_VERSION:-1.1.4} + networks: + penthouse: + default: + depends_on: + - postgres + +networks: + penthouse: + driver: bridge + name: shift diff --git a/lib/penthouse/tenants/migratable.rb b/lib/penthouse/tenants/migratable.rb index 3bdc568..0e8b07c 100644 --- a/lib/penthouse/tenants/migratable.rb +++ b/lib/penthouse/tenants/migratable.rb @@ -24,7 +24,7 @@ def migrate(db_schema_file: Penthouse.configuration.db_schema_file) end end - private + private def read_schema(db_schema_file) case db_schema_file.extname @@ -46,7 +46,7 @@ def load_ruby_schema(db_schema_file) def load_sql_schema(db_schema_file) sql = process_schema_file(db_schema_file) - + ActiveRecord::Base.transaction do with_limited_logging { ActiveRecord::Base.connection.execute(sql) } end diff --git a/penthouse.gemspec b/penthouse.gemspec index 4557880..753d8aa 100644 --- a/penthouse.gemspec +++ b/penthouse.gemspec @@ -30,10 +30,10 @@ Gem::Specification.new do |spec| # web spec.add_development_dependency 'rack', '~> 1.6.4' # db - spec.add_development_dependency 'ar-octopus', '~> 0.8.6' - spec.add_development_dependency 'activesupport', "~> #{ENV.fetch('RAILS_VERSION', '4.2.2')}" - spec.add_development_dependency 'activerecord', "~> #{ENV.fetch('RAILS_VERSION', '4.2.2')}" - spec.add_development_dependency 'pg', "~> #{ENV.fetch('PG_VERSION', '0.19.0')}" + spec.add_development_dependency 'ar-octopus', '~> 0.9.1' + spec.add_development_dependency 'activesupport', "#{ENV.fetch('RAILS_VERSION', '4.2.2')}" + spec.add_development_dependency 'activerecord', "#{ENV.fetch('RAILS_VERSION', '4.2.2')}" + spec.add_development_dependency 'pg', "#{ENV.fetch('PG_VERSION', '0.19.0')}" spec.add_development_dependency 'guard-rspec' spec.add_development_dependency 'pry' diff --git a/spec/activerecord_helper.rb b/spec/activerecord_helper.rb index 68405e2..4aa2014 100644 --- a/spec/activerecord_helper.rb +++ b/spec/activerecord_helper.rb @@ -2,6 +2,15 @@ require 'pg' require 'active_record' -puts ActiveRecord.version +# Prepare the databases for testing +ActiveRecord::Base.establish_connection YAML.load_file(File.join(File.dirname(__FILE__), "support/database.test.yml")).fetch("default") +ActiveRecord::Base.connection.create_database("penthouse_test") rescue PG::DuplicateDatabase +ActiveRecord::Base.connection.create_database("penthouse_octopus_one") rescue PG::DuplicateDatabase +ActiveRecord::Base.connection.create_database("penthouse_octopus_two") rescue PG::DuplicateDatabase -ActiveRecord::Base.establish_connection YAML.load_file(File.join(File.dirname(__FILE__), "support/database.yml")).fetch("test") +# Establish the active record connection to the test database +ActiveRecord::Base.establish_connection YAML.load_file(File.join(File.dirname(__FILE__), "support/database.test.yml")).fetch("test") +ActiveRecord::Base.connection.execute(IO.read("./spec/support/structure.sql")) rescue PG::DuplicateTable + +# Log everything executed in the datbase +ActiveRecord::Base.logger = Logger.new(STDOUT) diff --git a/spec/octopus_helper.rb b/spec/octopus_helper.rb index a9d94ca..0086242 100644 --- a/spec/octopus_helper.rb +++ b/spec/octopus_helper.rb @@ -3,5 +3,5 @@ Octopus.setup do |config| config.environments = [:test] - config.shards = YAML.load_file(File.join(File.dirname(__FILE__), "support/octopus.yml")).fetch("octopus").fetch("shards") + config.shards = YAML.load_file(File.join(File.dirname(__FILE__), "support/octopus.test.yml")).fetch("octopus").fetch("shards") end diff --git a/spec/support/database.test.yml b/spec/support/database.test.yml new file mode 100644 index 0000000..87d64f8 --- /dev/null +++ b/spec/support/database.test.yml @@ -0,0 +1,12 @@ +default: &default + host: postgres + adapter: postgresql + encoding: unicode + pool: 10 + port: 5432 + username: postgres + password: + +test: + <<: *default + database: penthouse_test diff --git a/spec/support/octopus.test.yml b/spec/support/octopus.test.yml new file mode 100644 index 0000000..680b369 --- /dev/null +++ b/spec/support/octopus.test.yml @@ -0,0 +1,18 @@ +octopus: + default: &default + host: postgres + adapter: postgresql + encoding: unicode + pool: 10 + port: 5432 + username: postgres + password: admin + + shards: + one: + <<: *default + database: penthouse_octopus_one + + two: + <<: *default + database: penthouse_octopus_two diff --git a/spec/support/structure.sql b/spec/support/structure.sql index cbe9e80..3a8629c 100644 --- a/spec/support/structure.sql +++ b/spec/support/structure.sql @@ -1,7 +1,7 @@ -SELECT pg_catalog.set_config('search_path', '', false); -SET search_path = this_should_get_replaced; +SET search_path = 'public'; -CREATE TABLE public.posts ( + +CREATE TABLE posts ( id integer NOT NULL, title character varying NOT NULL, description character varying NOT NULL, From 8b05b5fdd0eccbc9d8bfcaad147deb3ae481883b Mon Sep 17 00:00:00 2001 From: "simonireilly@gmail.com" Date: Sat, 26 Oct 2019 21:56:35 +0100 Subject: [PATCH 03/11] Linting with standard, running 4.2, 5.1, 5.2 in circleCI --- Gemfile | 4 +- Guardfile | 18 +++--- README.md | 24 +++++++- lib/penthouse.rb | 16 +++--- lib/penthouse/active_job.rb | 4 +- lib/penthouse/app.rb | 2 +- lib/penthouse/migrator.rb | 38 +++---------- lib/penthouse/routers/base_router.rb | 2 - lib/penthouse/routers/subdomain_router.rb | 2 - lib/penthouse/runners/base_runner.rb | 10 ++-- lib/penthouse/runners/schema_runner.rb | 8 +-- lib/penthouse/sidekiq.rb | 9 ++- lib/penthouse/sidekiq/middleware/client.rb | 4 +- lib/penthouse/sidekiq/middleware/server.rb | 2 +- lib/penthouse/tenants/migratable.rb | 13 ++--- .../tenants/octopus_schema_tenant.rb | 5 +- lib/penthouse/tenants/octopus_shard_tenant.rb | 3 +- lib/penthouse/tenants/schema_tenant.rb | 31 +++++------ penthouse.gemspec | 55 +++++++++---------- spec/activerecord_helper.rb | 30 +++++++--- spec/octopus_helper.rb | 4 +- spec/penthouse/configuration_spec.rb | 30 +++++----- .../routers/subdomain_router_spec.rb | 6 +- spec/penthouse/runners/schema_runner_spec.rb | 15 +++-- .../tenants/octopus_schema_tenant_spec.rb | 12 ++-- .../tenants/octopus_shard_tenant_spec.rb | 10 ++-- spec/penthouse/tenants/schema_tenant_spec.rb | 13 ++--- spec/penthouse_spec.rb | 34 ++++++------ spec/spec_helper.rb | 6 +- 29 files changed, 200 insertions(+), 210 deletions(-) diff --git a/Gemfile b/Gemfile index f035be8..d3a8289 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ -source 'https://rubygems.org' -ruby ENV.fetch('RUBY_VERSION', '2.3.0') +source "https://rubygems.org" +ruby ENV.fetch("RUBY_VERSION", "2.3.0") gemspec diff --git a/Guardfile b/Guardfile index f541554..bf2249a 100644 --- a/Guardfile +++ b/Guardfile @@ -41,26 +41,26 @@ guard :rspec, cmd: "bundle exec rspec", failed_mode: :focus do dsl.watch_spec_files_for(ruby.lib_files) # Rails files - rails = dsl.rails(view_extensions: %w(erb haml slim)) + rails = dsl.rails(view_extensions: %w[erb haml slim]) dsl.watch_spec_files_for(rails.app_files) dsl.watch_spec_files_for(rails.views) watch(rails.controllers) do |m| [ - rspec.spec.("routing/#{m[1]}_routing"), - rspec.spec.("controllers/#{m[1]}_controller"), - rspec.spec.("acceptance/#{m[1]}") + rspec.spec.call("routing/#{m[1]}_routing"), + rspec.spec.call("controllers/#{m[1]}_controller"), + rspec.spec.call("acceptance/#{m[1]}"), ] end # Rails config changes - watch(rails.spec_helper) { rspec.spec_dir } - watch(rails.routes) { "#{rspec.spec_dir}/routing" } - watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" } + watch(rails.spec_helper) { rspec.spec_dir } + watch(rails.routes) { "#{rspec.spec_dir}/routing" } + watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" } # Capybara features specs - watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") } - watch(rails.layouts) { |m| rspec.spec.("features/#{m[1]}") } + watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") } + watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") } # Turnip features and steps watch(%r{^spec/acceptance/(.+)\.feature$}) diff --git a/README.md b/README.md index f5e06cf..943ca54 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,9 @@ Penthouse is an alternative to the excellent [Apartment gem](https://github.com/ - [Sidekiq](#sidekiq) - [Dictionary](#dictionary) - [Contributing](#contributing) - - [Testing](#testing) + - [Testing](#testing) + - [CI/Local](#cilocal) + - [Without Circle](#without-circle) ## Installation @@ -93,11 +95,25 @@ require 'penthouse/sidekiq' Bug reports and pull requests are welcome on GitHub at https://github.com/ryantownsend/penthouse. -### Testing +## Testing -Docker is used for isolated testing. To test all supported versions run: +### CI/Local + +We use circle,a dn it can be used locally with docker. See: + +- [running circle locally](https://circleci.com/docs/2.0/local-cli/) +- [Using postgres with circle](https://circleci.com/docs/2.0/postgres-config/) +```bash +echo | circleci setup +circleci local execute ``` + +### Without Circle + +Docker is used for isolated testing. To test all supported versions run: + +```bash make test ``` @@ -112,3 +128,5 @@ rbenv local $RUBY_VERSION RUBY_VERSION=$RUBY_VERSION RAILS_VERSION=4.2.11.1 PG_VERSION=0.21.0 bundle install RUBY_VERSION=$RUBY_VERSION RAILS_VERSION=4.2.11.1 PG_VERSION=0.21.0 bundle exec rsepc ``` + + diff --git a/lib/penthouse.rb b/lib/penthouse.rb index c6b491a..68bea92 100644 --- a/lib/penthouse.rb +++ b/lib/penthouse.rb @@ -6,7 +6,7 @@ module Penthouse class TenantNotFound < RuntimeError; end - CURRENT_TENANT_KEY = 'penthouse_tenant'.freeze + CURRENT_TENANT_KEY = "penthouse_tenant".freeze class << self # Retrieves the currently active tenant identifier @@ -29,7 +29,7 @@ def tenant=(tenant_identifier) # @param block [Block] the code to execute # @yield [String, Symbol] the identifier for the tenant # @return [void] - def with_tenant(tenant_identifier:, default_tenant: self.tenant, &block) + def with_tenant(tenant_identifier:, default_tenant: tenant, &block) self.tenant = tenant_identifier block.yield(tenant_identifier) ensure @@ -43,7 +43,7 @@ def with_tenant(tenant_identifier:, default_tenant: self.tenant, &block) # @param block [Block] the code to execute # @yield [String, Symbol] the identifier for the tenant # @return [void] - def each_tenant(tenant_identifiers: self.tenant_identifiers, runner: self.configuration.runner, &block) + def each_tenant(tenant_identifiers: self.tenant_identifiers, runner: configuration.runner, &block) tenant_identifiers.each do |tenant_identifier| switch(tenant_identifier: tenant_identifier, runner: runner, &block) end @@ -55,7 +55,7 @@ def each_tenant(tenant_identifiers: self.tenant_identifiers, runner: self.config # @param block [Block] the code to execute # @yield [Penthouse::Tenants::BaseTenant] the tenant instance # @return [void] - def switch(tenant_identifier:, runner: self.configuration.runner, &block) + def switch(tenant_identifier:, runner: configuration.runner, &block) runner.call(tenant_identifier: tenant_identifier, &block) end @@ -63,7 +63,7 @@ def switch(tenant_identifier:, runner: self.configuration.runner, &block) # @param tenant_identifier [String, Symbol] the identifier for the tenant # @see Penthouse::Tenants::BaseTenant#delete # @return [void] - def create(tenant_identifier:, runner: self.configuration.runner, **options) + def create(tenant_identifier:, runner: configuration.runner, **options) switch(tenant_identifier: tenant_identifier, runner: runner) do |tenant| tenant.create(**options) end @@ -73,7 +73,7 @@ def create(tenant_identifier:, runner: self.configuration.runner, **options) # @param tenant_identifier [String, Symbol] the identifier for the tenant # @see Penthouse::Tenants::BaseTenant#delete # @return [void] - def delete(tenant_identifier:, runner: self.configuration.runner, **options) + def delete(tenant_identifier:, runner: configuration.runner, **options) switch(tenant_identifier: tenant_identifier, runner: runner) do |tenant| tenant.delete(**options) end @@ -84,9 +84,9 @@ def delete(tenant_identifier:, runner: self.configuration.runner, **options) # @return [void] def configure(&block) # allow the configuration by the block - block.yield(self.configuration) + block.yield(configuration) # prevent modification of configuration once set - self.configuration.freeze + configuration.freeze end # Returns the current configuration of Penthouse diff --git a/lib/penthouse/active_job.rb b/lib/penthouse/active_job.rb index 9b0c3dd..ff3662a 100644 --- a/lib/penthouse/active_job.rb +++ b/lib/penthouse/active_job.rb @@ -4,14 +4,14 @@ module ActiveJob class_methods do def execute(job_data) - Penthouse.switch(job_data['tenant']) do + Penthouse.switch(job_data["tenant"]) do super end end end def serialize - super.merge('tenant' => Penthouse.tenant) + super.merge("tenant" => Penthouse.tenant) end end end diff --git a/lib/penthouse/app.rb b/lib/penthouse/app.rb index 230ae5b..3244fb6 100644 --- a/lib/penthouse/app.rb +++ b/lib/penthouse/app.rb @@ -9,7 +9,7 @@ # application within that tenant. # -require 'rack/request' +require "rack/request" module Penthouse class App diff --git a/lib/penthouse/migrator.rb b/lib/penthouse/migrator.rb index e92f6a0..b1d0da5 100644 --- a/lib/penthouse/migrator.rb +++ b/lib/penthouse/migrator.rb @@ -1,28 +1,5 @@ -require 'active_record' -require 'active_support/core_ext/module/aliasing' - -module Penthouse - module Migration - def self.included(base) - base.class_eval do - # Verbose form of alias_method_chain which is now deprecated in ActiveSupport. - # - # This replaces the original #annouce method with #announce_with_penthouse - # but allows calling #annouce by using #announce_without_penthouse. - alias_method :announce_without_penthouse, :announce - alias_method :announce, :announce_with_penthouse - end - end - - def announce_with_penthouse(message) - announce_without_penthouse("#{message} - #{current_tenant}") - end - - def current_tenant - "Tenant: #{Penthouse.tenant || '*** global ***'}" - end - end -end +require "active_record" +require "active_support/core_ext/module/aliasing" module Penthouse module Migrator @@ -45,9 +22,9 @@ class << self # override any new Octopus methods with the new Penthouse ones alias_method :migrate_with_octopus, :migrate_with_penthouse - alias_method :up_with_octopus, :up_with_penthouse - alias_method :down_with_octopus, :down_with_penthouse - alias_method :run_with_octopus, :run_with_penthouse + alias_method :up_with_octopus, :up_with_penthouse + alias_method :down_with_octopus, :down_with_penthouse + alias_method :run_with_octopus, :run_with_penthouse end alias_method :migrate_without_penthouse, :migrate @@ -57,7 +34,7 @@ class << self alias_method :migrations, :migrations_with_penthouse # override any new Octopus methods with the new Penthouse ones - alias_method :migrate_with_octopus, :migrate_with_penthouse + alias_method :migrate_with_octopus, :migrate_with_penthouse alias_method :migrations_with_octopus, :migrations_with_penthouse end end @@ -137,5 +114,4 @@ def tenants_to_migrate end end -ActiveRecord::Migration.send(:include, Penthouse::Migration) -ActiveRecord::Migrator.send(:include, Penthouse::Migrator) +ActiveRecord::Migrator.send(:include, Penthouse::Migrator) if ActiveRecord.version.release < Gem::Version.new("5.2.0") diff --git a/lib/penthouse/routers/base_router.rb b/lib/penthouse/routers/base_router.rb index 6640935..e72ef03 100644 --- a/lib/penthouse/routers/base_router.rb +++ b/lib/penthouse/routers/base_router.rb @@ -10,7 +10,6 @@ module Penthouse module Routers class BaseRouter - # @abstract typically used by the App to receive a request and return a tenant that can be switched to # @param request [Rack::Request] The request from the Rack app, used to determine the tenant # @return [String, Symbol] A tenant identifier @@ -18,7 +17,6 @@ class BaseRouter def self.call(request) raise NotImplementedError end - end end end diff --git a/lib/penthouse/routers/subdomain_router.rb b/lib/penthouse/routers/subdomain_router.rb index 0cca62f..556ea2d 100644 --- a/lib/penthouse/routers/subdomain_router.rb +++ b/lib/penthouse/routers/subdomain_router.rb @@ -5,14 +5,12 @@ module Penthouse module Routers class SubdomainRouter < BaseRouter - # Determines the tenant identifier based on the sub-domain of the request # @param request [Rack::Request] The request from the Rack app, used to determine the tenant # @return [String, Symbol] A tenant identifier def self.call(request) request.host.split(".").first end - end end end diff --git a/lib/penthouse/runners/base_runner.rb b/lib/penthouse/runners/base_runner.rb index 3c99ca5..e209577 100644 --- a/lib/penthouse/runners/base_runner.rb +++ b/lib/penthouse/runners/base_runner.rb @@ -10,7 +10,6 @@ module Penthouse module Runners class BaseRunner - PENTHOUSE_RUNNER_CALL_STACK = :current_penthouse_runner_call_stack # @param tenant_identifier [String, Symbol] The identifier for the tenant @@ -18,7 +17,7 @@ class BaseRunner # @return [void] # @raise [Penthouse::TenantNotFound] if the tenant cannot be switched to def call(tenant_identifier:, &block) - previous_tenant_identifier = call_stack.last || 'public' + previous_tenant_identifier = call_stack.last || "public" call_stack.push(tenant_identifier) result = nil @@ -39,16 +38,15 @@ def call(tenant_identifier:, &block) # @param tenant_identifier [String, Symbol] The identifier for the tenant # @return [Penthouse::Tenants::BaseTenant] An instance of a tenant # @raise [Penthouse::TenantNotFound] if the tenant cannot be switched to - def load_tenant(tenant_identifier:, previous_tenant_identifier: 'public') + def load_tenant(tenant_identifier:, previous_tenant_identifier: "public") raise NotImplementedError end - + private - + def call_stack Thread.current[PENTHOUSE_RUNNER_CALL_STACK] ||= [] end - end end end diff --git a/lib/penthouse/runners/schema_runner.rb b/lib/penthouse/runners/schema_runner.rb index 4552aec..37c62b7 100644 --- a/lib/penthouse/runners/schema_runner.rb +++ b/lib/penthouse/runners/schema_runner.rb @@ -2,19 +2,17 @@ # This runner will simply use the SchemaTenant # -require_relative './base_runner' -require_relative '../tenants/schema_tenant' +require_relative "./base_runner" +require_relative "../tenants/schema_tenant" module Penthouse module Runners class SchemaRunner < BaseRunner - # @param tenant_identifier [String, Symbol] The identifier for the tenant # @return [Penthouse::Tenants::BaseTenant] An instance of a tenant - def load_tenant(tenant_identifier:, previous_tenant_identifier: 'public') + def load_tenant(tenant_identifier:, previous_tenant_identifier: "public") Tenants::SchemaTenant.new(identifier: tenant_identifier, tenant_schema: tenant_identifier, previous_schema: previous_tenant_identifier) end - end end end diff --git a/lib/penthouse/sidekiq.rb b/lib/penthouse/sidekiq.rb index 975cb82..a601420 100644 --- a/lib/penthouse/sidekiq.rb +++ b/lib/penthouse/sidekiq.rb @@ -1,11 +1,10 @@ -require 'sidekiq' -require 'penthouse/sidekiq/middleware/client' -require 'penthouse/sidekiq/middleware/server' +require "sidekiq" +require "penthouse/sidekiq/middleware/client" +require "penthouse/sidekiq/middleware/server" module Penthouse module Sidekiq module Middleware - def self.run ::Sidekiq.configure_client do |config| config.client_middleware do |chain| @@ -27,4 +26,4 @@ def self.run end end -require 'penthouse/sidekiq/railtie' if defined?(Rails) +require "penthouse/sidekiq/railtie" if defined?(Rails) diff --git a/lib/penthouse/sidekiq/middleware/client.rb b/lib/penthouse/sidekiq/middleware/client.rb index cc92b29..6757c8b 100644 --- a/lib/penthouse/sidekiq/middleware/client.rb +++ b/lib/penthouse/sidekiq/middleware/client.rb @@ -2,8 +2,8 @@ module Penthouse module Sidekiq module Middleware class Client - def call(worker_class, item, queue, redis_pool=nil) - item['tenant'] ||= Penthouse.tenant + def call(worker_class, item, queue, redis_pool = nil) + item["tenant"] ||= Penthouse.tenant yield end end diff --git a/lib/penthouse/sidekiq/middleware/server.rb b/lib/penthouse/sidekiq/middleware/server.rb index 4a4f87c..b8bca07 100644 --- a/lib/penthouse/sidekiq/middleware/server.rb +++ b/lib/penthouse/sidekiq/middleware/server.rb @@ -3,7 +3,7 @@ module Sidekiq module Middleware class Server def call(worker_class, item, queue) - Penthouse.switch(tenant_identifier: item['tenant']) do + Penthouse.switch(tenant_identifier: item["tenant"]) do yield end end diff --git a/lib/penthouse/tenants/migratable.rb b/lib/penthouse/tenants/migratable.rb index 0e8b07c..5d90478 100644 --- a/lib/penthouse/tenants/migratable.rb +++ b/lib/penthouse/tenants/migratable.rb @@ -10,7 +10,6 @@ module Penthouse module Tenants module Migratable - # @param db_schema_file [String] a path to the DB schema file to load, defaults to Penthouse.configuration.db_schema_file # @return [void] def migrate(db_schema_file: Penthouse.configuration.db_schema_file) @@ -28,9 +27,9 @@ def migrate(db_schema_file: Penthouse.configuration.db_schema_file) def read_schema(db_schema_file) case db_schema_file.extname - when '.rb' + when ".rb" load_ruby_schema(db_schema_file) - when '.sql' + when ".sql" load_sql_schema(db_schema_file) else raise ArgumentError, "Unrecognized schema file extension" @@ -68,10 +67,10 @@ def process_schema_file(db_schema_file) def sanitize_sql(sql) sql - .gsub(/SELECT pg_catalog.set_config\(\'search_path.*;/, '') - .gsub(/SET search_path.*;/, '') - .gsub(/CREATE SCHEMA/, 'CREATE SCHEMA IF NOT EXISTS') - .gsub(/public\./, '') + .gsub(/SELECT pg_catalog.set_config\(\'search_path.*;/, "") + .gsub(/SET search_path.*;/, "") + .gsub(/CREATE SCHEMA/, "CREATE SCHEMA IF NOT EXISTS") + .gsub(/public\./, "") end end end diff --git a/lib/penthouse/tenants/octopus_schema_tenant.rb b/lib/penthouse/tenants/octopus_schema_tenant.rb index 41d2411..10c29bc 100644 --- a/lib/penthouse/tenants/octopus_schema_tenant.rb +++ b/lib/penthouse/tenants/octopus_schema_tenant.rb @@ -7,13 +7,12 @@ # [1]: (https://github.com/thiagopradi/octopus) # -require_relative './schema_tenant' -require 'octopus' +require_relative "./schema_tenant" +require "octopus" module Penthouse module Tenants class OctopusSchemaTenant < SchemaTenant - # ensures we're on the correct Octopus shard, then just updates the schema # name with the tenant name # @param shard [String, Symbol] The shard to execute within, usually master diff --git a/lib/penthouse/tenants/octopus_shard_tenant.rb b/lib/penthouse/tenants/octopus_shard_tenant.rb index c734c2d..2fcfffe 100644 --- a/lib/penthouse/tenants/octopus_shard_tenant.rb +++ b/lib/penthouse/tenants/octopus_shard_tenant.rb @@ -6,12 +6,11 @@ # [1]: (https://github.com/thiagopradi/octopus) # -require_relative './octopus_schema_tenant' +require_relative "./octopus_schema_tenant" module Penthouse module Tenants class OctopusShardTenant < OctopusSchemaTenant - attr_accessor :shard private :shard= diff --git a/lib/penthouse/tenants/schema_tenant.rb b/lib/penthouse/tenants/schema_tenant.rb index e17e6f4..716a853 100644 --- a/lib/penthouse/tenants/schema_tenant.rb +++ b/lib/penthouse/tenants/schema_tenant.rb @@ -5,9 +5,9 @@ # shared. # -require_relative './base_tenant' -require_relative './migratable' -require 'active_record' +require_relative "./base_tenant" +require_relative "./migratable" +require "active_record" module Penthouse module Tenants @@ -37,16 +37,14 @@ def initialize(identifier:, tenant_schema:, persistent_schemas: ["shared_extensi # @yield [SchemaTenant] The current tenant instance # @return [void] def call(&block) - begin - # set the search path to include the tenant - ActiveRecord::Base.connection.schema_search_path = persistent_schemas.dup.unshift(tenant_schema).join(", ") - ActiveRecord::Base.connection.clear_query_cache - block.yield(self) - ensure - # reset the search path back to the default - ActiveRecord::Base.connection.schema_search_path = persistent_schemas.dup.unshift(previous_schema).join(", ") - ActiveRecord::Base.connection.clear_query_cache - end + # set the search path to include the tenant + ActiveRecord::Base.connection.schema_search_path = persistent_schemas.dup.unshift(tenant_schema).join(", ") + ActiveRecord::Base.connection.clear_query_cache + block.yield(self) + ensure + # reset the search path back to the default + ActiveRecord::Base.connection.schema_search_path = persistent_schemas.dup.unshift(previous_schema).join(", ") + ActiveRecord::Base.connection.clear_query_cache end # creates the tenant schema @@ -55,7 +53,7 @@ def call(&block) # @return [void] def create(run_migrations: Penthouse.configuration.migrate_tenants?, db_schema_file: Penthouse.configuration.db_schema_file) sql = ActiveRecord::Base.send(:sanitize_sql_array, ["create schema if not exists %s", tenant_schema]) - ActiveRecord::Base.connection.exec_query(sql, 'Create Schema') + ActiveRecord::Base.connection.exec_query(sql, "Create Schema") if !!run_migrations migrate(db_schema_file: db_schema_file) end @@ -65,8 +63,8 @@ def create(run_migrations: Penthouse.configuration.migrate_tenants?, db_schema_f # @param force [Boolean] whether or not to drop the schema if not empty, defaults to true # @return [void] def delete(force: true) - sql = ActiveRecord::Base.send(:sanitize_sql_array, ["drop schema if exists %s %s", tenant_schema, force ? 'cascade' : 'restrict']) - ActiveRecord::Base.connection.exec_query(sql, 'Delete Schema') + sql = ActiveRecord::Base.send(:sanitize_sql_array, ["drop schema if exists %s %s", tenant_schema, force ? "cascade" : "restrict"]) + ActiveRecord::Base.connection.exec_query(sql, "Delete Schema") end # returns whether or not this tenant's schema exists @@ -76,7 +74,6 @@ def exists?(**) result = ActiveRecord::Base.connection.exec_query(sql, "Schema Exists") !result.rows.empty? end - end end end diff --git a/penthouse.gemspec b/penthouse.gemspec index 753d8aa..71da0fe 100644 --- a/penthouse.gemspec +++ b/penthouse.gemspec @@ -1,40 +1,39 @@ -# coding: utf-8 -lib = File.expand_path('../lib', __FILE__) +lib = File.expand_path("../lib", __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require 'penthouse/version' +require "penthouse/version" Gem::Specification.new do |spec| - spec.name = 'penthouse' - spec.version = Penthouse::VERSION - spec.authors = ['Ryan Townsend'] - spec.email = ['ryan@ryantownsend.co.uk'] + spec.name = "penthouse" + spec.version = Penthouse::VERSION + spec.authors = ["Ryan Townsend"] + spec.email = ["ryan@ryantownsend.co.uk"] - spec.summary = %q{Multi-tenancy framework. Out of the box, supports Postgres schemas and per-tenant databases} - spec.homepage = 'https://github.com/shiftcommerce/penthouse' + spec.summary = "Multi-tenancy framework. Out of the box, supports Postgres schemas and per-tenant databases" + spec.homepage = "https://github.com/shiftcommerce/penthouse" - spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - spec.bindir = 'exe' - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = ['lib'] + spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] - spec.add_dependency 'bundler', '>= 1.11' + spec.add_dependency "bundler", ">= 1.11" - spec.add_development_dependency 'bundler', '>= 1.11' - spec.add_development_dependency 'rake', '~> 10.0' - spec.add_development_dependency 'yard', '~> 0.8.7.6' + spec.add_development_dependency "bundler", ">= 1.11" + spec.add_development_dependency "rake", "~> 10.0" + spec.add_development_dependency "yard", "~> 0.8.7.6" # testing - spec.add_development_dependency 'rspec', '~> 3.4.0' - spec.add_development_dependency 'simplecov', '~> 0.11.2' - spec.add_development_dependency 'rubocop', '~> 0.38' - spec.add_development_dependency 'standardrb' + spec.add_development_dependency "rspec", "~> 3.4.0" + spec.add_development_dependency "simplecov", "~> 0.11.2" + spec.add_development_dependency "rubocop", "~> 0.38" + spec.add_development_dependency "standardrb" # web - spec.add_development_dependency 'rack', '~> 1.6.4' + spec.add_development_dependency "rack", "~> 1.6.4" # db - spec.add_development_dependency 'ar-octopus', '~> 0.9.1' - spec.add_development_dependency 'activesupport', "#{ENV.fetch('RAILS_VERSION', '4.2.2')}" - spec.add_development_dependency 'activerecord', "#{ENV.fetch('RAILS_VERSION', '4.2.2')}" - spec.add_development_dependency 'pg', "#{ENV.fetch('PG_VERSION', '0.19.0')}" + spec.add_development_dependency "ar-octopus", "~> 0.10.2" + spec.add_development_dependency "activesupport", ENV.fetch("RAILS_VERSION", "4.2.2").to_s + spec.add_development_dependency "activerecord", ENV.fetch("RAILS_VERSION", "4.2.2").to_s + spec.add_development_dependency "pg", ENV.fetch("PG_VERSION", "0.19.0").to_s - spec.add_development_dependency 'guard-rspec' - spec.add_development_dependency 'pry' + spec.add_development_dependency "guard-rspec" + spec.add_development_dependency "pry" end diff --git a/spec/activerecord_helper.rb b/spec/activerecord_helper.rb index 4aa2014..9bc0b48 100644 --- a/spec/activerecord_helper.rb +++ b/spec/activerecord_helper.rb @@ -1,16 +1,32 @@ -require 'yaml' -require 'pg' -require 'active_record' +require "yaml" +require "pg" +require "active_record" # Prepare the databases for testing ActiveRecord::Base.establish_connection YAML.load_file(File.join(File.dirname(__FILE__), "support/database.test.yml")).fetch("default") -ActiveRecord::Base.connection.create_database("penthouse_test") rescue PG::DuplicateDatabase -ActiveRecord::Base.connection.create_database("penthouse_octopus_one") rescue PG::DuplicateDatabase -ActiveRecord::Base.connection.create_database("penthouse_octopus_two") rescue PG::DuplicateDatabase +begin + ActiveRecord::Base.connection.create_database("penthouse_test") +rescue + PG::DuplicateDatabase +end +begin + ActiveRecord::Base.connection.create_database("penthouse_octopus_one") +rescue + PG::DuplicateDatabase +end +begin + ActiveRecord::Base.connection.create_database("penthouse_octopus_two") +rescue + PG::DuplicateDatabase +end # Establish the active record connection to the test database ActiveRecord::Base.establish_connection YAML.load_file(File.join(File.dirname(__FILE__), "support/database.test.yml")).fetch("test") -ActiveRecord::Base.connection.execute(IO.read("./spec/support/structure.sql")) rescue PG::DuplicateTable +begin + ActiveRecord::Base.connection.execute(IO.read("./spec/support/structure.sql")) +rescue + PG::DuplicateTable +end # Log everything executed in the datbase ActiveRecord::Base.logger = Logger.new(STDOUT) diff --git a/spec/octopus_helper.rb b/spec/octopus_helper.rb index 0086242..b58178a 100644 --- a/spec/octopus_helper.rb +++ b/spec/octopus_helper.rb @@ -1,5 +1,5 @@ -require_relative './activerecord_helper' -require 'octopus' +require_relative "./activerecord_helper" +require "octopus" Octopus.setup do |config| config.environments = [:test] diff --git a/spec/penthouse/configuration_spec.rb b/spec/penthouse/configuration_spec.rb index b46ae03..30e42e2 100644 --- a/spec/penthouse/configuration_spec.rb +++ b/spec/penthouse/configuration_spec.rb @@ -1,29 +1,29 @@ -require 'spec_helper' -require 'penthouse/configuration' +require "spec_helper" +require "penthouse/configuration" RSpec.describe Penthouse::Configuration do - describe '.new' do - context 'with migrations but no DB schema file' do - it 'should raise an ArgumentError' do - expect do + describe ".new" do + context "with migrations but no DB schema file" do + it "should raise an ArgumentError" do + expect { described_class.new(migrate_tenants: true) - end.to raise_error(ArgumentError) + }.to raise_error(ArgumentError) end end - context 'with migrations and a non-existant schema file' do - it 'should raise an ArgumentError' do - expect do + context "with migrations and a non-existant schema file" do + it "should raise an ArgumentError" do + expect { described_class.new(migrate_tenants: true, db_schema_file: "/tmp/bla") - end.to raise_error(ArgumentError) + }.to raise_error(ArgumentError) end end - context 'with migrations and a valid schema file' do - it 'should raise an ArgumentError' do - expect do + context "with migrations and a valid schema file" do + it "should raise an ArgumentError" do + expect { described_class.new(migrate_tenants: true, db_schema_file: File.join(File.dirname(__FILE__), "../support/schema.rb")) - end.to_not raise_error(ArgumentError) + }.to_not raise_error(ArgumentError) end end end diff --git a/spec/penthouse/routers/subdomain_router_spec.rb b/spec/penthouse/routers/subdomain_router_spec.rb index 6f4aa2f..f71d5b1 100644 --- a/spec/penthouse/routers/subdomain_router_spec.rb +++ b/spec/penthouse/routers/subdomain_router_spec.rb @@ -1,6 +1,6 @@ -require 'spec_helper' -require 'penthouse/routers/subdomain_router' -require 'rack/request' +require "spec_helper" +require "penthouse/routers/subdomain_router" +require "rack/request" RSpec.describe Penthouse::Routers::SubdomainRouter do describe ".call" do diff --git a/spec/penthouse/runners/schema_runner_spec.rb b/spec/penthouse/runners/schema_runner_spec.rb index 2e1b030..0ce4ab1 100644 --- a/spec/penthouse/runners/schema_runner_spec.rb +++ b/spec/penthouse/runners/schema_runner_spec.rb @@ -1,6 +1,6 @@ -require 'spec_helper' -require 'activerecord_helper' -require 'penthouse/runners/schema_runner' +require "spec_helper" +require "activerecord_helper" +require "penthouse/runners/schema_runner" RSpec.describe Penthouse::Runners::SchemaRunner do let(:schema_name) { "schema_runner_test" } @@ -17,20 +17,19 @@ expect(ActiveRecord::Base.connection.schema_search_path).to include(schema_name) end end - + it "should honour nested switches to the relevant Postgres schema" do - schema_1 = 'schema_1' - schema_2 = 'schema_2' + schema_1 = "schema_1" + schema_2 = "schema_2" runner.call(tenant_identifier: schema_1) do runner.call(tenant_identifier: schema_2) do expect(ActiveRecord::Base.connection.schema_search_path).not_to include(schema_1) expect(ActiveRecord::Base.connection.schema_search_path).to include(schema_2) end - expect(ActiveRecord::Base.connection.schema_search_path).not_to include('public') + expect(ActiveRecord::Base.connection.schema_search_path).not_to include("public") expect(ActiveRecord::Base.connection.schema_search_path).to include(schema_1) expect(ActiveRecord::Base.connection.schema_search_path).not_to include(schema_2) end end - end end diff --git a/spec/penthouse/tenants/octopus_schema_tenant_spec.rb b/spec/penthouse/tenants/octopus_schema_tenant_spec.rb index 776c642..8d7cbed 100644 --- a/spec/penthouse/tenants/octopus_schema_tenant_spec.rb +++ b/spec/penthouse/tenants/octopus_schema_tenant_spec.rb @@ -1,14 +1,14 @@ -require 'spec_helper' -require 'octopus_helper' -require 'penthouse/tenants/octopus_schema_tenant' -require_relative '../../support/models' +require "spec_helper" +require "octopus_helper" +require "penthouse/tenants/octopus_schema_tenant" +require_relative "../../support/models" RSpec.describe Penthouse::Tenants::OctopusSchemaTenant do let(:schema_name) { "octopus_schema_tenant_test" } let(:persistent_schemas) { ["shared_extensions"] } let(:default_schema) { "public" } - let(:db_schema_file) { Pathname.new(File.join(File.dirname(__FILE__), '../../support/schema.rb')) } - let(:db_structure_file) { Pathname.new(File.join(File.dirname(__FILE__), '../../support/structure.sql')) } + let(:db_schema_file) { Pathname.new(File.join(File.dirname(__FILE__), "../../support/schema.rb")) } + let(:db_structure_file) { Pathname.new(File.join(File.dirname(__FILE__), "../../support/structure.sql")) } subject(:octopus_schema_tenant) { described_class.new( diff --git a/spec/penthouse/tenants/octopus_shard_tenant_spec.rb b/spec/penthouse/tenants/octopus_shard_tenant_spec.rb index 4d5f60b..d698f1f 100644 --- a/spec/penthouse/tenants/octopus_shard_tenant_spec.rb +++ b/spec/penthouse/tenants/octopus_shard_tenant_spec.rb @@ -1,6 +1,6 @@ -require 'spec_helper' -require 'octopus_helper' -require 'penthouse/tenants/octopus_shard_tenant' +require "spec_helper" +require "octopus_helper" +require "penthouse/tenants/octopus_shard_tenant" RSpec.describe Penthouse::Tenants::OctopusShardTenant do subject { described_class.new(identifier: shard_name, shard: shard_name) } @@ -20,9 +20,9 @@ let(:shard_name) { "invalid_shard" } it "should raise an exception" do - expect do + expect { subject.call { true } - end.to raise_error(RuntimeError) + }.to raise_error(RuntimeError) end end end diff --git a/spec/penthouse/tenants/schema_tenant_spec.rb b/spec/penthouse/tenants/schema_tenant_spec.rb index 4703ba0..60bdf00 100644 --- a/spec/penthouse/tenants/schema_tenant_spec.rb +++ b/spec/penthouse/tenants/schema_tenant_spec.rb @@ -1,6 +1,6 @@ -require 'spec_helper' -require 'activerecord_helper' -require 'penthouse/tenants/schema_tenant' +require "spec_helper" +require "activerecord_helper" +require "penthouse/tenants/schema_tenant" RSpec.describe Penthouse::Tenants::SchemaTenant do let(:schema_name) { "schema_tenant_test" } @@ -9,10 +9,9 @@ subject(:schema_tenant) do described_class.new(identifier: schema_name, - tenant_schema: schema_name, - persistent_schemas: persistent_schemas, - default_schema: default_schema - ) + tenant_schema: schema_name, + persistent_schemas: persistent_schemas, + default_schema: default_schema) end describe "#call" do diff --git a/spec/penthouse_spec.rb b/spec/penthouse_spec.rb index f1f2e96..9ac5cf6 100644 --- a/spec/penthouse_spec.rb +++ b/spec/penthouse_spec.rb @@ -1,21 +1,20 @@ -require 'spec_helper' -require 'penthouse/tenants/base_tenant' +require "spec_helper" +require "penthouse/tenants/base_tenant" RSpec.describe Penthouse do - subject(:penthouse) { described_class } - TestTenant = Class.new(Penthouse::Tenants::BaseTenant) do + TestTenant = Class.new(Penthouse::Tenants::BaseTenant) { def call(&block) block.yield(self) end - end + } - TestRunner = Class.new(Penthouse::Runners::BaseRunner) do + TestRunner = Class.new(Penthouse::Runners::BaseRunner) { def load_tenant(tenant_identifier:, **args) TestTenant.new(identifier: tenant_identifier) end - end + } let(:runner) { TestRunner.new } @@ -25,12 +24,12 @@ def load_tenant(tenant_identifier:, **args) it "should set the tenant on the current thread" do penthouse.tenant = "main_thread" expect(penthouse.tenant).to eq("main_thread") - (1..3).to_a.map do |i| + (1..3).to_a.map { |i| Thread.new do penthouse.tenant = "thread_#{i}" expect(penthouse.tenant).to eq("thread_#{i}") end - end.each(&:join) + }.each(&:join) expect(penthouse.tenant).to eq("main_thread") end end @@ -52,13 +51,13 @@ def load_tenant(tenant_identifier:, **args) fit "should use the proc defined by the configuration" do penthouse.configure do |config| - config.tenants = Proc.new { { one: "one", two: "two", three: "three" } } + config.tenants = proc { {one: "one", two: "two", three: "three"} } end @tenants = [] penthouse.each_tenant(runner: runner) do |tenant| @tenants.push(tenant.identifier) end - expect(@tenants).to eq(%i(one two three)) + expect(@tenants).to eq(%i[one two three]) end end @@ -73,7 +72,7 @@ def load_tenant(tenant_identifier:, **args) config.router = router_class config.runner = runner_class config.migrate_tenants = true - config.tenants = Proc.new { Hash.new } + config.tenants = proc { {} } end expect(subject.configuration.router).to eq(router_class) expect(subject.configuration.runner).to eq(runner_class) @@ -91,8 +90,8 @@ def load_tenant(tenant_identifier:, **args) end expect(penthouse.tenant).to eq(original_tenant) end - - it 'should honour nested switches' do + + it "should honour nested switches" do penthouse.switch(tenant_identifier: "outer_test", runner: runner) do |tenant| penthouse.switch(tenant_identifier: "inner_test", runner: runner) do |tenant| expect(penthouse.tenant).to eq("inner_test") @@ -103,7 +102,6 @@ def load_tenant(tenant_identifier:, **args) end expect(penthouse.tenant).to eq(original_tenant) end - end context "when tenants are configured" do @@ -111,19 +109,19 @@ def load_tenant(tenant_identifier:, **args) before(:each) do subject.configure do |config| - config.tenants = Proc.new { { one: "one", two: "two", three: "three" } } + config.tenants = proc { {one: "one", two: "two", three: "three"} } end end describe ".tenant_identifiers" do it "should return an array of the tenant keys" do - expect(subject.tenant_identifiers).to eq(%i(one two three)) + expect(subject.tenant_identifiers).to eq(%i[one two three]) end end describe ".tenants" do it "should return a hash as the result of the proc" do - expect(subject.tenants).to eq({ one: "one", two: "two", three: "three" }) + expect(subject.tenants).to eq({one: "one", two: "two", three: "three"}) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b2edfbe..286ddcf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,9 +1,9 @@ -require 'simplecov' +require "simplecov" SimpleCov.start do add_filter "/spec/" end -require 'bundler/setup' +require "bundler/setup" Bundler.setup -require 'penthouse' +require "penthouse" From 5436602c264a1c581217c022ae482c448ac624da Mon Sep 17 00:00:00 2001 From: "simonireilly@gmail.com" Date: Sat, 26 Oct 2019 21:56:52 +0100 Subject: [PATCH 04/11] Attempted fix for MigrationContext --- .circleci/config.yml | 26 +++++++ lib/penthouse/migration.rb | 27 +++++++ lib/penthouse/migration_context.rb | 112 +++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 .circleci/config.yml create mode 100644 lib/penthouse/migration.rb create mode 100644 lib/penthouse/migration_context.rb diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..b742949 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,26 @@ +version: 2 +jobs: + build: + docker: + - image: circleci/ruby:2.4.1 + + - image: circleci/postgres:9.6.2-alpine + name: postgres + + steps: + - checkout + + - run: bundle install + - run: bundle exec standardrb + - run: rm Gemfile.lock + + - run: RUBY_VERSION=2.4.1 RAILS_VERSION=4.2.11.1 PG_VERSION=0.21.0 bundle install + - run: RUBY_VERSION=2.4.1 RAILS_VERSION=4.2.11.1 PG_VERSION=0.21.0 bundle exec rspec + - run: rm Gemfile.lock + + - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.1.7 PG_VERSION=0.21.0 bundle install + - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.1.7 PG_VERSION=0.21.0 bundle exec rspec + - run: rm Gemfile.lock + + - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.2.3 PG_VERSION=0.21.0 bundle install + - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.2.3 PG_VERSION=0.21.0 bundle exec rspec diff --git a/lib/penthouse/migration.rb b/lib/penthouse/migration.rb new file mode 100644 index 0000000..77fe0c1 --- /dev/null +++ b/lib/penthouse/migration.rb @@ -0,0 +1,27 @@ +require "active_record" +require "active_support/core_ext/module/aliasing" + +module Penthouse + module Migration + def self.included(base) + base.class_eval do + # Verbose form of alias_method_chain which is now deprecated in ActiveSupport. + # + # This replaces the original #annouce method with #announce_with_penthouse + # but allows calling #annouce by using #announce_without_penthouse. + alias_method :announce_without_penthouse, :announce + alias_method :announce, :announce_with_penthouse + end + end + + def announce_with_penthouse(message) + announce_without_penthouse("#{message} - #{current_tenant}") + end + + def current_tenant + "Tenant: #{Penthouse.tenant || "*** global ***"}" + end + end +end + +ActiveRecord::Migration.send(:include, Penthouse::Migration) diff --git a/lib/penthouse/migration_context.rb b/lib/penthouse/migration_context.rb new file mode 100644 index 0000000..2783759 --- /dev/null +++ b/lib/penthouse/migration_context.rb @@ -0,0 +1,112 @@ +require "active_record" +require "active_support/core_ext/module/aliasing" + +module Penthouse + module MigrationContext + def self.included(base) + base.extend(ClassMethods) + + base.class_eval do + alias_method :migrate_without_penthouse, :migrate + alias_method :migrate, :migrate_with_penthouse + + alias_method :up_without_penthouse, :up + alias_method :up, :up_with_penthouse + + alias_method :down_without_penthouse, :down + alias_method :down, :down_with_penthouse + + alias_method :run_without_penthouse, :run + alias_method :run, :run_with_penthouse + + # override any new Octopus methods with the new Penthouse ones + alias_method :migrate_with_octopus, :migrate_with_penthouse + alias_method :up_with_octopus, :up_with_penthouse + alias_method :down_with_octopus, :down_with_penthouse + alias_method :run_with_octopus, :run_with_penthouse + + alias_method :migrations_without_penthouse, :migrations + alias_method :migrations, :migrations_with_penthouse + + # override any new Octopus methods with the new Penthouse ones + alias_method :migrate_with_octopus, :migrate_with_penthouse + alias_method :migrations_with_octopus, :migrations_with_penthouse + end + end + + # this may seem stupid but it gets around issues with Octopus + def migrate_with_penthouse(*args) + migrate_without_penthouse(*args) + end + + # this may seem stupid but it gets around issues with Octopus + def migrations_with_penthouse + migrations_without_penthouse + end + + module ClassMethods + def migrate_with_penthouse(migrations_paths, target_version = nil, &block) + unless Penthouse.configuration.migrate_tenants? + return migrate_without_penthouse(migrations_paths, target_version, &block) + end + + wrap_penthouse do + migrate_without_penthouse(migrations_paths, target_version, &block) + end + end + + def up_with_penthouse(migrations_paths, target_version = nil, &block) + unless Penthouse.configuration.migrate_tenants? + return up_without_penthouse(migrations_paths, target_version, &block) + end + + wrap_penthouse do + up_without_penthouse(migrations_paths, target_version) + end + end + + def down_with_penthouse(migrations_paths, target_version = nil, &block) + unless Penthouse.configuration.migrate_tenants? + return down_without_penthouse(migrations_paths, target_version) + end + + wrap_penthouse do + down_without_penthouse(migrations_paths, target_version) + end + end + + def run_with_penthouse(direction, migrations_paths, target_version) + unless Penthouse.configuration.migrate_tenants? + return run_without_penthouse(direction, migrations_paths, target_version) + end + + wrap_penthouse do + run_without_penthouse(direction, migrations_paths, target_version) + end + end + + private + + def wrap_penthouse(&block) + if Penthouse.tenant + block.yield + else + Penthouse.each_tenant(tenant_identifiers: tenants_to_migrate, &block) + end + end + + def tenants_to_migrate + return @tenants_to_migrate if defined?(@tenants_to_migrate) + @tenants_to_migrate = begin + if !!(t = (ENV["TENANT"] || ENV["TENANTS"])) + t.split(",").map(&:strip) + else + Penthouse.tenant_identifiers + end + end + end + end + end +end + +ActiveRecord::MigrationContext.send(:include, Penthouse::MigrationContext) if ActiveRecord.version.release > Gem::Version.new("5.2.0") From fcd861d4195f9c68f0cf262815eb917239235e2d Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 31 Oct 2019 20:14:47 +0000 Subject: [PATCH 05/11] Clean up the gemspec and remove old methods --- Dockerfile.test | 2 +- Gemfile | 7 +++++++ docker-compose.yml | 3 ++- lib/penthouse/migration_context.rb | 24 ++++++++++++------------ penthouse.gemspec | 6 +++--- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Dockerfile.test b/Dockerfile.test index 80f19ef..e82b3d6 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -17,6 +17,6 @@ ENV RUBY_VERSION=$RUBY_VERSION ENV RAILS_VERSION=$RAILS_VERSION ENV PG_VERSION=$PG_VERSION -RUN RUBY_VERSION=$RUBY_VERSION RAILS_VERSION=$RAILS_VERSION PG_VERSION=$PG_VERSION bundle install --jobs=4 --quiet --no-cache +RUN RUBY_VERSION=$RUBY_VERSION RAILS_VERSION=$RAILS_VERSION PG_VERSION=$PG_VERSION bundle install --jobs=4 --no-cache ENTRYPOINT ["bundle", "exec", "rspec"] diff --git a/Gemfile b/Gemfile index d3a8289..565e00d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,10 @@ source "https://rubygems.org" ruby ENV.fetch("RUBY_VERSION", "2.3.0") + +group :test do + gem "activesupport", ENV.fetch("RAILS_VERSION", "4.2.2").to_s + gem "activerecord", ENV.fetch("RAILS_VERSION", "4.2.2").to_s + gem "pg", ENV.fetch("PG_VERSION", "0.19.0").to_s +end + gemspec diff --git a/docker-compose.yml b/docker-compose.yml index 91a0269..d7d2a4f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,7 @@ services: RUBY_VERSION: ${RUBY_VERSION:-2.5.0} RAILS_VERSION: ${RAILS_VERSION:-5.1.7} PG_VERSION: ${PG_VERSION:-1.1.4} + RAILS_ENV: test networks: penthouse: default: @@ -26,4 +27,4 @@ services: networks: penthouse: driver: bridge - name: shift + name: penthouse diff --git a/lib/penthouse/migration_context.rb b/lib/penthouse/migration_context.rb index 2783759..750ce62 100644 --- a/lib/penthouse/migration_context.rb +++ b/lib/penthouse/migration_context.rb @@ -45,43 +45,43 @@ def migrations_with_penthouse end module ClassMethods - def migrate_with_penthouse(migrations_paths, target_version = nil, &block) + def migrate_with_penthouse(target_version = nil, &block) unless Penthouse.configuration.migrate_tenants? - return migrate_without_penthouse(migrations_paths, target_version, &block) + return migrate_without_penthouse(target_version, &block) end wrap_penthouse do - migrate_without_penthouse(migrations_paths, target_version, &block) + migrate_without_penthouse(target_version, &block) end end - def up_with_penthouse(migrations_paths, target_version = nil, &block) + def up_with_penthouse(target_version = nil, &block) unless Penthouse.configuration.migrate_tenants? - return up_without_penthouse(migrations_paths, target_version, &block) + return up_without_penthouse(target_version, &block) end wrap_penthouse do - up_without_penthouse(migrations_paths, target_version) + up_without_penthouse(target_version) end end - def down_with_penthouse(migrations_paths, target_version = nil, &block) + def down_with_penthouse(target_version = nil, &block) unless Penthouse.configuration.migrate_tenants? - return down_without_penthouse(migrations_paths, target_version) + return down_without_penthouse(target_version) end wrap_penthouse do - down_without_penthouse(migrations_paths, target_version) + down_without_penthouse(target_version) end end - def run_with_penthouse(direction, migrations_paths, target_version) + def run_with_penthouse(direction, target_version) unless Penthouse.configuration.migrate_tenants? - return run_without_penthouse(direction, migrations_paths, target_version) + return run_without_penthouse(direction, target_version) end wrap_penthouse do - run_without_penthouse(direction, migrations_paths, target_version) + run_without_penthouse(direction, target_version) end end diff --git a/penthouse.gemspec b/penthouse.gemspec index 71da0fe..bab4e7f 100644 --- a/penthouse.gemspec +++ b/penthouse.gemspec @@ -30,9 +30,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rack", "~> 1.6.4" # db spec.add_development_dependency "ar-octopus", "~> 0.10.2" - spec.add_development_dependency "activesupport", ENV.fetch("RAILS_VERSION", "4.2.2").to_s - spec.add_development_dependency "activerecord", ENV.fetch("RAILS_VERSION", "4.2.2").to_s - spec.add_development_dependency "pg", ENV.fetch("PG_VERSION", "0.19.0").to_s + spec.add_development_dependency "activesupport", ">= 4.2.2" + spec.add_development_dependency "activerecord", ">= 4.2.2" + spec.add_development_dependency "pg", ">= 0.19.0" spec.add_development_dependency "guard-rspec" spec.add_development_dependency "pry" From 785278c7cd234cde64da1d675fadd6e97f74fbb9 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 20 Jul 2020 14:34:53 +0100 Subject: [PATCH 06/11] Remove unnecessary changed from the migration module --- lib/penthouse/migration.rb | 27 ------- lib/penthouse/migration_context.rb | 112 ----------------------------- lib/penthouse/migrator.rb | 26 ++++++- 3 files changed, 25 insertions(+), 140 deletions(-) delete mode 100644 lib/penthouse/migration.rb delete mode 100644 lib/penthouse/migration_context.rb diff --git a/lib/penthouse/migration.rb b/lib/penthouse/migration.rb deleted file mode 100644 index 77fe0c1..0000000 --- a/lib/penthouse/migration.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "active_record" -require "active_support/core_ext/module/aliasing" - -module Penthouse - module Migration - def self.included(base) - base.class_eval do - # Verbose form of alias_method_chain which is now deprecated in ActiveSupport. - # - # This replaces the original #annouce method with #announce_with_penthouse - # but allows calling #annouce by using #announce_without_penthouse. - alias_method :announce_without_penthouse, :announce - alias_method :announce, :announce_with_penthouse - end - end - - def announce_with_penthouse(message) - announce_without_penthouse("#{message} - #{current_tenant}") - end - - def current_tenant - "Tenant: #{Penthouse.tenant || "*** global ***"}" - end - end -end - -ActiveRecord::Migration.send(:include, Penthouse::Migration) diff --git a/lib/penthouse/migration_context.rb b/lib/penthouse/migration_context.rb deleted file mode 100644 index 750ce62..0000000 --- a/lib/penthouse/migration_context.rb +++ /dev/null @@ -1,112 +0,0 @@ -require "active_record" -require "active_support/core_ext/module/aliasing" - -module Penthouse - module MigrationContext - def self.included(base) - base.extend(ClassMethods) - - base.class_eval do - alias_method :migrate_without_penthouse, :migrate - alias_method :migrate, :migrate_with_penthouse - - alias_method :up_without_penthouse, :up - alias_method :up, :up_with_penthouse - - alias_method :down_without_penthouse, :down - alias_method :down, :down_with_penthouse - - alias_method :run_without_penthouse, :run - alias_method :run, :run_with_penthouse - - # override any new Octopus methods with the new Penthouse ones - alias_method :migrate_with_octopus, :migrate_with_penthouse - alias_method :up_with_octopus, :up_with_penthouse - alias_method :down_with_octopus, :down_with_penthouse - alias_method :run_with_octopus, :run_with_penthouse - - alias_method :migrations_without_penthouse, :migrations - alias_method :migrations, :migrations_with_penthouse - - # override any new Octopus methods with the new Penthouse ones - alias_method :migrate_with_octopus, :migrate_with_penthouse - alias_method :migrations_with_octopus, :migrations_with_penthouse - end - end - - # this may seem stupid but it gets around issues with Octopus - def migrate_with_penthouse(*args) - migrate_without_penthouse(*args) - end - - # this may seem stupid but it gets around issues with Octopus - def migrations_with_penthouse - migrations_without_penthouse - end - - module ClassMethods - def migrate_with_penthouse(target_version = nil, &block) - unless Penthouse.configuration.migrate_tenants? - return migrate_without_penthouse(target_version, &block) - end - - wrap_penthouse do - migrate_without_penthouse(target_version, &block) - end - end - - def up_with_penthouse(target_version = nil, &block) - unless Penthouse.configuration.migrate_tenants? - return up_without_penthouse(target_version, &block) - end - - wrap_penthouse do - up_without_penthouse(target_version) - end - end - - def down_with_penthouse(target_version = nil, &block) - unless Penthouse.configuration.migrate_tenants? - return down_without_penthouse(target_version) - end - - wrap_penthouse do - down_without_penthouse(target_version) - end - end - - def run_with_penthouse(direction, target_version) - unless Penthouse.configuration.migrate_tenants? - return run_without_penthouse(direction, target_version) - end - - wrap_penthouse do - run_without_penthouse(direction, target_version) - end - end - - private - - def wrap_penthouse(&block) - if Penthouse.tenant - block.yield - else - Penthouse.each_tenant(tenant_identifiers: tenants_to_migrate, &block) - end - end - - def tenants_to_migrate - return @tenants_to_migrate if defined?(@tenants_to_migrate) - @tenants_to_migrate = begin - if !!(t = (ENV["TENANT"] || ENV["TENANTS"])) - t.split(",").map(&:strip) - else - Penthouse.tenant_identifiers - end - end - end - end - end -end - -ActiveRecord::MigrationContext.send(:include, Penthouse::MigrationContext) if ActiveRecord.version.release > Gem::Version.new("5.2.0") diff --git a/lib/penthouse/migrator.rb b/lib/penthouse/migrator.rb index b1d0da5..76f8c4b 100644 --- a/lib/penthouse/migrator.rb +++ b/lib/penthouse/migrator.rb @@ -1,6 +1,29 @@ require "active_record" require "active_support/core_ext/module/aliasing" +module Penthouse + module Migration + def self.included(base) + base.class_eval do + # Verbose form of alias_method_chain which is now deprecated in ActiveSupport. + # + # This replaces the original #annouce method with #announce_with_penthouse + # but allows calling #annouce by using #announce_without_penthouse. + alias_method :announce_without_penthouse, :announce + alias_method :announce, :announce_with_penthouse + end + end + + def announce_with_penthouse(message) + announce_without_penthouse("#{message} - #{current_tenant}") + end + + def current_tenant + "Tenant: #{Penthouse.tenant || "*** global ***"}" + end + end +end + module Penthouse module Migrator def self.included(base) @@ -114,4 +137,5 @@ def tenants_to_migrate end end -ActiveRecord::Migrator.send(:include, Penthouse::Migrator) if ActiveRecord.version.release < Gem::Version.new("5.2.0") +ActiveRecord::Migration.send(:include, Penthouse::Migration) +ActiveRecord::Migrator.send(:include, Penthouse::Migrator) From 499357de724fcf5fbd80c75bb006415f446a1c1b Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 20 Jul 2020 14:47:47 +0100 Subject: [PATCH 07/11] Linting --- lib/penthouse/tenants/sharded_tenant.rb | 2 +- penthouse.gemspec | 2 +- spec/penthouse/tenants/shared_tenant_spec.rb | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/penthouse/tenants/sharded_tenant.rb b/lib/penthouse/tenants/sharded_tenant.rb index c6e66cb..4b10683 100644 --- a/lib/penthouse/tenants/sharded_tenant.rb +++ b/lib/penthouse/tenants/sharded_tenant.rb @@ -6,7 +6,7 @@ # [1]: (https://github.com/thiagopradi/octopus) # -require_relative './shared_tenant' +require_relative "./shared_tenant" module Penthouse module Tenants diff --git a/penthouse.gemspec b/penthouse.gemspec index 47bd18e..ad8db39 100644 --- a/penthouse.gemspec +++ b/penthouse.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |spec| # web spec.add_development_dependency "rack", "~> 1.6.4" # db - spec.add_development_dependency 'ar-octopus', '~> 0.8.6' + spec.add_development_dependency "ar-octopus", "~> 0.8.6" spec.add_development_dependency "activesupport", ">= 4.2.2" spec.add_development_dependency "activerecord", ">= 4.2.2" spec.add_development_dependency "pg", ">= 0.19.0" diff --git a/spec/penthouse/tenants/shared_tenant_spec.rb b/spec/penthouse/tenants/shared_tenant_spec.rb index 6f6b444..26f9399 100644 --- a/spec/penthouse/tenants/shared_tenant_spec.rb +++ b/spec/penthouse/tenants/shared_tenant_spec.rb @@ -1,6 +1,6 @@ -require 'spec_helper' -require 'octopus_helper' -require 'penthouse/tenants/shared_tenant' +require "spec_helper" +require "octopus_helper" +require "penthouse/tenants/shared_tenant" RSpec.describe Penthouse::Tenants::SharedTenant do subject { described_class.new(identifier: "test") } From 818195c88108dac547235ad72793dbb5a2b73fa9 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 20 Jul 2020 16:08:10 +0100 Subject: [PATCH 08/11] Linting --- lib/penthouse/tenants/migratable.rb | 2 +- lib/penthouse/tenants/shared_tenant.rb | 5 ++--- spec/penthouse/tenants/sharded_tenant_spec.rb | 10 +++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/penthouse/tenants/migratable.rb b/lib/penthouse/tenants/migratable.rb index 5d90478..5896921 100644 --- a/lib/penthouse/tenants/migratable.rb +++ b/lib/penthouse/tenants/migratable.rb @@ -67,7 +67,7 @@ def process_schema_file(db_schema_file) def sanitize_sql(sql) sql - .gsub(/SELECT pg_catalog.set_config\(\'search_path.*;/, "") + .gsub(/SELECT pg_catalog.set_config\('search_path.*;/, "") .gsub(/SET search_path.*;/, "") .gsub(/CREATE SCHEMA/, "CREATE SCHEMA IF NOT EXISTS") .gsub(/public\./, "") diff --git a/lib/penthouse/tenants/shared_tenant.rb b/lib/penthouse/tenants/shared_tenant.rb index 42493c2..00a4f72 100644 --- a/lib/penthouse/tenants/shared_tenant.rb +++ b/lib/penthouse/tenants/shared_tenant.rb @@ -8,13 +8,12 @@ # [1]: (https://github.com/thiagopradi/octopus) # -require_relative './base_tenant' -require 'octopus' +require_relative "./base_tenant" +require "octopus" module Penthouse module Tenants class SharedTenant < BaseTenant - # ensures we're on the correct Octopus shard, then executes the query # @param shard [String, Symbol] The shard to execute within, usually master # @param block [Block] The code to execute within the schema diff --git a/spec/penthouse/tenants/sharded_tenant_spec.rb b/spec/penthouse/tenants/sharded_tenant_spec.rb index 097e364..8f9d189 100644 --- a/spec/penthouse/tenants/sharded_tenant_spec.rb +++ b/spec/penthouse/tenants/sharded_tenant_spec.rb @@ -1,6 +1,6 @@ -require 'spec_helper' -require 'octopus_helper' -require 'penthouse/tenants/sharded_tenant' +require "spec_helper" +require "octopus_helper" +require "penthouse/tenants/sharded_tenant" RSpec.describe Penthouse::Tenants::ShardedTenant do subject { described_class.new(identifier: shard_name, shard: shard_name) } @@ -26,9 +26,9 @@ let(:shard_name) { "invalid_shard" } it "should raise an exception" do - expect do + expect { subject.call { true } - end.to raise_error(RuntimeError) + }.to raise_error(RuntimeError) end end end From 10ab16509addcf31a45ef522e0e91acf6f137fb9 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 20 Jul 2020 16:14:06 +0100 Subject: [PATCH 09/11] Trailing comma --- Guardfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Guardfile b/Guardfile index bf2249a..8334da0 100644 --- a/Guardfile +++ b/Guardfile @@ -49,7 +49,7 @@ guard :rspec, cmd: "bundle exec rspec", failed_mode: :focus do [ rspec.spec.call("routing/#{m[1]}_routing"), rspec.spec.call("controllers/#{m[1]}_controller"), - rspec.spec.call("acceptance/#{m[1]}"), + rspec.spec.call("acceptance/#{m[1]}") ] end From 5e582a0af18b78cd689cc8d92d37b95cb5979307 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 20 Jul 2020 16:23:17 +0100 Subject: [PATCH 10/11] Remove testing of rails versions greater than 5.1.7 --- .circleci/config.yml | 9 ++++++--- Makefile | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b742949..60e0fc4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,6 +21,9 @@ jobs: - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.1.7 PG_VERSION=0.21.0 bundle install - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.1.7 PG_VERSION=0.21.0 bundle exec rspec - run: rm Gemfile.lock - - - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.2.3 PG_VERSION=0.21.0 bundle install - - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.2.3 PG_VERSION=0.21.0 bundle exec rspec + # Uncomment when adding support for greater rails versions + # + # - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.2.3 PG_VERSION=1.1.4 bundle install + # - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.2.3 PG_VERSION=1.1.4 bundle exec rspec + # - run: RUBY_VERSION=2.4.1 RAILS_VERSION=6.0.0 PG_VERSION=0.21.0 bundle install + # - run: RUBY_VERSION=2.4.1 RAILS_VERSION=6.0.0 PG_VERSION=0.21.0 bundle exec rspec diff --git a/Makefile b/Makefile index 68189af..ddf9226 100644 --- a/Makefile +++ b/Makefile @@ -18,4 +18,3 @@ test: make test-4.2.11.1 make test-5.1.7 make test-5.2.3 - make test-6.0.0 From 89b97a8d41b2af4e97a73006c849e491c79f10a6 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 20 Jul 2020 16:40:42 +0100 Subject: [PATCH 11/11] Test less versions --- .circleci/config.yml | 12 +++++++++++- penthouse.gemspec | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 60e0fc4..f7d4f0f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,12 +18,22 @@ jobs: - run: RUBY_VERSION=2.4.1 RAILS_VERSION=4.2.11.1 PG_VERSION=0.21.0 bundle exec rspec - run: rm Gemfile.lock + - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.1.6.2 PG_VERSION=0.21.0 bundle install + - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.1.6.2 PG_VERSION=0.21.0 bundle exec rspec + - run: rm Gemfile.lock + - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.1.7 PG_VERSION=0.21.0 bundle install - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.1.7 PG_VERSION=0.21.0 bundle exec rspec - run: rm Gemfile.lock - # Uncomment when adding support for greater rails versions + # # # - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.2.3 PG_VERSION=1.1.4 bundle install # - run: RUBY_VERSION=2.4.1 RAILS_VERSION=5.2.3 PG_VERSION=1.1.4 bundle exec rspec + # - run: rm Gemfile.lock + # + # Fails with `NameError: undefined method `migrate' for class `#'` + # + # Uncomment when adding support for greater rails versions + # # - run: RUBY_VERSION=2.4.1 RAILS_VERSION=6.0.0 PG_VERSION=0.21.0 bundle install # - run: RUBY_VERSION=2.4.1 RAILS_VERSION=6.0.0 PG_VERSION=0.21.0 bundle exec rspec diff --git a/penthouse.gemspec b/penthouse.gemspec index ad8db39..bab4e7f 100644 --- a/penthouse.gemspec +++ b/penthouse.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |spec| # web spec.add_development_dependency "rack", "~> 1.6.4" # db - spec.add_development_dependency "ar-octopus", "~> 0.8.6" + spec.add_development_dependency "ar-octopus", "~> 0.10.2" spec.add_development_dependency "activesupport", ">= 4.2.2" spec.add_development_dependency "activerecord", ">= 4.2.2" spec.add_development_dependency "pg", ">= 0.19.0"