From 70a329d3e3db9d155ec97e09cee1730bd8e72ecc Mon Sep 17 00:00:00 2001 From: Geoff Harcourt Date: Fri, 22 Jan 2016 17:54:04 -0500 Subject: [PATCH] Parse git remote name to determine Heroku app Several reports have matched #72, which was affecting the `restore` command for some users. The cause turned out to be local folder names not matching the name of the Heroku app. Now that Heroku tracks Git remotes, we can take advantage of the Git remote to correctly identify the app name even the local folder name doesn't match. While this requirement has been present for the entirety of Parity's existence, it stopped being a problem for most commands once Heroku introduced remotes. I inadvertently reintroduced this requirement in ad2c21a42fb85bd00ec58d7326725f0a1d5a7771 when we started automatically bypassing confirmation arguments for restores to non-production environments. Fix #72. --- Gemfile | 5 ++-- README.md | 2 -- lib/parity.rb | 1 + lib/parity/environment.rb | 6 ++++- spec/parity/environment_spec.rb | 47 ++++++++++++++++++++++++++++----- 5 files changed, 50 insertions(+), 11 deletions(-) diff --git a/Gemfile b/Gemfile index f9c4c0d..5ec0ead 100644 --- a/Gemfile +++ b/Gemfile @@ -2,5 +2,6 @@ source 'https://rubygems.org' gemspec -gem 'rake' -gem 'rspec' +gem "git" +gem "rake" +gem "rspec" diff --git a/README.md b/README.md index 102a2a4..8ce8924 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,6 @@ Parity expects: * A `production` remote pointing to the production Heroku app. * There is a `config/database.yml` file that can be parsed as YAML for `['development']['database']`. -* The Heroku apps are named like `app-staging` and `app-production` - where `app` is equal to `basename $PWD`. Customization ------------- diff --git a/lib/parity.rb b/lib/parity.rb index 2d517f5..105f69a 100644 --- a/lib/parity.rb +++ b/lib/parity.rb @@ -3,6 +3,7 @@ require "parity/version" require "parity/environment" require "parity/usage" +require "git" require "open3" require "pathname" require "uri" diff --git a/lib/parity/environment.rb b/lib/parity/environment.rb index c7a7a9b..5a1dfe3 100644 --- a/lib/parity/environment.rb +++ b/lib/parity/environment.rb @@ -125,8 +125,12 @@ def raw_redis_url )[0].strip end + def git_remote + Git.init.remote(environment).url + end + def heroku_app_name - [basename, environment].join('-') + git_remote.split(":").last.split(".").first end def basename diff --git a/spec/parity/environment_spec.rb b/spec/parity/environment_spec.rb index 6c425d6..7d1ec97 100644 --- a/spec/parity/environment_spec.rb +++ b/spec/parity/environment_spec.rb @@ -31,8 +31,26 @@ expect(Kernel).to have_received(:system).with(heroku_backup) end + it "correctly connects to the Heroku app when the $PWD's name does not match the app's name" do + backup = stub_parity_backup + stub_git_remote(base_name: "parity-integration", environment: "staging") + allow(Parity::Backup).to receive(:new).and_return(backup) + + Parity::Environment.new("staging", ["restore", "production"]).run + + expect(Parity::Backup). + to have_received(:new). + with( + from: "production", + to: "staging", + additional_args: "--confirm parity-integration-staging", + ) + expect(backup).to have_received(:restore) + end + it "restores backups from production to staging" do - backup = double("backup", restore: nil) + backup = stub_parity_backup + stub_git_remote(environment: "staging") allow(Parity::Backup).to receive(:new).and_return(backup) Parity::Environment.new("staging", ["restore", "production"]).run @@ -48,7 +66,8 @@ end it "restores using restore-from" do - backup = double("backup", restore: nil) + backup = stub_parity_backup + stub_git_remote(environment: "staging") allow(Parity::Backup).to receive(:new).and_return(backup) Parity::Environment.new("staging", ["restore-from", "production"]).run @@ -64,7 +83,8 @@ end it "passes the confirm argument when restoring to a non-prod environment" do - backup = double("backup", restore: nil) + backup = stub_parity_backup + stub_git_remote(environment: "staging") allow(Parity::Backup).to receive(:new).and_return(backup) Parity::Environment.new("staging", ["restore", "production"]).run @@ -79,7 +99,7 @@ end it "restores backups from production to development" do - backup = double("backup", restore: nil) + backup = stub_parity_backup allow(Parity::Backup).to receive(:new).and_return(backup) Parity::Environment.new("development", ["restore", "production"]).run @@ -90,7 +110,7 @@ end it "restores backups from staging to development" do - backup = double("backup", restore: nil) + backup = stub_parity_backup allow(Parity::Backup).to receive(:new).and_return(backup) Parity::Environment.new("development", ["restore", "staging"]).run @@ -101,7 +121,8 @@ end it "does not allow restoring backups into production" do - backup = double("backup", restore: nil) + backup = stub_parity_backup + stub_git_remote allow(Parity::Backup).to receive(:new).and_return(backup) allow($stdout).to receive(:puts) @@ -323,4 +344,18 @@ def stub_migration_path_check(result) path_stub end + + def stub_git_remote(base_name: "parity", environment: "staging") + git_remote = instance_double( + "Git::Remote", + url: "git@heroku.com:#{base_name}-#{environment}.git", + ) + git = instance_double("Git::Base") + allow(git).to receive(:remote).with("staging").and_return(git_remote) + allow(Git).to receive(:init).and_return(git) + end + + def stub_parity_backup + instance_double("Parity::Backup", restore: nil) + end end