diff --git a/.gitignore b/.gitignore index 494f7d3..6559a11 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ pkg ## bundler Gemfile.lock + +## RSpec temp files +spec/tmp diff --git a/README.md b/README.md index 09cb377..07afc90 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ update the local feature branch with latest remote changes plus upstream release integrate the current feature branch into an aggregate branch (ex: prototype, staging) -## git review +## git review create a pull request on github for peer review of the current branch. This command is re-runnable in order to re-assign pull requests. @@ -41,13 +41,14 @@ options: NOTE: the `--bump` option will also update the pull request commit status to mark the branch as 'pending peer review'. This setting is cleared when a reviewer approves or rejects the pull request. -## git release +## git release :boolean, :aliases => '-v' @@ -38,18 +36,22 @@ def current_branch repo.branches.find(&:head?) end - def aggregate_branch?(branch) - AGGREGATE_BRANCHES.include?(branch) + def assert_aggregate_branch!(target_branch) + fail "Invalid aggregate branch: #{target_branch} must be one of supported aggregate branches #{config.aggregate_branches}" unless config.aggregate_branch?(target_branch) end def assert_not_protected_branch!(branch, action) - raise "Cannot #{action} reserved branch" if RESERVED_BRANCHES.include?(branch) || aggregate_branch?(branch) + raise "Cannot #{action} reserved branch" if config.reserved_branch?(branch) || config.aggregate_branch?(branch) end # helper to invoke other CLI commands def execute_command(command_class, method, args = []) command_class.new.send(method, *args) end + + def config + @configuration ||= Thegarage::Gitx::Configuration.new(repo.workdir) + end end end end diff --git a/lib/thegarage/gitx/cli/buildtag_command.rb b/lib/thegarage/gitx/cli/buildtag_command.rb index 88ee9ee..a887aad 100644 --- a/lib/thegarage/gitx/cli/buildtag_command.rb +++ b/lib/thegarage/gitx/cli/buildtag_command.rb @@ -6,12 +6,11 @@ module Thegarage module Gitx module Cli class BuildtagCommand < BaseCommand - TAGGABLE_BRANCHES = %w( master staging ) desc 'buildtag', 'create a tag for the current build and push it back to origin (supports Travis CI and Codeship)' def buildtag fail "Unknown branch. Environment variables TRAVIS_BRANCH or CI_BRANCH are required" unless branch_name - fail "Branch must be one of the supported taggable branches: #{TAGGABLE_BRANCHES}" unless TAGGABLE_BRANCHES.include?(branch_name) + fail "Branch must be one of the supported taggable branches: #{config.taggable_branches}" unless config.taggable_branch?(branch_name) label = "buildtag generated by build #{build_number}" create_build_tag(branch_name, label) diff --git a/lib/thegarage/gitx/cli/cleanup_command.rb b/lib/thegarage/gitx/cli/cleanup_command.rb index 7622c6d..4844907 100644 --- a/lib/thegarage/gitx/cli/cleanup_command.rb +++ b/lib/thegarage/gitx/cli/cleanup_command.rb @@ -36,8 +36,8 @@ def merged_branches(options = {}) branch end branches.uniq! - branches -= RESERVED_BRANCHES - branches.reject! { |b| aggregate_branch?(b) } + branches -= config.reserved_branches + branches.reject! { |b| config.aggregate_branch?(b) } branches end diff --git a/lib/thegarage/gitx/cli/integrate_command.rb b/lib/thegarage/gitx/cli/integrate_command.rb index bf9d33e..b0299e1 100644 --- a/lib/thegarage/gitx/cli/integrate_command.rb +++ b/lib/thegarage/gitx/cli/integrate_command.rb @@ -26,7 +26,7 @@ def integrate(integration_branch = 'staging') integrate_branch(branch, integration_branch) unless options[:resume] checkout_branch branch - create_integrate_comment(branch) unless RESERVED_BRANCHES.include?(branch) + create_integrate_comment(branch) unless config.reserved_branch?(branch) end private @@ -59,10 +59,6 @@ def feature_branch_name end end - def assert_aggregate_branch!(target_branch) - fail "Invalid aggregate branch: #{target_branch} must be one of supported aggregate branches #{AGGREGATE_BRANCHES}" unless aggregate_branch?(target_branch) - end - # nuke local branch and pull fresh version from remote repo def fetch_remote_branch(target_branch) create_remote_branch(target_branch) unless remote_branch_exists?(target_branch) diff --git a/lib/thegarage/gitx/cli/nuke_command.rb b/lib/thegarage/gitx/cli/nuke_command.rb index e37511d..5858fdc 100644 --- a/lib/thegarage/gitx/cli/nuke_command.rb +++ b/lib/thegarage/gitx/cli/nuke_command.rb @@ -14,7 +14,7 @@ def nuke(bad_branch) last_known_good_tag = current_build_tag(good_branch) return unless yes?("Reset #{bad_branch} to #{last_known_good_tag}? (y/n)", :green) - fail "Only aggregate branches are allowed to be reset: #{AGGREGATE_BRANCHES}" unless aggregate_branch?(bad_branch) + assert_aggregate_branch!(bad_branch) return if migrations_need_to_be_reverted?(bad_branch, last_known_good_tag) say "Resetting " diff --git a/lib/thegarage/gitx/cli/release_command.rb b/lib/thegarage/gitx/cli/release_command.rb index 327be2d..49521f7 100644 --- a/lib/thegarage/gitx/cli/release_command.rb +++ b/lib/thegarage/gitx/cli/release_command.rb @@ -14,11 +14,12 @@ class ReleaseCommand < BaseCommand desc 'release', 'release the current branch to production' method_option :cleanup, :type => :boolean, :desc => 'cleanup merged branches after release' - def release + def release(branch = nil) return unless yes?("Release #{current_branch.name} to production? (y/n)", :green) - branch = current_branch.name + branch ||= current_branch.name assert_not_protected_branch!(branch, 'release') + checkout_branch(branch) execute_command(UpdateCommand, :update) find_or_create_pull_request(branch) diff --git a/lib/thegarage/gitx/cli/review_command.rb b/lib/thegarage/gitx/cli/review_command.rb index 79de65f..5d2a355 100644 --- a/lib/thegarage/gitx/cli/review_command.rb +++ b/lib/thegarage/gitx/cli/review_command.rb @@ -1,7 +1,6 @@ require 'thor' require 'thegarage/gitx' require 'thegarage/gitx/cli/base_command' -require 'thegarage/gitx/cli/update_command' require 'thegarage/gitx/github' module Thegarage @@ -41,10 +40,10 @@ class ReviewCommand < BaseCommand method_option :approve, :type => :boolean, :desc => 'approve the pull request an post comment on pull request' method_option :reject, :type => :boolean, :desc => 'reject the pull request an post comment on pull request' # @see http://developer.github.com/v3/pulls/ - def review + def review(branch = nil) fail 'Github authorization token not found' unless authorization_token - branch = current_branch.name + branch ||= current_branch.name pull_request = find_or_create_pull_request(branch) bump_pull_request(pull_request) if options[:bump] approve_pull_request(pull_request) if options[:approve] diff --git a/lib/thegarage/gitx/configuration.rb b/lib/thegarage/gitx/configuration.rb new file mode 100644 index 0000000..a276dc5 --- /dev/null +++ b/lib/thegarage/gitx/configuration.rb @@ -0,0 +1,47 @@ +require 'yaml' + +module Thegarage + module Gitx + class Configuration + DEFAULT_CONFIG = { + 'aggregate_branches' => %w( staging prototype ), + 'reserved_branches' => %w( HEAD master next_release staging prototype ), + 'taggable_branches' => %w( master staging ) + } + CONFIG_FILE = '.gitx.yml' + + attr_reader :config + + def initialize(root_dir) + @config = Thor::CoreExt::HashWithIndifferentAccess.new(DEFAULT_CONFIG) + config_file_path = File.join(root_dir, CONFIG_FILE) + if File.exists?(config_file_path) + @config.merge!(::YAML::load_file(config_file_path)) + end + end + + def aggregate_branches + config[:aggregate_branches] + end + def aggregate_branch?(branch) + aggregate_branches.include?(branch) + end + + def reserved_branches + config[:reserved_branches] + end + + def reserved_branch?(branch) + reserved_branches.include?(branch) + end + + def taggable_branches + config[:taggable_branches] + end + + def taggable_branch?(branch) + taggable_branches.include?(branch) + end + end + end +end diff --git a/lib/thegarage/gitx/github.rb b/lib/thegarage/gitx/github.rb index 5aaf084..8015d11 100644 --- a/lib/thegarage/gitx/github.rb +++ b/lib/thegarage/gitx/github.rb @@ -1,8 +1,12 @@ require 'octokit' +require 'fileutils' +require 'yaml' +require 'thegarage/gitx/cli/update_command' module Thegarage module Gitx module Github + GLOBAL_CONFIG_FILE = '~/.config/gitx/github.yml' REVIEW_CONTEXT = 'peer_review' CLIENT_URL = 'https://github.com/thegarage/thegarage-gitx' PULL_REQUEST_FOOTER = <<-EOS.dedent @@ -17,6 +21,7 @@ module Github def find_or_create_pull_request(branch) pull_request = find_pull_request(branch) pull_request ||= begin + checkout_branch(branch) execute_command(Thegarage::Gitx::Cli::UpdateCommand, :update) pull_request = create_pull_request(branch) say 'Created pull request: ' @@ -79,39 +84,41 @@ def pull_request_body(branch) body.gsub(PULL_REQUEST_FOOTER, '').chomp.strip end - # token is cached in local git config for future use + # authorization token used for github API calls + # the token is cached on the filesystem for future use # @return [String] auth token stored in git (current repo, user config or installed global settings) # @see http://developer.github.com/v3/oauth/#scopes # @see http://developer.github.com/v3/#user-agent-required def authorization_token - auth_token = repo.config['thegarage.gitx.githubauthtoken'] - return auth_token unless auth_token.to_s.blank? - - auth_token = create_authorization - repo.config['thegarage.gitx.githubauthtoken'] = auth_token + auth_token = global_config['token'] + auth_token ||= begin + new_token = create_authorization + save_global_config('token' => new_token) + new_token + end auth_token end def create_authorization - password = ask("Github password for #{username}: ", :echo => false) - say '' + password = ask_without_echo("Github password for #{username}: ") client = Octokit::Client.new(login: username, password: password) - response = client.create_authorization(authorization_request_options) - response.token - end - - def authorization_request_options - timestamp = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S%z') - client_name = "The Garage Git eXtensions - #{github_slug} #{timestamp}" options = { :scopes => ['repo'], - :note => client_name, + :note => github_client_name, :note_url => CLIENT_URL } - two_factor_auth_token = ask("Github two factor authorization token (if enabled): ", :echo => false) - say '' + two_factor_auth_token = ask_without_echo("Github two factor authorization token (if enabled): ") options[:headers] = {'X-GitHub-OTP' => two_factor_auth_token} if two_factor_auth_token - options + response = client.create_authorization(options) + response.token + rescue Octokit::ClientError => e + say "Error creating authorization: #{e.message}", :red + retry + end + + def github_client_name + timestamp = Time.now.utc.strftime('%FT%R:%S%z') + client_name = "The Garage Git eXtensions #{timestamp}" end def github_client @@ -139,6 +146,34 @@ def github_slug def github_organization github_slug.split('/').first end + + def global_config_file + File.expand_path(GLOBAL_CONFIG_FILE) + end + + def global_config + @config ||= begin + File.exists?(global_config_file) ? YAML.load_file(global_config_file) : {} + end + end + + def save_global_config(options) + config_dir = File.dirname(global_config_file) + ::FileUtils.mkdir_p(config_dir, mode: 0700) unless File.exists?(config_dir) + + @config = global_config.merge(options) + File.open(global_config_file, "a+") do |file| + file.truncate(0) + file.write(@config.to_yaml) + end + File.chmod(0600, global_config_file) + end + + def ask_without_echo(message) + value = ask(message, echo: false) + say '' + value + end end end end diff --git a/lib/thegarage/gitx/version.rb b/lib/thegarage/gitx/version.rb index d2b6cfd..3f20a67 100644 --- a/lib/thegarage/gitx/version.rb +++ b/lib/thegarage/gitx/version.rb @@ -1,5 +1,5 @@ module Thegarage module Gitx - VERSION = '2.10.1' + VERSION = '2.13.0' end end diff --git a/spec/support/global_config.rb b/spec/support/global_config.rb new file mode 100644 index 0000000..0d28920 --- /dev/null +++ b/spec/support/global_config.rb @@ -0,0 +1,24 @@ +# helper for reading global config file +module GlobalConfig + def global_config_file + config_file = File.join(temp_dir, '.config/gitx/github.yml') + config_dir = File.dirname(config_file) + FileUtils.mkdir_p(config_dir) unless File.exists?(config_dir) + config_file + end + def global_config + YAML.load_file(global_config_file) + end + def temp_dir + tmp_dir = File.join(__dir__, '../tmp') + end +end + +RSpec.configure do |config| + config.include GlobalConfig + + config.before do + FileUtils.rm_rf(temp_dir) + FileUtils.mkdir_p(temp_dir) + end +end diff --git a/spec/support/home_env.rb b/spec/support/home_env.rb new file mode 100644 index 0000000..b2d0c8f --- /dev/null +++ b/spec/support/home_env.rb @@ -0,0 +1,11 @@ +# Swap home directory to current project spec/tmp +# to allow for writing files + cleanup +RSpec.configure do |config| + config.before do + @old_home = ENV['HOME'] + ENV['HOME'] = temp_dir + end + config.after do + ENV['HOME'] = @old_home + end +end diff --git a/spec/thegarage/gitx/cli/base_command_spec.rb b/spec/thegarage/gitx/cli/base_command_spec.rb new file mode 100644 index 0000000..e699802 --- /dev/null +++ b/spec/thegarage/gitx/cli/base_command_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' +require 'thegarage/gitx/cli/base_command' + +describe Thegarage::Gitx::Cli::BaseCommand do + let(:args) { [] } + let(:options) { {} } + let(:config) do + { + pretend: true + } + end + let(:cli) { described_class.new(args, options, config) } + let(:repo) { cli.send(:repo) } + + describe 'without custom .gitx.yml config file' do + it 'provides default options' do + expect(cli.send(:config).config).to eq Thegarage::Gitx::Configuration::DEFAULT_CONFIG + end + end + + describe 'with custom .gitx.yml config file' do + let(:config) do + { + 'aggregate_branches' => %w( foo bar ), + 'reserved_branches' => %w( baz qux ), + 'taggable_branches' => %w( quux corge ) + } + end + before do + expect(repo).to receive(:workdir).and_return(temp_dir) + File.open(File.join(temp_dir, '.gitx.yml'), 'w') do |f| + f.puts config.to_yaml + end + end + it 'overrides default options' do + expect(cli.send(:config).aggregate_branches).to eq(%w( foo bar )) + expect(cli.send(:config).reserved_branches).to eq(%w( baz qux )) + expect(cli.send(:config).taggable_branches).to eq(%w( quux corge )) + end + end +end diff --git a/spec/thegarage/gitx/cli/integrate_command_spec.rb b/spec/thegarage/gitx/cli/integrate_command_spec.rb index 5bbe7b5..170e36c 100644 --- a/spec/thegarage/gitx/cli/integrate_command_spec.rb +++ b/spec/thegarage/gitx/cli/integrate_command_spec.rb @@ -98,7 +98,7 @@ expect(cli).to receive(:run_cmd).with("git merge feature-branch").ordered expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered - + expect(cli).to receive(:run_cmd).with('git checkout feature-branch').ordered expect(cli).to receive(:run_cmd).with("git log master...feature-branch --reverse --no-merges --pretty=format:'* %s%n%b'").and_return("2013-01-01 did some stuff").ordered stub_request(:post, 'https://api.github.com/repos/thegarage/thegarage-gitx/pulls').to_return(:status => 201, :body => new_pull_request.to_json, :headers => {'Content-Type' => 'application/json'}) diff --git a/spec/thegarage/gitx/cli/release_command_spec.rb b/spec/thegarage/gitx/cli/release_command_spec.rb index d60ce48..84b3f13 100644 --- a/spec/thegarage/gitx/cli/release_command_spec.rb +++ b/spec/thegarage/gitx/cli/release_command_spec.rb @@ -61,6 +61,7 @@ expect(cli).to receive(:yes?).and_return(true) allow(cli).to receive(:authorization_token).and_return(authorization_token) + expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered expect(cli).to receive(:run_cmd).with("git checkout master").ordered expect(cli).to receive(:run_cmd).with("git pull origin master").ordered expect(cli).to receive(:run_cmd).with("git merge --no-ff feature-branch").ordered @@ -74,6 +75,29 @@ should meet_expectations end end + context 'when target_branch is not nil and user confirms release and pull request exists with success status' do + before do + expect(cli).to receive(:execute_command).with(Thegarage::Gitx::Cli::UpdateCommand, :update) + expect(cli).to receive(:execute_command).with(Thegarage::Gitx::Cli::IntegrateCommand, :integrate, 'staging') + expect(cli).to_not receive(:execute_command).with(Thegarage::Gitx::Cli::CleanupCommand, :cleanup) + + expect(cli).to receive(:yes?).and_return(true) + allow(cli).to receive(:authorization_token).and_return(authorization_token) + + expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered + expect(cli).to receive(:run_cmd).with("git checkout master").ordered + expect(cli).to receive(:run_cmd).with("git pull origin master").ordered + expect(cli).to receive(:run_cmd).with("git merge --no-ff feature-branch").ordered + expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered + + VCR.use_cassette('pull_request_does_exist_with_success_status') do + cli.release 'feature-branch' + end + end + it 'runs expected commands' do + should meet_expectations + end + end context 'when user confirms release and pull request does not exist' do let(:new_pull_request) do { @@ -96,6 +120,8 @@ expect(cli).to receive(:yes?).with('Release feature-branch to production? (y/n)', :green).and_return(true) expect(cli).to receive(:yes?).with('Branch status is currently: pending. Proceed with release? (y/n)', :red).and_return(true) + expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered + expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered expect(cli).to receive(:run_cmd).with("git log master...feature-branch --reverse --no-merges --pretty=format:'* %s%n%b'").and_return("2013-01-01 did some stuff").ordered expect(cli).to receive(:run_cmd).with("git checkout master").ordered expect(cli).to receive(:run_cmd).with("git pull origin master").ordered @@ -128,6 +154,7 @@ expect(cli).to receive(:yes?).and_return(true) allow(cli).to receive(:authorization_token).and_return(authorization_token) + expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered expect(cli).to receive(:run_cmd).with("git checkout master").ordered expect(cli).to receive(:run_cmd).with("git pull origin master").ordered expect(cli).to receive(:run_cmd).with("git merge --no-ff feature-branch").ordered @@ -140,9 +167,6 @@ it 'runs expected commands' do should meet_expectations end - it 'prunes merged branches (git cleanup)' do - should meet_expectations - end end end end diff --git a/spec/thegarage/gitx/cli/review_command_spec.rb b/spec/thegarage/gitx/cli/review_command_spec.rb index bdf5109..6fbe4b5 100644 --- a/spec/thegarage/gitx/cli/review_command_spec.rb +++ b/spec/thegarage/gitx/cli/review_command_spec.rb @@ -9,7 +9,7 @@ pretend: true } end - let(:cli) { Thegarage::Gitx::Cli::ReviewCommand.new(args, options, config) } + let(:cli) { described_class.new(args, options, config) } let(:repo) { double('fake repo', config: repo_config) } let(:repo_config) do { @@ -43,6 +43,7 @@ expect(Thegarage::Gitx::Cli::UpdateCommand).to receive(:new).and_return(fake_update_command) allow(cli).to receive(:authorization_token).and_return(authorization_token) + expect(cli).to receive(:run_cmd).with('git checkout feature-branch').ordered expect(cli).to receive(:run_cmd).with("git log master...feature-branch --reverse --no-merges --pretty=format:'* %s%n%b'").and_return("* old commit\n\n* new commit").ordered expect(cli).to receive(:ask_editor).with("### Changelog\n* old commit\n\n* new commit\n#{Thegarage::Gitx::Github::PULL_REQUEST_FOOTER}", anything).and_return('description') @@ -59,6 +60,41 @@ should meet_expectations end end + context 'when target branch is not nil and pull request does not exist' do + let(:authorization_token) { '123123' } + let(:changelog) { '* made some fixes' } + let(:fake_update_command) { double('fake update command', update: nil) } + let(:new_pull_request) do + { + html_url: "https://path/to/html/pull/request", + issue_url: "https://api/path/to/issue/url", + number: 10, + head: { + ref: "branch_name" + } + } + end + before do + expect(Thegarage::Gitx::Cli::UpdateCommand).to receive(:new).and_return(fake_update_command) + + allow(cli).to receive(:authorization_token).and_return(authorization_token) + expect(cli).to receive(:run_cmd).with('git checkout feature-branch').ordered + expect(cli).to receive(:run_cmd).with("git log master...feature-branch --reverse --no-merges --pretty=format:'* %s%n%b'").and_return("* old commit\n\n* new commit").ordered + expect(cli).to receive(:ask_editor).with("### Changelog\n* old commit\n\n* new commit\n#{Thegarage::Gitx::Github::PULL_REQUEST_FOOTER}", anything).and_return('description') + + stub_request(:post, 'https://api.github.com/repos/thegarage/thegarage-gitx/pulls').to_return(:status => 201, :body => new_pull_request.to_json, :headers => {'Content-Type' => 'application/json'}) + + VCR.use_cassette('pull_request_does_not_exist') do + cli.review 'feature-branch' + end + end + it 'creates github pull request' do + should meet_expectations + end + it 'runs expected commands' do + should meet_expectations + end + end context 'when authorization_token is missing' do let(:authorization_token) { nil } it do @@ -209,7 +245,7 @@ end.to raise_error(/Github user not configured/) end end - context 'when config.authorization_token is nil' do + context 'when global config token is nil' do let(:repo_config) do { 'remote.origin.url' => 'https://github.com/thegarage/thegarage-gitx', @@ -227,21 +263,53 @@ @auth_token = cli.send(:authorization_token) end - it 'stores authorization_token in git config' do - expect(repo_config).to include('thegarage.gitx.githubauthtoken' => authorization_token) + it 'stores authorization_token in global config' do + expect(global_config).to include('token' => authorization_token) end it { expect(@auth_token).to eq authorization_token } end - context 'when there is an existing authorization_token' do + context 'when global authorization_token is nil and first request fails' do + let(:repo_config) do + { + 'remote.origin.url' => 'https://github.com/thegarage/thegarage-gitx', + 'github.user' => 'ryan@codecrate.com' + } + end + let(:github_password) { 'secretz' } + let(:authorization_token) { '123981239123' } + before do + stub_request(:post, "https://ryan@codecrate.com:secretz@api.github.com/authorizations"). + to_return(:status => 401, :body => JSON.dump(token: authorization_token), :headers => {'Content-Type' => 'application/json'}). + then. + to_return(:status => 200, :body => JSON.dump(token: authorization_token), :headers => {'Content-Type' => 'application/json'}) + + expect(cli).to receive(:ask).with('Github password for ryan@codecrate.com: ', {:echo => false}).and_return(github_password).twice + expect(cli).to receive(:ask).with('Github two factor authorization token (if enabled): ', {:echo => false}).and_return(nil).twice + + @auth_token = cli.send(:authorization_token) + end + it 'stores authorization_token in global config' do + expect(global_config).to include('token' => authorization_token) + end + it { expect(@auth_token).to eq authorization_token } + end + context 'when the global config has an existing token' do let(:authorization_token) { '123981239123' } let(:repo_config) do { 'remote.origin.url' => 'https://github.com/thegarage/thegarage-gitx', - 'github.user' => 'ryan@codecrate.com', - 'thegarage.gitx.githubauthtoken' => authorization_token + 'github.user' => 'ryan@codecrate.com' + } + end + let(:config) do + { + 'token' => authorization_token } end before do + File.open(global_config_file, 'w') do |file| + file.write(config.to_yaml) + end @auth_token = cli.send(:authorization_token) end it { expect(@auth_token).to eq authorization_token } @@ -266,8 +334,8 @@ @auth_token = cli.send(:authorization_token) end - it 'stores authorization_token in git config' do - expect(repo_config).to include('thegarage.gitx.githubauthtoken' => authorization_token) + it 'stores authorization_token in global config' do + expect(global_config).to include('token' => authorization_token) end it { expect(@auth_token).to eq authorization_token } end