jive 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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