jive 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6281244f3600328a55a9a4e197933273d53201e499c012d0f920a93f7ee1e4e3
4
- data.tar.gz: 59651c78078fbb18dbcf078648fd0f661ce51386e64c93b885cd16d9d04a8bc6
3
+ metadata.gz: 1e99fd45b1d45c356ac45300a941833cf34dbcfc3995f935234c9c08f06dba74
4
+ data.tar.gz: a68176da0fe8547d201ddbc573fb6d49e0773ca983fa312e4b6dc313c9a4157b
5
5
  SHA512:
6
- metadata.gz: e0b953652bf6867534fff58d96996d652b11087f8830660d3b0ba1466cf3f950076e95168237087173638f5bd701ea46be21b235f3cef14167b16c2226168f55
7
- data.tar.gz: 52446f569a68c88aa2a75685b32fe96d2532f3074a183ebc26ae2ceb0b7b17fec17da412f10208e938b743b4888a5d40f4f5c60dfd8c5c85207c8be4d6580cd8
6
+ metadata.gz: c41233baa8f43d3a9277435661eb9ccb13e874d5a5ed338f4de60cd095942c6b8ad3f13f74be5a34819d5efea3b8fd090c68369a6f39bacb8f2f10edf313e1c6
7
+ data.tar.gz: cafe522151627f9e4649391e620cb4419970454a04cd62d2b31d329699c7d3cb0bb73dfb2b1faaa9b8ffbec43ee89750b06dc10b75723bf343609bbf1751a2be
@@ -0,0 +1,28 @@
1
+ name: ci
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ branches: [main]
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ ruby-version: ['2.5', '2.6', '2.7', '3.0']
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby-version }}
18
+ bundler-cache: true
19
+ - run: ./bin/test
20
+ style:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v2
24
+ - uses: ruby/setup-ruby@v1
25
+ with:
26
+ ruby-version: '3'
27
+ bundler-cache: true
28
+ - run: ./bin/style
data/.gitignore CHANGED
@@ -4,8 +4,4 @@
4
4
  /coverage/
5
5
  /doc/
6
6
  /pkg/
7
- /spec/reports/
8
7
  /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
data/.rubocop.yml ADDED
@@ -0,0 +1,37 @@
1
+ require:
2
+ - rubocop-minitest
3
+ - rubocop-rake
4
+
5
+ AllCops:
6
+ NewCops: enable
7
+ TargetRubyVersion: 2.5
8
+
9
+ Layout/LineLength:
10
+ Max: 120
11
+
12
+ Layout/EndOfLine:
13
+ EnforcedStyle: lf
14
+
15
+ Layout/FirstArrayElementIndentation:
16
+ EnforcedStyle: consistent
17
+
18
+ Metrics/AbcSize:
19
+ Exclude:
20
+ - lib/jive/batch_runner.rb
21
+ - lib/jive/popen.rb
22
+
23
+ Metrics/MethodLength:
24
+ Exclude:
25
+ - lib/jive/batch_runner.rb
26
+ - lib/jive/popen.rb
27
+
28
+ Style/Documentation:
29
+ Enabled: false
30
+
31
+ Style/StringLiterals:
32
+ Enabled: true
33
+ EnforcedStyle: double_quotes
34
+
35
+ Style/StringLiteralsInInterpolation:
36
+ Enabled: true
37
+ EnforcedStyle: double_quotes
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  # Specify your gem's dependencies in jive.gemspec
data/Gemfile.lock CHANGED
@@ -1,35 +1,50 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jive (0.1.0)
4
+ jive (0.2.0)
5
+ thor (~> 1.1)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
9
- diff-lcs (1.3)
10
- rake (10.5.0)
11
- rspec (3.9.0)
12
- rspec-core (~> 3.9.0)
13
- rspec-expectations (~> 3.9.0)
14
- rspec-mocks (~> 3.9.0)
15
- rspec-core (3.9.0)
16
- rspec-support (~> 3.9.0)
17
- rspec-expectations (3.9.0)
18
- diff-lcs (>= 1.2.0, < 2.0)
19
- rspec-support (~> 3.9.0)
20
- rspec-mocks (3.9.0)
21
- diff-lcs (>= 1.2.0, < 2.0)
22
- rspec-support (~> 3.9.0)
23
- rspec-support (3.9.0)
10
+ ast (2.4.2)
11
+ minitest (5.14.3)
12
+ parallel (1.20.1)
13
+ parser (3.0.0.0)
14
+ ast (~> 2.4.1)
15
+ rainbow (3.0.0)
16
+ rake (13.0.3)
17
+ regexp_parser (2.0.3)
18
+ rexml (3.2.4)
19
+ rubocop (1.9.1)
20
+ parallel (~> 1.10)
21
+ parser (>= 3.0.0.0)
22
+ rainbow (>= 2.2.2, < 4.0)
23
+ regexp_parser (>= 1.8, < 3.0)
24
+ rexml
25
+ rubocop-ast (>= 1.2.0, < 2.0)
26
+ ruby-progressbar (~> 1.7)
27
+ unicode-display_width (>= 1.4.0, < 3.0)
28
+ rubocop-ast (1.4.1)
29
+ parser (>= 2.7.1.5)
30
+ rubocop-minitest (0.10.3)
31
+ rubocop (>= 0.87, < 2.0)
32
+ rubocop-rake (0.5.1)
33
+ rubocop
34
+ ruby-progressbar (1.11.0)
35
+ thor (1.1.0)
36
+ unicode-display_width (2.0.0)
24
37
 
25
38
  PLATFORMS
26
39
  ruby
27
40
 
28
41
  DEPENDENCIES
29
- bundler (~> 2.0)
30
42
  jive!
31
- rake (~> 10.0)
32
- rspec (~> 3.0)
43
+ minitest (~> 5.0)
44
+ rake (~> 13.0)
45
+ rubocop (~> 1.7)
46
+ rubocop-minitest (~> 0.1)
47
+ rubocop-rake (~> 0.5)
33
48
 
34
49
  BUNDLED WITH
35
- 2.0.2
50
+ 2.2.8
data/README.md CHANGED
@@ -1,38 +1,34 @@
1
1
  # Jive
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/jive`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Build Status](https://github.com/xlgmokha/jive/workflows/ci/badge.svg)](https://github.com/xlgmokha/jive/actions)
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ Hi!
6
6
 
7
7
  ## Installation
8
8
 
9
- Add this line to your application's Gemfile:
10
-
11
- ```ruby
12
- gem 'jive'
13
- ```
14
-
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
20
-
21
9
  $ gem install jive
22
10
 
23
11
  ## Usage
24
12
 
25
- TODO: Write usage instructions here
13
+ $ jive --help
14
+
26
15
 
27
16
  ## Development
28
17
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
18
+ After checking out the repo, run `bin/setup` to install dependencies.
19
+ Then, run `./bin/test` to run the tests.
20
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
21
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
22
+ To install this gem onto your local machine, run `bundle exec rake install`.
23
+ To release a new version, update the version number in `version.rb`,
24
+ and then run `bundle exec rake release`,
25
+ which will create a git tag for the version,
26
+ push git commits and tags, and push the `.gem`
27
+ file to [rubygems.org](https://rubygems.org).
32
28
 
33
29
  ## Contributing
34
30
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/jive.
31
+ Bug reports and pull requests are welcome on GitHub at https://github.com/xlgmokha/jive.
36
32
 
37
33
  ## License
38
34
 
data/Rakefile CHANGED
@@ -1,6 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
4
+ require "rake/testtask"
5
+ require "rubocop/rake_task"
3
6
 
4
- RSpec::Core::RakeTask.new(:spec)
7
+ Rake::TestTask.new(:test) do |task|
8
+ task.libs << "lib"
9
+ task.libs << "test"
10
+ task.test_files = FileList["test/**/*_test.rb"]
11
+ end
12
+ RuboCop::RakeTask.new
5
13
 
6
- task :default => :spec
14
+ task default: %i[test rubocop]
data/bin/console CHANGED
@@ -1,14 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "jive"
5
6
 
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
7
  require "irb"
14
8
  IRB.start(__FILE__)
data/bin/run ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ bundle exec ./exe/jive "$@"
data/bin/setup CHANGED
@@ -1,8 +1,6 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
1
+ #!/bin/sh
2
+ set -e
5
3
 
6
- bundle install
4
+ cd "$(dirname "$0")/.."
7
5
 
8
- # Do any other automated setup that you need to do here
6
+ bundle install
data/bin/shipit ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ bundle exec rake release
data/bin/style ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ cd "$(dirname "$0")/.."
5
+
6
+ bundle exec rubocop "$@"
data/bin/test CHANGED
@@ -1,7 +1,12 @@
1
- #!/usr/bin/env ruby
1
+ #!/bin/sh
2
+ set -e
2
3
 
3
- $LOAD_PATH.unshift(File.expand_path(File.join(__dir__, '../lib')))
4
+ cd "$(dirname "$0")/.."
4
5
 
5
- require 'jive'
6
+ export RUBYOPT="-Ilib:test"
6
7
 
7
- exit Jive.run([%w[bundle exec rspec]])
8
+ if [ $# -gt 0 ]; then
9
+ bundle exec ruby "$@"
10
+ else
11
+ bundle exec ruby test/**/*_test.rb
12
+ fi
data/exe/jive CHANGED
@@ -1,3 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "jive"
4
+ require "jive/cli"
5
+
6
+ ::Jive::Cli::App.start(ARGV)
data/jive.gemspec CHANGED
@@ -1,32 +1,41 @@
1
- lib = File.expand_path("lib", __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "jive/version"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/jive/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "jive"
7
7
  spec.version = Jive::VERSION
8
8
  spec.authors = ["mo khan"]
9
- spec.email = ["mo.khan@gmail.com"]
9
+ spec.email = ["mo@mokhan.ca"]
10
10
 
11
- spec.summary = %q{The art just comes.}
12
- spec.description = %q{The art just comes.}
13
- spec.homepage = "https://github.com/mokhan/jive"
11
+ spec.summary = "The art just comes."
12
+ spec.description = "The art just comes."
13
+ spec.homepage = "https://rubygems.org/gems/jive"
14
14
  spec.license = "MIT"
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
15
16
 
16
17
  spec.metadata["homepage_uri"] = spec.homepage
17
- spec.metadata["source_code_uri"] = "https://github.com/mokhan/jive"
18
- spec.metadata["changelog_uri"] = "https://github.com/mokhan/jive"
19
18
 
20
19
  # Specify which files should be added to the gem when it is released.
21
20
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ f.match(%r{^(test|spec|features)/})
24
+ end
24
25
  end
25
26
  spec.bindir = "exe"
26
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
27
28
  spec.require_paths = ["lib"]
29
+ spec.post_install_message = <<~MESSAGE
30
+ Include the following in your ~/.bash_profile
31
+
32
+ source #{__dir__}/jive.sh
33
+ MESSAGE
28
34
 
29
- spec.add_development_dependency "bundler", "~> 2.0"
30
- spec.add_development_dependency "rake", "~> 10.0"
31
- spec.add_development_dependency "rspec", "~> 3.0"
35
+ spec.add_dependency "thor", "~> 1.1"
36
+ spec.add_development_dependency "minitest", "~> 5.0"
37
+ spec.add_development_dependency "rake", "~> 13.0"
38
+ spec.add_development_dependency "rubocop", "~> 1.7"
39
+ spec.add_development_dependency "rubocop-minitest", "~> 0.1"
40
+ spec.add_development_dependency "rubocop-rake", "~> 0.5"
32
41
  end
data/jive.sh ADDED
@@ -0,0 +1,87 @@
1
+ #!/bin/sh
2
+ # shellcheck disable=1001,1012,2039,1090
3
+ # 1001,1012 stop complaints about '\awk' syntax to bypass aliases.
4
+ # 2039 stops complaints about array references not being POSIX.
5
+ # 1090 stops complaints about sourcing non-constant paths.
6
+
7
+ __shell="$(\ps -p $$ | \awk 'NR > 1 { sub(/^-/, "", $4); print $4 }')"
8
+ __shellname="$(basename "${__shell}")"
9
+
10
+ case "${__shellname}" in
11
+ bash)
12
+ __jive_root_dir="$(builtin cd "$(\dirname "${BASH_SOURCE[0]}")" && \pwd)"
13
+ ;;
14
+ zsh)
15
+ __jive_root_dir="$(\dirname "$0:A")"
16
+ ;;
17
+ *)
18
+ >&2 \echo "jive is not compatible with your shell (${__shell})"
19
+ \return 1
20
+ ;;
21
+ esac
22
+
23
+ __jive_exe_dir="${__jive_root_dir}/exe"
24
+ __jive_lib_dir="${__jive_root_dir}/lib"
25
+ __jive_script="${__jive_root_dir}/jive.sh"
26
+
27
+ __mtime_of_jive_script="$(\date -r "${__jive_script}" +%s)"
28
+ __jive_auto_reload() {
29
+ local current_mtime
30
+ current_mtime="$(\date -r "${__jive_script}" +%s)"
31
+
32
+ if [[ "${current_mtime}" != "${__mtime_of_jive_script}" ]]; then
33
+ echo "Reloading... ${__jive_script}"
34
+ . "${__jive_script}"
35
+ fi
36
+ }
37
+
38
+ __jive_exec() {
39
+ /usr/bin/env -S ruby -I "${__jive_lib_dir}" "${__jive_exe_dir}/jive" "$@"
40
+ }
41
+
42
+ __jive_open_pipe() {
43
+ local tmpfile
44
+ tmpfile="$(\mktemp -u)"
45
+
46
+ exec 9>"${tmpfile}" # Open the tempfile for writing on FD 9.
47
+ exec 8<"${tmpfile}" # Open the tempfile for reading on FD 8.
48
+ \rm -f "${tmpfile}" # Unlink the tempfile. (we've already opened it).
49
+ }
50
+
51
+ __jive_execute_task() {
52
+ local task=$1
53
+
54
+ case "${task}" in
55
+ cd:*)
56
+ # shellcheck disable=SC2164
57
+ cd "${task//cd:/}"
58
+ ;;
59
+ setenv:*)
60
+ export "${task//setenv:/}"
61
+ ;;
62
+ *)
63
+ echo "Woof! ${task}"
64
+ ;;
65
+ esac
66
+ }
67
+
68
+ __jive_flush_tasks() {
69
+ local task
70
+ while \read -r task; do
71
+ __jive_execute_task "${task}"
72
+ done <&8
73
+
74
+ __jive_close_pipe
75
+ }
76
+
77
+ __jive_close_pipe() {
78
+ exec 8<&- # close FD 8.
79
+ exec 9<&- # close FD 9.
80
+ }
81
+
82
+ jive() {
83
+ __jive_auto_reload
84
+ __jive_open_pipe
85
+ __jive_exec "$@"
86
+ __jive_flush_tasks
87
+ }
data/lib/jive.rb CHANGED
@@ -1,144 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "fileutils"
4
- require "jive/version"
5
4
  require "open3"
6
5
 
6
+ require "jive/batch_runner"
7
+ require "jive/popen"
8
+ require "jive/runner"
9
+ require "jive/version"
10
+
7
11
  module Jive
8
12
  class Error < StandardError; end
9
13
 
10
14
  def self.run(tasks)
11
15
  Jive::BatchRunner.new.run(tasks)
12
16
  end
13
-
14
- module Popen
15
- Result = Struct.new(:command, :stdout, :stderr, :status, :duration)
16
-
17
- def self.popen(command, path = nil, env = {}, &block)
18
- result = popen_with_detail(command, path, env, &block)
19
-
20
- ["#{result.stdout}#{result.stderr}", result.status&.exitstatus]
21
- end
22
-
23
- def self.popen_with_detail(command, path = Dir.pwd, env = {})
24
- FileUtils.mkdir_p(path) unless File.directory?(path)
25
-
26
- captured_stdout = ''
27
- captured_stderr = ''
28
- exit_status = nil
29
- start = Time.now
30
-
31
- Open3.popen3(env.merge('PWD' => path), *Array(command), { chdir: path }) do |stdin, stdout, stderr, wait_thr|
32
- out_reader = Thread.new { stdout.read }
33
- err_reader = Thread.new { stderr.read }
34
-
35
- yield(stdin) if block_given?
36
-
37
- stdin.close
38
- captured_stdout = out_reader.value
39
- captured_stderr = err_reader.value
40
- exit_status = wait_thr.value
41
- end
42
- Result.new(command, captured_stdout, captured_stderr, exit_status, Time.now - start)
43
- end
44
- end
45
-
46
- class BatchRunner
47
- attr_reader :runner, :stdout
48
-
49
- def initialize(runner: Runner.new, stdout: STDOUT)
50
- @runner = runner
51
- @stdout = stdout
52
- end
53
-
54
- def run(tasks, verbose: true)
55
- runner.run(tasks) do |command, &run|
56
- stdout.puts
57
- stdout.puts "$ #{command.join(' ')}"
58
- result = run.call
59
- stdout.print result.stdout if verbose
60
- stdout.print result.stderr if verbose
61
- stdout.puts "==> Finished in #{result.duration} seconds"
62
- stdout.puts
63
- end
64
- stdout.puts '==================================================='
65
- if runner.all_success_and_clean?
66
- stdout.puts 'Passed successfully.'
67
- return 0
68
- elsif runner.all_success?
69
- stdout.puts 'Passed successfully, but we have warnings:'
70
- stdout.puts
71
- emit_warnings
72
- return 2
73
- else
74
- stdout.puts 'Something failed:'
75
- emit_warnings
76
- emit_errors
77
- return 1
78
- end
79
- end
80
-
81
- private
82
-
83
- def emit_warnings
84
- runner.warned_results.each do |result|
85
- stdout.puts
86
- stdout.puts "**** #{result.command.join(' ')} had the following warning(s):"
87
- stdout.puts
88
- stdout.puts result.stderr
89
- stdout.puts
90
- end
91
- end
92
-
93
- def emit_errors
94
- runner.failed_results.each do |result|
95
- stdout.puts
96
- stdout.puts "**** #{result.command.join(' ')} failed with the following error(s):"
97
- stdout.puts
98
- stdout.puts result.stdout
99
- stdout.puts result.stderr
100
- stdout.puts
101
- end
102
- end
103
- end
104
-
105
- class Runner
106
- attr_reader :results
107
-
108
- def initialize
109
- @results = []
110
- end
111
-
112
- def run(commands, &block)
113
- commands.each do |command|
114
- block.call(command) do
115
- cmd_result = Popen.popen_with_detail(command)
116
- results << cmd_result
117
- cmd_result
118
- end
119
- end
120
- end
121
-
122
- def all_success_and_clean?
123
- all_success? && all_stderr_empty?
124
- end
125
-
126
- def all_success?
127
- results.all? { |result| result.status.success? }
128
- end
129
-
130
- def all_stderr_empty?
131
- results.all? { |result| result.stderr.empty? }
132
- end
133
-
134
- def failed_results
135
- results.reject { |result| result.status.success? }
136
- end
137
-
138
- def warned_results
139
- results.select do |result|
140
- result.status.success? && !result.stderr.empty?
141
- end
142
- end
143
- end
144
17
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jive
4
+ class BatchRunner
5
+ attr_reader :runner, :stdout
6
+
7
+ def initialize(runner: Runner.new, stdout: $stdout)
8
+ @runner = runner
9
+ @stdout = stdout
10
+ end
11
+
12
+ def run(tasks)
13
+ stream_output_for(runner, tasks)
14
+ stdout.puts "==================================================="
15
+ print_result_for(runner)
16
+ end
17
+
18
+ private
19
+
20
+ def stream_output_for(runner, tasks)
21
+ runner.run(tasks) do |command, &run|
22
+ stdout.puts
23
+ stdout.puts "$ #{command.join(" ")}"
24
+ result = run.call
25
+ stdout.print result.stdout
26
+ stdout.print result.stderr
27
+ stdout.puts "==> Finished in #{result.duration} seconds"
28
+ stdout.puts
29
+ end
30
+ end
31
+
32
+ def print_result_for(runner)
33
+ if runner.all_success_and_clean?
34
+ stdout.puts "Passed successfully."
35
+ 0
36
+ elsif runner.all_success?
37
+ stdout.puts "Passed successfully, but we have warnings:"
38
+ stdout.puts
39
+ emit_warnings_for(runner)
40
+ 2
41
+ else
42
+ stdout.puts "Something failed:"
43
+ emit_warnings_for(runner)
44
+ emit_errors_for(runner)
45
+ 1
46
+ end
47
+ end
48
+
49
+ def emit_warnings_for(runner)
50
+ runner.warned_results.each do |result|
51
+ stdout.puts
52
+ stdout.puts "**** #{result.command.join(" ")} had the following warning(s):"
53
+ stdout.puts
54
+ stdout.puts result.stderr
55
+ stdout.puts
56
+ end
57
+ end
58
+
59
+ def emit_errors_for(runner)
60
+ runner.failed_results.each do |result|
61
+ stdout.puts
62
+ stdout.puts "**** #{result.command.join(" ")} failed with the following error(s):"
63
+ stdout.puts
64
+ stdout.puts result.stdout
65
+ stdout.puts result.stderr
66
+ stdout.puts
67
+ end
68
+ end
69
+ end
70
+ end
data/lib/jive/cli.rb ADDED
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+ require "jive"
5
+ require "pathname"
6
+
7
+ module Jive
8
+ module Cli
9
+ class App < Thor
10
+ def self.exit_on_failure?
11
+ true
12
+ end
13
+
14
+ desc "clone <org>/<project>", "git clone to ~/src/github.com/<org>/<project>"
15
+ def clone(slug)
16
+ target_dir = Pathname.new(Dir.home).join("src/github.com/#{slug}")
17
+ run_each([
18
+ [:mkdir, "-p", target_dir.parent.to_s],
19
+ [:git, "clone", "git@github.com:#{slug}.git", target_dir]
20
+ ])
21
+ after_run([
22
+ ["cd", target_dir],
23
+ ["setenv", "JIVE_LAST_RUN=#{Time.now.to_i}"]
24
+ ])
25
+ end
26
+
27
+ private
28
+
29
+ COMMAND_MAP = {
30
+ cd: "/usr/bin/cd",
31
+ echo: "/usr/bin/echo",
32
+ git: "/usr/bin/git",
33
+ mkdir: "/usr/bin/mkdir"
34
+ }.freeze
35
+
36
+ def run_each(tasks)
37
+ tasks.each do |task|
38
+ break unless execute(task)
39
+ end
40
+ end
41
+
42
+ def execute(command, env: {})
43
+ system(env, expand(command))
44
+ end
45
+
46
+ def after_run(tasks)
47
+ finalizer_fd = 9
48
+ pipe = IO.new(finalizer_fd)
49
+ pipe.puts(tasks.map { |x| x.join(":") }.join("\n"))
50
+ end
51
+
52
+ def expand(command)
53
+ Array(command)
54
+ .flatten
55
+ .map { |x| COMMAND_MAP.fetch(x, x).to_s }
56
+ .join(" ")
57
+ end
58
+ end
59
+ end
60
+ end
data/lib/jive/popen.rb ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jive
4
+ module Popen
5
+ Result = Struct.new(:command, :stdout, :stderr, :status, :duration)
6
+
7
+ def self.popen(command, path = nil, env = {}, &block)
8
+ result = popen_with_detail(command, path, env, &block)
9
+
10
+ ["#{result.stdout}#{result.stderr}", result.status&.exitstatus]
11
+ end
12
+
13
+ def self.popen_with_detail(command, path = Dir.pwd, env = {})
14
+ FileUtils.mkdir_p(path) unless File.directory?(path)
15
+
16
+ captured_stdout = ""
17
+ captured_stderr = ""
18
+ exit_status = nil
19
+ start = Time.now
20
+
21
+ Open3.popen3(env.merge("PWD" => path), *Array(command),
22
+ { chdir: path }) do |stdin, stdout, stderr, wait_thr|
23
+ out_reader = Thread.new { stdout.read }
24
+ err_reader = Thread.new { stderr.read }
25
+
26
+ yield(stdin) if block_given?
27
+
28
+ stdin.close
29
+ captured_stdout = out_reader.value
30
+ captured_stderr = err_reader.value
31
+ exit_status = wait_thr.value
32
+ end
33
+ Result.new(command, captured_stdout, captured_stderr, exit_status,
34
+ Time.now - start)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jive
4
+ class Runner
5
+ attr_reader :results
6
+
7
+ def initialize
8
+ @results = []
9
+ end
10
+
11
+ def run(commands, &block)
12
+ commands.each do |command|
13
+ block.call(command) do
14
+ cmd_result = Popen.popen_with_detail(command)
15
+ results << cmd_result
16
+ cmd_result
17
+ end
18
+ end
19
+ end
20
+
21
+ def all_success_and_clean?
22
+ all_success? && all_stderr_empty?
23
+ end
24
+
25
+ def all_success?
26
+ results.all? { |result| result.status.success? }
27
+ end
28
+
29
+ def all_stderr_empty?
30
+ results.all? { |result| result.stderr.empty? }
31
+ end
32
+
33
+ def failed_results
34
+ results.reject { |result| result.status.success? }
35
+ end
36
+
37
+ def warned_results
38
+ results.select do |result|
39
+ result.status.success? && !result.stderr.empty?
40
+ end
41
+ end
42
+ end
43
+ end
data/lib/jive/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Jive
2
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
3
5
  end
metadata CHANGED
@@ -1,89 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mo khan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-19 00:00:00.000000000 Z
11
+ date: 2021-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: thor
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '1.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
20
34
  type: :development
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '2.0'
40
+ version: '5.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '10.0'
47
+ version: '13.0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '10.0'
54
+ version: '13.0'
41
55
  - !ruby/object:Gem::Dependency
42
- name: rspec
56
+ name: rubocop
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '3.0'
61
+ version: '1.7'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '3.0'
68
+ version: '1.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.5'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.5'
55
97
  description: The art just comes.
56
98
  email:
57
- - mo.khan@gmail.com
99
+ - mo@mokhan.ca
58
100
  executables:
59
101
  - jive
60
102
  extensions: []
61
103
  extra_rdoc_files: []
62
104
  files:
63
- - ".github/workflows/test.yml"
105
+ - ".github/workflows/ci.yml"
64
106
  - ".gitignore"
65
- - ".rspec"
66
- - ".travis.yml"
107
+ - ".rubocop.yml"
67
108
  - Gemfile
68
109
  - Gemfile.lock
69
110
  - LICENSE.txt
70
111
  - README.md
71
112
  - Rakefile
72
113
  - bin/console
114
+ - bin/run
73
115
  - bin/setup
116
+ - bin/shipit
117
+ - bin/style
74
118
  - bin/test
75
119
  - exe/jive
76
120
  - jive.gemspec
121
+ - jive.sh
77
122
  - lib/jive.rb
123
+ - lib/jive/batch_runner.rb
124
+ - lib/jive/cli.rb
125
+ - lib/jive/popen.rb
126
+ - lib/jive/runner.rb
78
127
  - lib/jive/version.rb
79
- homepage: https://github.com/mokhan/jive
128
+ homepage: https://rubygems.org/gems/jive
80
129
  licenses:
81
130
  - MIT
82
131
  metadata:
83
- homepage_uri: https://github.com/mokhan/jive
84
- source_code_uri: https://github.com/mokhan/jive
85
- changelog_uri: https://github.com/mokhan/jive
86
- post_install_message:
132
+ homepage_uri: https://rubygems.org/gems/jive
133
+ post_install_message: |
134
+ Include the following in your ~/.bash_profile
135
+
136
+ source /home/mokha/src/github.com/xlgmokha/jive/jive.sh
87
137
  rdoc_options: []
88
138
  require_paths:
89
139
  - lib
@@ -91,15 +141,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
141
  requirements:
92
142
  - - ">="
93
143
  - !ruby/object:Gem::Version
94
- version: '0'
144
+ version: 2.5.0
95
145
  required_rubygems_version: !ruby/object:Gem::Requirement
96
146
  requirements:
97
147
  - - ">="
98
148
  - !ruby/object:Gem::Version
99
149
  version: '0'
100
150
  requirements: []
101
- rubygems_version: 3.0.3
102
- signing_key:
151
+ rubygems_version: 3.2.3
152
+ signing_key:
103
153
  specification_version: 4
104
154
  summary: The art just comes.
105
155
  test_files: []
@@ -1,17 +0,0 @@
1
- name: Ruby
2
- on: [push]
3
-
4
- jobs:
5
- build:
6
- runs-on: ubuntu-latest
7
- steps:
8
- - uses: actions/checkout@v1
9
- - name: Set up Ruby 2.6
10
- uses: actions/setup-ruby@v1
11
- with:
12
- ruby-version: 2.6.x
13
- - name: Build and test with Rake
14
- run: |
15
- gem install bundler
16
- bundle install --jobs 4 --retry 3
17
- ./bin/test
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.6.4
7
- before_install: gem install bundler -v 2.0.2