bard 1.8.0.beta4 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +76 -0
  3. data/PLUGINS.md +114 -0
  4. data/README.md +14 -6
  5. data/features/ci.feature +62 -0
  6. data/features/deploy_git_workflow.feature +88 -0
  7. data/features/step_definitions/bard_steps.rb +96 -0
  8. data/features/support/bard-coverage +16 -0
  9. data/features/support/env.rb +10 -1
  10. data/features/support/test_server.rb +2 -1
  11. data/lib/bard/ci/github_actions.rb +1 -2
  12. data/lib/bard/ci/jenkins.rb +82 -11
  13. data/lib/bard/ci/local.rb +6 -6
  14. data/lib/bard/ci/runner.rb +35 -1
  15. data/lib/bard/ci.rb +11 -23
  16. data/lib/bard/cli/ci.rb +45 -38
  17. data/lib/bard/cli/deploy.rb +40 -8
  18. data/lib/bard/cli/hurt.rb +10 -15
  19. data/lib/bard/cli/install.rb +7 -12
  20. data/lib/bard/cli/open.rb +12 -16
  21. data/lib/bard/cli/ping.rb +8 -14
  22. data/lib/bard/cli/run.rb +5 -3
  23. data/lib/bard/cli/vim.rb +5 -10
  24. data/lib/bard/cli.rb +7 -12
  25. data/lib/bard/config.rb +1 -13
  26. data/lib/bard/github.rb +2 -4
  27. data/lib/bard/plugin.rb +99 -0
  28. data/lib/bard/plugins/backup.rb +19 -0
  29. data/lib/bard/plugins/github_pages.rb +34 -0
  30. data/lib/bard/plugins/hurt.rb +5 -0
  31. data/lib/bard/plugins/install.rb +5 -0
  32. data/lib/bard/plugins/jenkins.rb +6 -0
  33. data/lib/bard/plugins/new.rb +5 -0
  34. data/lib/bard/plugins/ping.rb +6 -0
  35. data/lib/bard/plugins/provision.rb +5 -0
  36. data/lib/bard/plugins/vim.rb +5 -0
  37. data/lib/bard/secrets.rb +10 -0
  38. data/lib/bard/version.rb +1 -1
  39. data/spec/bard/ci/github_actions_spec.rb +116 -13
  40. data/spec/bard/ci/jenkins_spec.rb +139 -0
  41. data/spec/bard/ci/runner_spec.rb +61 -0
  42. data/spec/bard/cli/ci_spec.rb +34 -8
  43. data/spec/bard/cli/deploy_spec.rb +20 -8
  44. data/spec/bard/cli/hurt_spec.rb +2 -2
  45. data/spec/bard/cli/install_spec.rb +4 -4
  46. data/spec/bard/cli/open_spec.rb +10 -8
  47. data/spec/bard/cli/ping_spec.rb +5 -5
  48. data/spec/bard/cli/run_spec.rb +20 -1
  49. data/spec/bard/cli/vim_spec.rb +5 -5
  50. data/spec/bard/github_spec.rb +1 -1
  51. data/spec/bard/plugin_spec.rb +79 -0
  52. data/spec/spec_helper.rb +6 -1
  53. metadata +27 -3
  54. data/README.rdoc +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b1a0399d5fd80c8599d584b056a6ae7b77959cdf9f394e3d76461826f2219f9f
4
- data.tar.gz: cd5b858005ffeddd001fffcef8538c07572b70d81ab086c9b44c4b06b2304f18
3
+ metadata.gz: 937ff227cd4b15691d6aa48c4d5f6670aa6c0232adf650672bd8790fb6baa6fa
4
+ data.tar.gz: 2858f62171dedf98e5518e16a82b0e1569c8c251024e7a934b9ebcbbec15a568
5
5
  SHA512:
6
- metadata.gz: 279c018696cdbef81518d54e37bc5f1508b42808e8c8f448bd048816a398f28b46ecd62865481ab3f83da742c4015b1d5acb69941769f004f40e7d88f765add7
7
- data.tar.gz: 3b7d5e076a8f5f20ac500e8261e4ff15b10dd7a8814c1aba097a8f1635dc610ed60f951af648a2a0e56e6adce2f2da8eee2ca54a2ad93312446883de3e416d93
6
+ metadata.gz: 03ecce7b9ee18e490a207d776b92958f71d17d2738f6641ceeb9a9a1605aba169dff86f942ae727134197bbed6b5b80825ed8a9a02b17d912dee3aa176ecae89
7
+ data.tar.gz: b39fe1a1e8d4e92961425ffdd5856d90f926d6f96cb19690e884b2b7c00776f1251285c9ef2034303f0cd3490823206cf975903f775ac19104e4b3243ac72b14
data/CLAUDE.md ADDED
@@ -0,0 +1,76 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## What is Bard?
6
+
7
+ Bard is a modular deployment CLI tool for Ruby applications. It provides:
8
+ - SSH-based deployment via git pull
9
+ - GitHub Pages static site deployment
10
+ - Custom pluggable deployment strategies
11
+ - Data syncing (database dumps and file rsync)
12
+ - CI integration (GitHub Actions/Jenkins)
13
+ - Server provisioning
14
+
15
+ ## Development Commands
16
+
17
+ ```bash
18
+ # Install dependencies
19
+ bundle install
20
+
21
+ # Run all tests (RSpec + Cucumber)
22
+ bundle exec rake
23
+
24
+ # Run only RSpec tests
25
+ bundle exec rspec
26
+
27
+ # Run a single spec file
28
+ bundle exec rspec spec/bard/target_spec.rb
29
+
30
+ # Run a specific test by line number
31
+ bundle exec rspec spec/bard/target_spec.rb:42
32
+
33
+ # Run Cucumber features (slow - avoid full suite)
34
+ bundle exec cucumber features/deploy.feature
35
+
36
+ # Run bard from source
37
+ bundle exec bin/bard
38
+ ```
39
+
40
+ ## Architecture
41
+
42
+ ### Core Classes
43
+
44
+ - **`Bard::CLI`** (`lib/bard/cli.rb`) - Thor-based command dispatcher. Commands are modules in `lib/bard/cli/` included into CLI.
45
+ - **`Bard::Config`** (`lib/bard/config.rb`) - DSL parser for `bard.rb` files. Manages targets and settings.
46
+ - **`Bard::Target`** (`lib/bard/target.rb`) - Deployment destination with capabilities (ssh, ping, data). Supports dynamic strategy DSL via `method_missing`.
47
+ - **`Bard::Server`** (`lib/bard/server.rb`) - Legacy v1.x server representation (deprecated, use Target).
48
+ - **`Bard::DeployStrategy`** (`lib/bard/deploy_strategy.rb`) - Base class for deployment strategies. Subclasses auto-register via Ruby's `inherited` hook.
49
+
50
+ ### Capability System
51
+
52
+ Targets track enabled capabilities (`:ssh`, `:ping`, `:github_pages`, etc.). Commands call `require_capability!` to ensure the target supports the operation.
53
+
54
+ ### Strategy Auto-Registration
55
+
56
+ Custom strategies subclass `DeployStrategy` and are automatically registered by class name:
57
+ ```ruby
58
+ class Bard::DeployStrategy::Jets < DeployStrategy # registers as :jets
59
+ def deploy; ...; end
60
+ end
61
+ ```
62
+
63
+ ### File Organization
64
+
65
+ - `lib/bard/cli/*.rb` - CLI command modules (deploy, data, ssh, etc.)
66
+ - `lib/bard/ci/*.rb` - CI system integrations (github_actions, jenkins, local)
67
+ - `lib/bard/deploy_strategy/*.rb` - Built-in strategies (ssh, github_pages)
68
+ - `lib/bard/provision/*.rb` - Server provisioning modules
69
+ - `spec/` - RSpec unit tests
70
+ - `features/` - Cucumber integration tests
71
+
72
+ ## Testing Notes
73
+
74
+ - Use `focus: true` in RSpec to run specific tests
75
+ - Cucumber tests use testcontainers and are slow - run specific feature files only
76
+ - SimpleCov tracks coverage across both RSpec and Cucumber runs
data/PLUGINS.md ADDED
@@ -0,0 +1,114 @@
1
+ # Plugin Development
2
+
3
+ Bard uses a plugin system to extend functionality. Plugins can add CLI commands, target methods, and config DSL methods.
4
+
5
+ ## Plugin Structure
6
+
7
+ Plugins live in `lib/bard/plugins/` and register themselves:
8
+
9
+ ```ruby
10
+ # lib/bard/plugins/my_plugin.rb
11
+ require "bard/plugin"
12
+
13
+ Bard::Plugin.register :my_plugin do
14
+ # Add CLI commands (class must implement .setup)
15
+ cli "Bard::CLI::MyPlugin", require: "bard/cli/my_plugin"
16
+
17
+ # Add methods to Target
18
+ target_method :my_feature do |url = nil|
19
+ if url.nil?
20
+ @my_feature_url
21
+ else
22
+ @my_feature_url = url
23
+ enable_capability(:my_feature)
24
+ end
25
+ end
26
+
27
+ # Add methods to Config
28
+ config_method :my_global_setting do |value = nil|
29
+ if value.nil?
30
+ @my_global_setting
31
+ else
32
+ @my_global_setting = value
33
+ end
34
+ end
35
+ end
36
+ ```
37
+
38
+ ## CLI Commands
39
+
40
+ CLI commands inherit from `Bard::CLI::Command` and implement a `setup` class method:
41
+
42
+ ```ruby
43
+ # lib/bard/cli/my_plugin.rb
44
+ require "bard/cli/command"
45
+
46
+ class Bard::CLI::MyPlugin < Bard::CLI::Command
47
+ desc "mycommand", "Description of my command"
48
+ def mycommand
49
+ puts "Hello from my plugin!"
50
+ end
51
+ end
52
+ ```
53
+
54
+ The `Command` base class provides:
55
+ - Automatic `setup` that registers the command with the CLI
56
+ - Delegation to the CLI instance (access to `config`, `project_name`, etc.)
57
+ - `desc` and `option` class methods for Thor integration
58
+
59
+ For Thor subcommand groups (nested under `bard mygroup`):
60
+
61
+ ```ruby
62
+ # lib/bard/cli/my_subcommand.rb
63
+ class Bard::CLI::MySubcommand < Thor
64
+ def self.setup(cli)
65
+ cli.register(self, "mygroup", "mygroup COMMAND", "My subcommand group")
66
+ end
67
+
68
+ desc "action", "Do something"
69
+ def action
70
+ puts "Hello from subcommand!"
71
+ end
72
+ end
73
+ ```
74
+
75
+ ## Adding Strategies
76
+
77
+ Plugins can add deployment strategies or CI runners:
78
+
79
+ ```ruby
80
+ # Custom deploy strategy
81
+ module Bard
82
+ class DeployStrategy
83
+ class MyCloud < DeployStrategy
84
+ def deploy
85
+ # Deployment logic here
86
+ run! "my-cloud deploy #{target.key}"
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ # Custom CI runner
93
+ module Bard
94
+ class CI
95
+ class Runner
96
+ class MyCI < Runner
97
+ def run
98
+ # Start CI run
99
+ end
100
+
101
+ def status
102
+ # Return current status
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ ```
109
+
110
+ Strategies auto-register via Ruby's `inherited` hook. The class name determines the strategy key (e.g., `MyCloud` → `:my_cloud`).
111
+
112
+ ## Plugin Loading
113
+
114
+ Plugins are loaded automatically from `lib/bard/plugins/`. The load order is alphabetical by filename. For CI runners, the last registered runner becomes the default.
data/README.md CHANGED
@@ -12,7 +12,7 @@ end
12
12
  ```
13
13
 
14
14
  ```bash
15
- bard deploy production
15
+ bard deploy
16
16
  ```
17
17
 
18
18
  ## Features
@@ -115,17 +115,21 @@ end
115
115
  ### Deployment
116
116
 
117
117
  ```bash
118
- # Deploy to production
119
- bard deploy production
118
+ # Deploy current branch to production (default)
119
+ bard deploy
120
120
 
121
- # Deploy to staging
122
- bard deploy staging
121
+ # Deploy a specific branch to production
122
+ bard deploy feature-branch
123
+
124
+ # Deploy to a different target
125
+ bard deploy --target=staging
126
+ bard deploy feature-branch --target=staging
123
127
 
124
128
  # Deploy feature branch to staging (no merge)
125
129
  bard stage feature-branch
126
130
 
127
131
  # Skip CI checks
128
- bard deploy production --skip-ci
132
+ bard deploy --skip-ci
129
133
  ```
130
134
 
131
135
  ### Data Management
@@ -459,6 +463,10 @@ See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed architecture documentation.
459
463
 
460
464
  See [CUSTOM_STRATEGIES.md](CUSTOM_STRATEGIES.md) for a step-by-step guide to creating custom deployment strategies.
461
465
 
466
+ ## Plugin Development
467
+
468
+ See [PLUGINS.md](PLUGINS.md) for a guide to creating plugins.
469
+
462
470
  ## Development
463
471
 
464
472
  ```bash
@@ -0,0 +1,62 @@
1
+ Feature: bard ci
2
+ Run continuous integration tests.
3
+
4
+ Background:
5
+ Given a test server is running
6
+
7
+ Scenario: no CI configured error
8
+ When I run expecting failure: bard ci
9
+ Then the output should contain "No CI found"
10
+ And the output should contain "Re-run with --skip-ci to bypass CI"
11
+
12
+ Scenario: local CI runs successfully
13
+ Given a local CI script that passes
14
+ When I run: bard ci --local-ci
15
+ Then the output should contain "Continuous integration: starting build"
16
+ And the output should contain "Continuous integration: success!"
17
+
18
+ Scenario: local CI reports failure
19
+ Given a local CI script that fails with "Test failed: expected 1 but got 2"
20
+ When I run expecting failure: bard ci --local-ci
21
+ Then the output should contain "Test failed: expected 1 but got 2"
22
+ And the output should contain "Automated tests failed!"
23
+
24
+ Scenario: --ci option runs specified CI runner
25
+ Given a local CI script that passes
26
+ When I run: bard ci --ci=local
27
+ Then the output should contain "Continuous integration: starting build"
28
+ And the output should contain "Continuous integration: success!"
29
+
30
+ Scenario: --ci option reports failure from specified runner
31
+ Given a local CI script that fails with "Custom runner failed"
32
+ When I run expecting failure: bard ci --ci=local
33
+ Then the output should contain "Custom runner failed"
34
+ And the output should contain "Automated tests failed!"
35
+
36
+ Scenario: deploy passes --ci option to CI
37
+ Given a local CI script that passes
38
+ And I create a file "ci-option-test.txt" with content "ci option test"
39
+ And I commit the changes with message "Add CI option test file"
40
+ When I run: bard deploy --ci=local
41
+ Then the output should contain "Continuous integration: starting build"
42
+ And the output should contain "Continuous integration: success!"
43
+ And the output should contain "Deploy Succeeded"
44
+
45
+ Scenario: deploy runs CI before deploying
46
+ Given a local CI script that passes
47
+ And I create a file "ci-test.txt" with content "ci test"
48
+ And I commit the changes with message "Add CI test file"
49
+ When I run: bard deploy --local-ci
50
+ Then the output should contain "Continuous integration: starting build"
51
+ And the output should contain "Continuous integration: success!"
52
+ And the output should contain "Deploy Succeeded"
53
+
54
+ Scenario: deploy aborts if CI fails
55
+ Given a local CI script that fails with "Build failed"
56
+ And I create a file "ci-fail.txt" with content "ci fail test"
57
+ And I commit the changes with message "Add CI fail test file"
58
+ When I run expecting failure: bard deploy --local-ci
59
+ Then the output should contain "Continuous integration: starting build"
60
+ And the output should contain "Build failed"
61
+ And the output should contain "Automated tests failed!"
62
+ And the output should not contain "Deploy Succeeded"
@@ -0,0 +1,88 @@
1
+ Feature: bard deploy git workflow
2
+ Git workflow behaviors during deploy.
3
+
4
+ Background:
5
+ Given a test server is running
6
+
7
+ Scenario: deploy on master pushes unpushed commits
8
+ Given I create a file "local-only.txt" with content "local commit"
9
+ And I commit the changes with message "Add local only file"
10
+ When I run: bard deploy --skip-ci
11
+ Then the output should contain "Deploy Succeeded"
12
+ When I run: bard run "cat local-only.txt"
13
+ Then the output should contain "local commit"
14
+
15
+ Scenario: feature branch fast-forward merge
16
+ Given I create and switch to branch "feature-branch"
17
+ And I create a file "feature.txt" with content "feature content"
18
+ And I commit the changes with message "Add feature"
19
+ When I run: bard deploy --skip-ci
20
+ Then the output should contain "Deploy Succeeded"
21
+ And I should be on branch "master"
22
+ And branch "feature-branch" should not exist locally
23
+ And branch "feature-branch" should not exist on origin
24
+ When I run: bard run "cat feature.txt"
25
+ Then the output should contain "feature content"
26
+
27
+ Scenario: feature branch requires rebase
28
+ Given I create and switch to branch "feature-branch"
29
+ And I create a file "feature.txt" with content "feature content"
30
+ And I commit the changes with message "Add feature"
31
+ And master has an additional commit from another source
32
+ When I run: bard deploy --skip-ci
33
+ Then the output should contain "The master branch has advanced"
34
+ And the output should contain "Attempting rebase"
35
+ And the output should contain "Deploy Succeeded"
36
+ And I should be on branch "master"
37
+ When I run: bard run "cat feature.txt"
38
+ Then the output should contain "feature content"
39
+ When I run: bard run "cat remote-change.txt"
40
+ Then the output should contain "remote change"
41
+
42
+ Scenario: feature branch rebase conflict
43
+ Given I create and switch to branch "feature-branch"
44
+ And I create a file "conflict.txt" with content "feature content"
45
+ And I commit the changes with message "Add conflicting file"
46
+ And master has a conflicting commit to "conflict.txt"
47
+ When I run expecting failure: bard deploy --skip-ci
48
+ Then the output should contain "The master branch has advanced"
49
+ And the output should contain "Attempting rebase"
50
+ And the output should contain "Running command failed"
51
+
52
+ Scenario: branch cleanup after deploy
53
+ Given I create and switch to branch "cleanup-test"
54
+ And I create a file "cleanup.txt" with content "cleanup test"
55
+ And I commit the changes with message "Add cleanup test file"
56
+ And I push branch "cleanup-test" to origin
57
+ When I run: bard deploy --skip-ci
58
+ Then the output should contain "Deleting branch: cleanup-test"
59
+ And the output should contain "Deploy Succeeded"
60
+ And I should be on branch "master"
61
+ And branch "cleanup-test" should not exist locally
62
+ And branch "cleanup-test" should not exist on origin
63
+
64
+ Scenario: deploy a branch without checking it out
65
+ Given I create and switch to branch "feature-branch"
66
+ And I create a file "feature.txt" with content "feature content"
67
+ And I commit the changes with message "Add feature"
68
+ And I switch to branch "master"
69
+ When I run: bard deploy feature-branch --skip-ci
70
+ Then the output should contain "Deploy Succeeded"
71
+ And I should be on branch "master"
72
+ And branch "feature-branch" should not exist locally
73
+ When I run: bard run "cat feature.txt"
74
+ Then the output should contain "feature content"
75
+
76
+ Scenario: deploy a branch that requires rebase without checking it out
77
+ Given I create and switch to branch "feature-branch"
78
+ And I create a file "feature.txt" with content "feature content"
79
+ And I commit the changes with message "Add feature"
80
+ And I switch to branch "master"
81
+ And master has an additional commit from another source
82
+ When I run: bard deploy feature-branch --skip-ci
83
+ Then the output should contain "The master branch has advanced"
84
+ And the output should contain "Attempting rebase"
85
+ And the output should contain "Deploy Succeeded"
86
+ And I should be on branch "master"
87
+ When I run: bard run "cat feature.txt"
88
+ Then the output should contain "feature content"
@@ -37,3 +37,99 @@ Then /^a file "([^\"]+)" should exist locally$/ do |filename|
37
37
  path = File.join(@test_dir, filename)
38
38
  expect(File.exist?(path)).to be(true), "Expected file #{filename} to exist at #{path}"
39
39
  end
40
+
41
+ # Branch management
42
+ Given /^I create and switch to branch "([^"]+)"$/ do |branch_name|
43
+ Dir.chdir(@test_dir) do
44
+ system("git checkout -b #{branch_name}", out: File::NULL, err: File::NULL)
45
+ end
46
+ end
47
+
48
+ Then /^I should be on branch "([^"]+)"$/ do |expected_branch|
49
+ Dir.chdir(@test_dir) do
50
+ current = `git rev-parse --abbrev-ref HEAD`.chomp
51
+ expect(current).to eq(expected_branch)
52
+ end
53
+ end
54
+
55
+ Given /^I push branch "([^"]+)" to origin$/ do |branch_name|
56
+ Dir.chdir(@test_dir) do
57
+ system("git push -u origin #{branch_name}", out: File::NULL, err: File::NULL)
58
+ end
59
+ end
60
+
61
+ Then /^branch "([^"]+)" should not exist locally$/ do |branch_name|
62
+ Dir.chdir(@test_dir) do
63
+ result = system("git rev-parse --verify #{branch_name}", out: File::NULL, err: File::NULL)
64
+ expect(result).to be(false), "Expected branch #{branch_name} to not exist locally"
65
+ end
66
+ end
67
+
68
+ Then /^branch "([^"]+)" should not exist on origin$/ do |branch_name|
69
+ Dir.chdir(@test_dir) do
70
+ system("git fetch --prune origin", out: File::NULL, err: File::NULL)
71
+ result = system("git rev-parse --verify origin/#{branch_name}", out: File::NULL, err: File::NULL)
72
+ expect(result).to be(false), "Expected branch #{branch_name} to not exist on origin"
73
+ end
74
+ end
75
+
76
+ # Simulating remote changes
77
+ Given /^master has an additional commit from another source$/ do
78
+ run_ssh "cd ~/testproject && git pull origin master"
79
+ run_ssh "cd ~/testproject && echo 'remote change' > remote-change.txt"
80
+ run_ssh "cd ~/testproject && git add remote-change.txt"
81
+ run_ssh "cd ~/testproject && git commit -m 'Remote commit on master'"
82
+ run_ssh "cd ~/testproject && git push origin master"
83
+
84
+ Dir.chdir(@test_dir) do
85
+ system("git fetch origin", out: File::NULL, err: File::NULL)
86
+ end
87
+ end
88
+
89
+ Given /^master has a conflicting commit to "([^"]+)"$/ do |filename|
90
+ run_ssh "cd ~/testproject && git pull origin master"
91
+ run_ssh "cd ~/testproject && echo 'conflicting content from remote' > #{filename}"
92
+ run_ssh "cd ~/testproject && git add #{filename}"
93
+ run_ssh "cd ~/testproject && git commit -m 'Remote conflicting commit'"
94
+ run_ssh "cd ~/testproject && git push origin master"
95
+
96
+ Dir.chdir(@test_dir) do
97
+ system("git fetch origin", out: File::NULL, err: File::NULL)
98
+ end
99
+ end
100
+
101
+ # CI setup
102
+ Given /^a local CI script that passes$/ do
103
+ Dir.chdir(@test_dir) do
104
+ File.write("bin/rake", <<~'SCRIPT')
105
+ #!/bin/bash
106
+ case "$1" in
107
+ ci) echo "All tests passed!"; exit 0 ;;
108
+ esac
109
+ SCRIPT
110
+ FileUtils.chmod(0o755, "bin/rake")
111
+ end
112
+ end
113
+
114
+ Given /^a local CI script that fails with "([^"]+)"$/ do |error_message|
115
+ Dir.chdir(@test_dir) do
116
+ File.write("bin/rake", <<~SCRIPT)
117
+ #!/bin/bash
118
+ case "$1" in
119
+ ci) echo "#{error_message}"; exit 1 ;;
120
+ esac
121
+ SCRIPT
122
+ FileUtils.chmod(0o755, "bin/rake")
123
+ end
124
+ end
125
+
126
+ Given /^I switch to branch "([^"]+)"$/ do |branch_name|
127
+ Dir.chdir(@test_dir) do
128
+ system("git checkout #{branch_name}", out: File::NULL, err: File::NULL)
129
+ end
130
+ end
131
+
132
+ # Output negation
133
+ Then /^the output should not contain "([^"]+)"$/ do |unexpected|
134
+ expect(@stdout).not_to include(unexpected)
135
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ root = File.expand_path("../../..", __FILE__)
3
+
4
+ require "simplecov"
5
+ SimpleCov.root(root)
6
+ SimpleCov.start do
7
+ command_name "Cucumber (subprocess #{$$})"
8
+ track_files "lib/**/*.rb"
9
+ add_filter "spec/"
10
+ add_filter "features/"
11
+ coverage_dir "#{root}/coverage"
12
+ end
13
+
14
+ $LOAD_PATH.unshift("#{root}/lib")
15
+ require "bard/cli"
16
+ Bard::CLI.start ARGV
@@ -1,8 +1,17 @@
1
+ require "simplecov"
2
+ SimpleCov.start do
3
+ command_name "Cucumber"
4
+ track_files "lib/**/*.rb"
5
+ add_filter "spec/"
6
+ add_filter "features/"
7
+ end
8
+
1
9
  $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
10
+ require "bard"
2
11
  require 'rspec/expectations'
3
12
  require 'fileutils'
4
13
 
5
- ENV["PATH"] = "#{File.dirname(File.expand_path(__FILE__))}/../../bin:#{ENV['PATH']}"
14
+ ENV["PATH"] = "#{File.dirname(File.expand_path(__FILE__))}:#{ENV['PATH']}"
6
15
  ENV["GIT_DIR"] = nil
7
16
  ENV["GIT_WORK_TREE"] = nil
8
17
  ENV["GIT_INDEX_FILE"] = nil
@@ -184,7 +184,8 @@ SCRIPT
184
184
 
185
185
  def run_bard(command)
186
186
  Dir.chdir(@test_dir) do
187
- @stdout, @status = Open3.capture2e("bard #{command}")
187
+ bard_coverage = File.join(ROOT, "features/support/bard-coverage")
188
+ @stdout, @status = Open3.capture2e("#{bard_coverage} #{command}")
188
189
  end
189
190
  end
190
191
 
@@ -5,9 +5,8 @@ require "bard/ci/runner"
5
5
  module Bard
6
6
  class CI
7
7
  class GithubActions < Runner
8
-
9
8
  def exists?
10
- true
9
+ File.exist?(".github/workflows/ci.yml")
11
10
  end
12
11
 
13
12
  def console