зеркало из https://github.com/mislav/hub.git
Коммит
e7576e0eac
|
@ -5,40 +5,22 @@ on: [push, pull_request]
|
|||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go: ["1.11", "1.12", "1.13", "1.14"]
|
||||
env:
|
||||
BUNDLE_BIN: bin
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Ruby
|
||||
uses: actions/setup-ruby@v1
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6.x
|
||||
|
||||
- name: Cache gems
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: vendor/bundle
|
||||
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gem-
|
||||
|
||||
- name: Bundle install
|
||||
run: |
|
||||
bundle install --path vendor/bundle
|
||||
bundle binstub cucumber --path bin
|
||||
ruby-version: "2.6"
|
||||
bundler-cache: true
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
|
||||
# - name: Install system packages
|
||||
# if: runner.os == 'Linux'
|
||||
# run: sudo apt-get install -y zsh fish
|
||||
go-version: "1.18"
|
||||
|
||||
- name: Run tests
|
||||
run: make test-all
|
||||
|
|
|
@ -12,9 +12,9 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: "1.13"
|
||||
go-version: "1.18"
|
||||
|
||||
- name: Publish release script
|
||||
run: script/publish-release
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -1,5 +1,5 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'aruba', '~> 1.0.0.pre.alpha.4'
|
||||
gem 'aruba', '~> 1.0.4'
|
||||
gem 'cucumber', '~> 3.1.2'
|
||||
gem 'sinatra'
|
||||
|
|
39
Gemfile.lock
39
Gemfile.lock
|
@ -1,18 +1,16 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
aruba (1.0.0.pre.alpha.4)
|
||||
childprocess (~> 1.0)
|
||||
contracts (~> 0.13)
|
||||
cucumber (>= 2.4, < 4.0)
|
||||
ffi (~> 1.9)
|
||||
aruba (1.0.4)
|
||||
childprocess (>= 2.0, < 5.0)
|
||||
contracts (~> 0.16.0)
|
||||
cucumber (>= 2.4, < 6.0)
|
||||
rspec-expectations (~> 3.4)
|
||||
thor (~> 0.19)
|
||||
backports (3.15.0)
|
||||
builder (3.2.3)
|
||||
childprocess (1.0.1)
|
||||
rake (< 13.0)
|
||||
contracts (0.16.0)
|
||||
thor (~> 1.0)
|
||||
backports (3.23.0)
|
||||
builder (3.2.4)
|
||||
childprocess (4.1.0)
|
||||
contracts (0.16.1)
|
||||
cucumber (3.1.2)
|
||||
builder (>= 2.1.2)
|
||||
cucumber-core (~> 3.2.0)
|
||||
|
@ -29,27 +27,24 @@ GEM
|
|||
cucumber-expressions (6.0.1)
|
||||
cucumber-tag_expressions (1.1.1)
|
||||
cucumber-wire (0.0.1)
|
||||
diff-lcs (1.3)
|
||||
ffi (1.11.1)
|
||||
ffi (1.11.1-java)
|
||||
diff-lcs (1.5.0)
|
||||
gherkin (5.1.0)
|
||||
multi_json (1.13.1)
|
||||
multi_json (1.15.0)
|
||||
multi_test (0.1.2)
|
||||
mustermann (1.0.3)
|
||||
rack (2.0.7)
|
||||
rack-protection (2.0.5)
|
||||
rack
|
||||
rake (12.3.3)
|
||||
rspec-expectations (3.8.4)
|
||||
rspec-expectations (3.11.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-support (3.8.2)
|
||||
rspec-support (~> 3.11.0)
|
||||
rspec-support (3.11.0)
|
||||
sinatra (2.0.5)
|
||||
mustermann (~> 1.0)
|
||||
rack (~> 2.0)
|
||||
rack-protection (= 2.0.5)
|
||||
tilt (~> 2.0)
|
||||
thor (0.20.3)
|
||||
thor (1.2.1)
|
||||
tilt (2.0.9)
|
||||
|
||||
PLATFORMS
|
||||
|
@ -57,9 +52,9 @@ PLATFORMS
|
|||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
aruba (~> 1.0.0.pre.alpha.4)
|
||||
aruba (~> 1.0.4)
|
||||
cucumber (~> 3.1.2)
|
||||
sinatra
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.1
|
||||
1.17.2
|
||||
|
|
|
@ -231,7 +231,7 @@ Feature: hub api
|
|||
"""
|
||||
Then the output should contain exactly:
|
||||
"""
|
||||
.query query {\n repository\n}\n
|
||||
.query query {\\n repository\\n}\\n\n
|
||||
"""
|
||||
|
||||
Scenario: POST body from file
|
||||
|
@ -340,7 +340,7 @@ Feature: hub api
|
|||
"""
|
||||
Then the output should contain exactly:
|
||||
"""
|
||||
.query repository(owner: "octocat", name: "Hello-World", nameWithOwner: "octocat/Hello-World")\n
|
||||
.query repository(owner: "octocat", name: "Hello-World", nameWithOwner: "octocat/Hello-World")\\n\n
|
||||
"""
|
||||
|
||||
Scenario: Cache response
|
||||
|
@ -508,7 +508,7 @@ Feature: hub api
|
|||
"""
|
||||
{}
|
||||
Your access token may have insufficient scopes. Visit http://github.com/settings/tokens
|
||||
to edit the 'hub' token and enable one of the following scopes: admin, repo
|
||||
to edit the 'hub' token and enable one of the following scopes: admin, repo\n
|
||||
"""
|
||||
|
||||
Scenario: Print the SSO challenge to stderr
|
||||
|
@ -526,5 +526,5 @@ Feature: hub api
|
|||
"""
|
||||
|
||||
You must authorize your token to access this organization:
|
||||
http://example.com?auth=HASH
|
||||
http://example.com?auth=HASH\n
|
||||
"""
|
||||
|
|
|
@ -18,7 +18,6 @@ Feature: hub apply
|
|||
}
|
||||
"""
|
||||
When I successfully run `hub apply -3 https://github.com/mislav/dotfiles/pull/387`
|
||||
Then the output should not contain anything
|
||||
Then a file named "README.md" should exist
|
||||
|
||||
Scenario: Apply commits when TMPDIR is empty
|
||||
|
|
|
@ -5,14 +5,9 @@ Feature: OAuth authentication
|
|||
Scenario: Ask for username & password, create authorization
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
require 'socket'
|
||||
require 'etc'
|
||||
machine_id = "#{Etc.getlogin}@#{Socket.gethostname}"
|
||||
|
||||
post('/authorizations') {
|
||||
assert_basic_auth 'mislav', 'kitty'
|
||||
assert :scopes => ['repo', 'gist'],
|
||||
:note => "hub for #{machine_id}",
|
||||
:note_url => 'https://hub.github.com/'
|
||||
status 201
|
||||
json :token => 'OTOKEN'
|
||||
|
@ -88,13 +83,9 @@ Feature: OAuth authentication
|
|||
Scenario: Rename & retry creating authorization if there's a token name collision
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
require 'socket'
|
||||
require 'etc'
|
||||
machine_id = "#{Etc.getlogin}@#{Socket.gethostname}"
|
||||
|
||||
post('/authorizations') {
|
||||
assert_basic_auth 'mislav', 'kitty'
|
||||
if params[:note] == "hub for #{machine_id} 3"
|
||||
if params[:note] =~ /\Ahub for .+ 3\Z/
|
||||
status 201
|
||||
json :token => 'OTOKEN'
|
||||
else
|
||||
|
@ -504,9 +495,9 @@ Feature: OAuth authentication
|
|||
Scenario: Config file is not writeable, should exit before asking for credentials
|
||||
Given $HUB_CONFIG is "/InvalidConfigFile"
|
||||
When I run `hub create` interactively
|
||||
Then the output should contain exactly:
|
||||
Then the output should contain:
|
||||
"""
|
||||
open /InvalidConfigFile: permission denied\n
|
||||
open /InvalidConfigFile:
|
||||
"""
|
||||
And the exit status should be 1
|
||||
And the file "../home/.config/hub" should not exist
|
||||
|
@ -536,5 +527,5 @@ Feature: OAuth authentication
|
|||
"""
|
||||
Error fetching releases: Forbidden (HTTP 403)
|
||||
You must authorize your token to access this organization:
|
||||
http://example.com?auth=HASH
|
||||
http://example.com?auth=HASH\n
|
||||
"""
|
||||
|
|
|
@ -21,14 +21,14 @@ Feature: hub compare
|
|||
Scenario: No args, no upstream
|
||||
When I run `hub compare`
|
||||
Then the exit status should be 1
|
||||
And the stderr should contain exactly "the current branch 'master' doesn't seem pushed to a remote"
|
||||
And the stderr should contain exactly "the current branch 'master' doesn't seem pushed to a remote\n"
|
||||
|
||||
Scenario: Can't compare default branch to self
|
||||
Given the default branch for "origin" is "develop"
|
||||
And I am on the "develop" branch with upstream "origin/develop"
|
||||
When I run `hub compare`
|
||||
Then the exit status should be 1
|
||||
And the stderr should contain exactly "the branch to compare 'develop' is the default branch"
|
||||
And the stderr should contain exactly "the branch to compare 'develop' is the default branch\n"
|
||||
|
||||
Scenario: No args, has upstream branch
|
||||
Given I am on the "feature" branch with upstream "origin/experimental"
|
||||
|
|
|
@ -107,7 +107,7 @@ Feature: hub create
|
|||
|
||||
Scenario: Cannot create from bare repo
|
||||
Given the current dir is not a repo
|
||||
And I run `git init --bare`
|
||||
And I run `git -c init.defaultBranch=main init --bare`
|
||||
When I run `hub create`
|
||||
Then the stderr should contain exactly "unable to determine git working directory\n"
|
||||
And the exit status should be 1
|
||||
|
|
|
@ -171,10 +171,10 @@ Feature: hub fork
|
|||
}
|
||||
"""
|
||||
When I run `hub fork`
|
||||
Then the exit status should be 128
|
||||
And the stderr should contain exactly:
|
||||
Then the exit status should not be 0
|
||||
And the stderr should contain:
|
||||
"""
|
||||
fatal: remote mislav already exists.\n
|
||||
remote mislav already exists.
|
||||
"""
|
||||
And the url for "mislav" should be "git@github.com:mislav/unrelated.git"
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ Feature: hub gist
|
|||
When I successfully run `hub gist show myhash`
|
||||
Then the output should contain exactly:
|
||||
"""
|
||||
my content is here
|
||||
my content is here\n
|
||||
"""
|
||||
|
||||
Scenario: Fetch a gist with many files
|
||||
|
@ -70,7 +70,7 @@ Feature: hub gist
|
|||
When I successfully run `hub gist show myhash hub_gist1.txt`
|
||||
Then the output should contain exactly:
|
||||
"""
|
||||
my content is here
|
||||
my content is here\n
|
||||
"""
|
||||
|
||||
Scenario: Create a gist from file
|
||||
|
@ -88,7 +88,7 @@ Feature: hub gist
|
|||
When I successfully run `hub gist create testfile.txt`
|
||||
Then the output should contain exactly:
|
||||
"""
|
||||
http://gists.github.com/somehash
|
||||
http://gists.github.com/somehash\n
|
||||
"""
|
||||
|
||||
Scenario: Open the new gist in a browser
|
||||
|
@ -130,7 +130,7 @@ Feature: hub gist
|
|||
When I successfully run `hub gist create testfile.txt testfile2.txt`
|
||||
Then the output should contain exactly:
|
||||
"""
|
||||
http://gists.github.com/somehash
|
||||
http://gists.github.com/somehash\n
|
||||
"""
|
||||
|
||||
Scenario: Create a gist from stdin
|
||||
|
@ -149,7 +149,7 @@ Feature: hub gist
|
|||
"""
|
||||
Then the output should contain exactly:
|
||||
"""
|
||||
http://gists.github.com/somehash
|
||||
http://gists.github.com/somehash\n
|
||||
"""
|
||||
|
||||
Scenario: Insufficient OAuth scopes
|
||||
|
@ -172,7 +172,7 @@ Feature: hub gist
|
|||
"""
|
||||
Error creating gist: Not Found (HTTP 404)
|
||||
Your access token may have insufficient scopes. Visit http://github.com/settings/tokens
|
||||
to edit the 'hub' token and enable one of the following scopes: gist
|
||||
to edit the 'hub' token and enable one of the following scopes: gist\n
|
||||
"""
|
||||
|
||||
Scenario: Infer correct OAuth scopes for gist
|
||||
|
@ -194,7 +194,7 @@ Feature: hub gist
|
|||
"""
|
||||
Error creating gist: Not Found (HTTP 404)
|
||||
Your access token may have insufficient scopes. Visit http://github.com/settings/tokens
|
||||
to edit the 'hub' token and enable one of the following scopes: gist
|
||||
to edit the 'hub' token and enable one of the following scopes: gist\n
|
||||
"""
|
||||
|
||||
Scenario: Create error
|
||||
|
|
|
@ -112,6 +112,7 @@ Feature: hub pr list
|
|||
#102 luke, jyn\n
|
||||
"""
|
||||
|
||||
@keep-ansi-escape-sequences
|
||||
Scenario: List draft status
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
|
|
|
@ -69,7 +69,7 @@ Feature: hub pr show
|
|||
Then "open https://github.com/ashemesh/hub/pull/102" should not be run
|
||||
And the output should contain exactly:
|
||||
"""
|
||||
#102 rey, github/troopers, github/cantina-band\n
|
||||
#102 rey, github/troopers, github/cantina-band\n\n
|
||||
"""
|
||||
|
||||
Scenario: Current branch in fork
|
||||
|
@ -208,7 +208,7 @@ Feature: hub pr show
|
|||
Then "open https://github.com/ashemesh/hub/pull/102" should not be run
|
||||
And the output should contain exactly:
|
||||
"""
|
||||
#102 rey, github/troopers, github/cantina-band\n
|
||||
#102 rey, github/troopers, github/cantina-band\n\n
|
||||
"""
|
||||
|
||||
Scenario: Show pull request by invalid number
|
||||
|
|
|
@ -1241,7 +1241,7 @@ Feature: hub pull-request
|
|||
And stderr should contain exactly:
|
||||
"""
|
||||
Error creating pull request: Post https://api.github.com/repositories/12345/pulls: refusing to follow HTTP 301 redirect for a POST request
|
||||
Have your site admin use HTTP 308 for this kind of redirect
|
||||
Have your site admin use HTTP 308 for this kind of redirect\n
|
||||
"""
|
||||
|
||||
Scenario: Default message with --push
|
||||
|
|
|
@ -359,7 +359,7 @@ MARKDOWN
|
|||
### Hello to my release
|
||||
|
||||
Here is what's broken:
|
||||
- everything\n
|
||||
- everything\n\n
|
||||
"""
|
||||
|
||||
Scenario: Show release no tag
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
require 'fileutils'
|
||||
|
||||
Given(/^HTTPS is preferred$/) do
|
||||
run_command_and_stop %(git config --global hub.protocol https)
|
||||
run_ignored_command %(git config --global hub.protocol https)
|
||||
end
|
||||
|
||||
Given(/^there are no remotes$/) do
|
||||
run_command_and_stop 'git remote'
|
||||
expect(last_command_started).not_to have_output
|
||||
output = run_ignored_command 'git remote'
|
||||
expect(output).to be_empty
|
||||
end
|
||||
|
||||
Given(/^"([^"]*)" is a whitelisted Enterprise host$/) do |host|
|
||||
run_command_and_stop %(git config --global --add hub.host "#{host}")
|
||||
run_ignored_command %(git config --global --add hub.host "#{host}")
|
||||
end
|
||||
|
||||
Given(/^git "(.+?)" is set to "(.+?)"$/) do |key, value|
|
||||
run_command_and_stop %(git config #{key} "#{value}")
|
||||
run_ignored_command %(git config #{key} "#{value}")
|
||||
end
|
||||
|
||||
Given(/^the "([^"]*)" remote has(?: (push))? url "([^"]*)"$/) do |remote_name, push, url|
|
||||
run_command_and_stop 'git remote'
|
||||
unless last_command_started.stdout.split("\n").include? remote_name
|
||||
run_command_and_stop %(git remote add #{remote_name} "#{url}")
|
||||
remotes = run_ignored_command 'git remote'
|
||||
unless remotes.split("\n").include? remote_name
|
||||
run_ignored_command %(git remote add #{remote_name} "#{url}")
|
||||
else
|
||||
run_command_and_stop %(git remote set-url #{"--push" if push} #{remote_name} "#{url}")
|
||||
run_ignored_command %(git remote set-url #{"--push" if push} #{remote_name} "#{url}")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -52,7 +52,7 @@ Given(/^I am in "([^"]*)" git repo$/) do |dir_name|
|
|||
end
|
||||
|
||||
Given(/^a (bare )?git repo in "([^"]*)"$/) do |bare, dir_name|
|
||||
run_command_and_stop %(git init --quiet #{"--bare" if bare} '#{dir_name}')
|
||||
run_ignored_command %(git -c init.defaultBranch=master init --quiet #{"--bare" if bare} '#{dir_name}')
|
||||
end
|
||||
|
||||
Given(/^a git bundle named "([^"]*)"$/) do |file|
|
||||
|
@ -71,8 +71,8 @@ end
|
|||
Given(/^there is a commit named "([^"]+)"$/) do |name|
|
||||
empty_commit
|
||||
empty_commit
|
||||
run_command_and_stop %(git tag #{name})
|
||||
run_command_and_stop %(git reset --quiet --hard HEAD^)
|
||||
run_ignored_command %(git tag #{name})
|
||||
run_ignored_command %(git reset --quiet --hard HEAD^)
|
||||
end
|
||||
|
||||
Given(/^there is a git FETCH_HEAD$/) do
|
||||
|
@ -83,7 +83,7 @@ Given(/^there is a git FETCH_HEAD$/) do
|
|||
fetch_head.puts "%s\t\t'refs/heads/made-up' of git://github.com/made/up.git" % `git rev-parse HEAD`.chomp
|
||||
end
|
||||
end
|
||||
run_command_and_stop %(git reset --quiet --hard HEAD^)
|
||||
run_ignored_command %(git reset --quiet --hard HEAD^)
|
||||
end
|
||||
|
||||
When(/^I make (a|\d+) commits?(?: with message "([^"]+)")?$/) do |num, msg|
|
||||
|
@ -114,15 +114,15 @@ Given(/^the "([^"]+)" branch is pushed to "([^"]+)"$/) do |name, upstream|
|
|||
end
|
||||
|
||||
Given(/^I am on the "([^"]+)" branch(?: (pushed to|with upstream) "([^"]+)")?$/) do |name, type, upstream|
|
||||
run_command_and_stop %(git checkout --quiet -b #{shell_escape name})
|
||||
run_ignored_command %(git checkout --quiet -b #{shell_escape name})
|
||||
empty_commit
|
||||
|
||||
if upstream
|
||||
full_upstream = upstream.start_with?('refs/') ? upstream : "refs/remotes/#{upstream}"
|
||||
run_command_and_stop %(git update-ref #{shell_escape full_upstream} HEAD)
|
||||
run_ignored_command %(git update-ref #{shell_escape full_upstream} HEAD)
|
||||
|
||||
if type == 'with upstream'
|
||||
run_command_and_stop %(git branch --set-upstream-to #{shell_escape upstream})
|
||||
run_ignored_command %(git branch --set-upstream-to #{shell_escape upstream})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -136,13 +136,13 @@ Given(/^the default branch for "([^"]+)" is "([^"]+)"$/) do |remote, branch|
|
|||
FileUtils.cp '.git/refs/heads/master', ref_file
|
||||
end
|
||||
end
|
||||
run_command_and_stop %(git remote set-head #{remote} #{branch})
|
||||
run_ignored_command %(git remote set-head #{remote} #{branch})
|
||||
end
|
||||
|
||||
Given(/^I am in detached HEAD$/) do
|
||||
empty_commit
|
||||
empty_commit
|
||||
run_command_and_stop %(git checkout HEAD^)
|
||||
run_ignored_command %(git checkout HEAD^)
|
||||
end
|
||||
|
||||
Given(/^the current dir is not a repo$/) do
|
||||
|
@ -185,26 +185,26 @@ Then(/^the git command should be unchanged$/) do
|
|||
end
|
||||
|
||||
Then(/^the url for "([^"]*)" should be "([^"]*)"$/) do |name, url|
|
||||
run_command_and_stop %(git config --get-all remote.#{name}.url)
|
||||
expect(last_command_started).to have_output(url)
|
||||
output = run_ignored_command %(git config --get-all remote.#{name}.url)
|
||||
expect(output).to include(url)
|
||||
end
|
||||
|
||||
Then(/^the "([^"]*)" submodule url should be "([^"]*)"$/) do |name, url|
|
||||
run_command_and_stop %(git config --get-all submodule."#{name}".url)
|
||||
expect(last_command_started).to have_output(url)
|
||||
output = run_ignored_command %(git config --get-all submodule."#{name}".url)
|
||||
expect(output).to include(url)
|
||||
end
|
||||
|
||||
Then(/^"([^"]*)" should merge "([^"]*)" from remote "([^"]*)"$/) do |name, merge, remote|
|
||||
run_command_and_stop %(git config --get-all branch.#{name}.remote)
|
||||
expect(last_command_started).to have_output(remote)
|
||||
output = run_ignored_command %(git config --get-all branch.#{name}.remote)
|
||||
expect(output).to include(remote)
|
||||
|
||||
run_command_and_stop %(git config --get-all branch.#{name}.merge)
|
||||
expect(last_command_started).to have_output(merge)
|
||||
output = run_ignored_command %(git config --get-all branch.#{name}.merge)
|
||||
expect(output).to include(merge)
|
||||
end
|
||||
|
||||
Then(/^there should be no "([^"]*)" remote$/) do |remote_name|
|
||||
run_command_and_stop 'git remote'
|
||||
expect(last_command_started.output.split("\n")).to_not include(remote_name)
|
||||
remotes = run_ignored_command 'git remote'
|
||||
expect(remotes.split("\n")).to_not include(remote_name)
|
||||
end
|
||||
|
||||
Then(/^the file "([^"]*)" should have mode "([^"]*)"$/) do |file, expected_mode|
|
||||
|
@ -216,8 +216,8 @@ Given(/^the remote commit states of "(.*?)" "(.*?)" are:$/) do |proj, ref, json_
|
|||
if ref == 'HEAD'
|
||||
empty_commit
|
||||
end
|
||||
run_command_and_stop %(git rev-parse #{ref})
|
||||
rev = last_command_started.output.chomp
|
||||
output = run_ignored_command %(git rev-parse #{ref})
|
||||
rev = output.chomp
|
||||
|
||||
host, owner, repo = proj.split('/', 3)
|
||||
if repo.nil?
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
require 'open3'
|
||||
require 'shellwords'
|
||||
|
||||
module Aruba
|
||||
remove_const :Command
|
||||
class Command
|
||||
attr_reader :commandline, :stdout, :stderr
|
||||
attr_reader :exit_timeout, :io_wait_timeout, :startup_wait_time, :environment, :stop_signal, :exit_status
|
||||
|
||||
def initialize(cmd, mode:, exit_timeout:, io_wait_timeout:,
|
||||
working_directory:, environment:, main_class:, stop_signal:,
|
||||
startup_wait_time:, event_bus:)
|
||||
@commandline = cmd
|
||||
@working_directory = working_directory
|
||||
@event_bus = event_bus
|
||||
@exit_timeout = exit_timeout
|
||||
@io_wait_timeout = io_wait_timeout
|
||||
@startup_wait_time = startup_wait_time
|
||||
@environment = environment
|
||||
@stop_signal = stop_signal
|
||||
|
||||
@stopped = false
|
||||
@exit_status = nil
|
||||
@stdout = nil
|
||||
@stderr = nil
|
||||
end
|
||||
|
||||
def inspect
|
||||
%(#<Command "#{@commandline}" exited:#{@exit_status}>)
|
||||
end
|
||||
|
||||
def output
|
||||
stdout + stderr
|
||||
end
|
||||
|
||||
def start
|
||||
@event_bus.notify Events::CommandStarted.new(self)
|
||||
cmd = Shellwords.split @commandline
|
||||
@stdin_io, @stdout_io, @stderr_io, @thread = Open3.popen3(@environment, *cmd, chdir: @working_directory)
|
||||
end
|
||||
|
||||
def write(input)
|
||||
@stdin_io.write input
|
||||
@stdin_io.flush
|
||||
end
|
||||
|
||||
def close_io(io)
|
||||
case io
|
||||
when :stdin then @stdin_io.close
|
||||
else
|
||||
raise ArgumentError, io.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def stop
|
||||
return if @exit_status
|
||||
@event_bus.notify Events::CommandStopped.new(self)
|
||||
terminate
|
||||
end
|
||||
|
||||
def terminate
|
||||
return if @exit_status
|
||||
|
||||
close_io(:stdin)
|
||||
@stdout = @stdout_io.read
|
||||
@stderr = @stderr_io.read
|
||||
|
||||
status = @thread.value
|
||||
@exit_status = status.exitstatus
|
||||
@thread = nil
|
||||
end
|
||||
|
||||
def interactive?
|
||||
true
|
||||
end
|
||||
|
||||
def timed_out?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,6 +2,7 @@ require 'aruba/cucumber'
|
|||
require 'fileutils'
|
||||
require 'forwardable'
|
||||
require 'tmpdir'
|
||||
require 'open3'
|
||||
|
||||
system_git = `which git 2>/dev/null`.chomp
|
||||
bin_dir = File.expand_path('../fakebin', __FILE__)
|
||||
|
@ -139,10 +140,17 @@ World Module.new {
|
|||
@empty_commit_count = defined?(@empty_commit_count) ? @empty_commit_count + 1 : 1
|
||||
message = "empty #{@empty_commit_count}"
|
||||
end
|
||||
run_command_and_stop "git commit --quiet -m '#{message}' --allow-empty"
|
||||
run_ignored_command "git commit --quiet -m '#{message}' --allow-empty"
|
||||
end
|
||||
|
||||
def shell_escape(message)
|
||||
message.to_s.gsub(/['"\\ $]/) { |m| "\\#{m}" }
|
||||
end
|
||||
|
||||
# runs a command entirely outside of Aruba's command system and returns its stdout
|
||||
def run_ignored_command(cmd_string)
|
||||
stdout, stderr, status = Open3.capture3(aruba.environment, cmd_string, chdir: expand_path('.'))
|
||||
expect(status).to be_success
|
||||
stdout
|
||||
end
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# Avoids over-zealous sanitize_text
|
||||
# https://github.com/cucumber/aruba/blob/v1.0.4/lib/aruba/matchers/string/output_string_eq.rb
|
||||
|
||||
sanitize_text = ->(expected) {
|
||||
expected.to_s.
|
||||
# convert "\n" in expectations to literal newline, unless it is preceded by another backslash
|
||||
gsub(/(?<!\\)\\n/, "\n").
|
||||
# convert "\e" in expectations to a literal ESC, unless it is preceded by another backslash
|
||||
gsub(/(?<!\\)\\e/, "\e").
|
||||
gsub('\\\\', '\\')
|
||||
}
|
||||
|
||||
RSpec::Matchers.define :output_string_eq do |expected|
|
||||
match do |actual|
|
||||
@expected = sanitize_text.(expected)
|
||||
@actual = actual.to_s
|
||||
@actual = extract_text(@actual) if aruba.config.remove_ansi_escape_sequences
|
||||
|
||||
@expected == @actual
|
||||
end
|
||||
|
||||
diffable
|
||||
|
||||
description { "output string is eq: #{description_of(self.expected)}" }
|
||||
end
|
||||
|
||||
RSpec::Matchers.define :have_output do |expected|
|
||||
match do |actual|
|
||||
@old_actual = actual
|
||||
|
||||
unless @old_actual.respond_to? :output
|
||||
raise "Expected #{@old_actual} to respond to #output"
|
||||
end
|
||||
|
||||
@old_actual.stop
|
||||
|
||||
@actual = actual.output
|
||||
@actual = extract_text(@actual) if aruba.config.remove_ansi_escape_sequences
|
||||
|
||||
expected === @actual
|
||||
end
|
||||
|
||||
diffable
|
||||
|
||||
description { "have output: #{description_of(expected)}" }
|
||||
|
||||
failure_message do |_actual|
|
||||
"expected `#{@old_actual.commandline}` to #{description_of(expected)}\n" \
|
||||
"but was: #{description_of(@actual)}"
|
||||
end
|
||||
end
|
||||
|
||||
RSpec::Matchers.alias_matcher :an_output_string_being_eq, :output_string_eq
|
|
@ -35,6 +35,8 @@ type Host struct {
|
|||
|
||||
type Config struct {
|
||||
Hosts []*Host `toml:"hosts"`
|
||||
|
||||
stdinScanner *bufio.Scanner
|
||||
}
|
||||
|
||||
func (c *Config) PromptForHost(host string) (h *Host, err error) {
|
||||
|
@ -181,8 +183,11 @@ func (c *Config) PromptForOTP() string {
|
|||
}
|
||||
|
||||
func (c *Config) scanLine() string {
|
||||
if c.stdinScanner == nil {
|
||||
c.stdinScanner = bufio.NewScanner(os.Stdin)
|
||||
}
|
||||
var line string
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
scanner := c.stdinScanner
|
||||
if scanner.Scan() {
|
||||
line = scanner.Text()
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package github
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package github
|
||||
|
|
2
go.mod
2
go.mod
|
@ -14,6 +14,6 @@ require (
|
|||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2 // indirect
|
||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect
|
||||
gopkg.in/yaml.v2 v2.0.0-20190319135612-7b8349ac747c
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -21,8 +21,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 h1:2mqDk8w/o6UmeUCu5Qiq2y7iMf6anbx+YA8d1JFoFrs=
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2 h1:T5DasATyLQfmbTpfEXx/IOL9vfjzW6up+ZDkmHvIf2s=
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=
|
||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
|
|
1
main.go
1
main.go
|
@ -1,3 +1,4 @@
|
|||
//go:build go1.8
|
||||
// +build go1.8
|
||||
|
||||
package main
|
||||
|
|
Загрузка…
Ссылка в новой задаче