retest 0.9.0 → 1.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: 8df33036507fe29259ef99ac9fa574fdece9af4e69911f21125a1c4bbad7778c
4
- data.tar.gz: a4bb2606b7373fb304638125be08d94c79a5dfb5e324cbf433848730cf08abe6
3
+ metadata.gz: 13ce5e74ba4682f3777259a6565c585271dd7db5f6d753c4e5d6836f5c457634
4
+ data.tar.gz: bfc62c5fd481982435b3ee8e372839b7678e489d8123bbcd629c5ba56c2b7012
5
5
  SHA512:
6
- metadata.gz: ba3f7823d9789965dbd44d92ac40aeb1f6d3dd9f35f6e634f317949adf72ba672abb231f4603acfe1da2c766d3158da81ca1c538868ab8be8955bfdf443651b0
7
- data.tar.gz: 74f1a43fc0b23d48bd9a7cdd53c8a57206cbf9cc3546f1a6d2d0609d7f837744f1f74162ced9f57661f6008237b039f32ba2454289d839314ecfae5bc4ce011f
6
+ metadata.gz: ef3ee2efb84b012c5b6ba340d81e578ec512960e7fc28516abbc23689c8ad43f3c3a5ecd1855d51df1bcee5a426fdd92aef3f460a65fbb7c39d35d83ad08c735
7
+ data.tar.gz: e5af1bbe78c6bfa347088fc0ec3c8e985a1dbad5393f47640b7885cf4a0bbdd5cbc8c8922f7b189794027af4e7091dc36fd81693e5d785cf11e330fd2ea78dc0
@@ -44,8 +44,10 @@ jobs:
44
44
  matrix:
45
45
  repo:
46
46
  - ruby-app
47
- - rails-app
47
+ - ruby-bare
48
+ - git-ruby
48
49
  - hanami-app
50
+ - rails-app
49
51
  - rspec-rails
50
52
  - rspec-ruby
51
53
  steps:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- retest (0.9.0)
4
+ retest (1.2.0)
5
5
  listen (~> 3.2)
6
6
  string-similarity (~> 2.1)
7
7
  tty-option (~> 0.1)
@@ -11,12 +11,12 @@ GEM
11
11
  specs:
12
12
  byebug (11.1.3)
13
13
  ffi (1.15.0)
14
- listen (3.4.1)
14
+ listen (3.5.0)
15
15
  rb-fsevent (~> 0.10, >= 0.10.3)
16
16
  rb-inotify (~> 0.9, >= 0.9.10)
17
17
  minitest (5.14.1)
18
18
  rake (12.3.3)
19
- rb-fsevent (0.10.4)
19
+ rb-fsevent (0.11.0)
20
20
  rb-inotify (0.10.1)
21
21
  ffi (~> 1.0)
22
22
  string-similarity (2.1.0)
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/retest.svg)](https://badge.fury.io/rb/retest)
2
+
1
3
  # Retest
2
4
 
3
5
  Retest is a small command-line tool to help you refactor code by watching a file change and running its matching spec. Designed to be dev-centric and project independent, it can be used on the fly. No Gemfile updates, no commits to a repo or configuration files required to start refactoring. Works with every Ruby projects (at least that is the end goal)
@@ -13,6 +15,7 @@ Install it on your machine without adding it on a Gemfile:
13
15
  $ gem install retest
14
16
 
15
17
  ## Usage
18
+ ### Refactoring
16
19
 
17
20
  Launch `retest` in your terminal after accessing your ruby repository.
18
21
 
@@ -28,11 +31,10 @@ Few shortcut flags exist to avoid writing the full test command.
28
31
  $ retest --rails
29
32
  $ retest --rake --all
30
33
 
31
- Finally let retest automatically find your ruby setup and run the appropriate command using:
34
+ Or let retest find your ruby setup and run the appropriate command using:
32
35
 
33
36
  $ retest
34
- $ retest --auto
35
- $ retest --auto --all
37
+ $ retest --all
36
38
 
37
39
  The gem works as follows:
38
40
 
@@ -41,7 +43,15 @@ The gem works as follows:
41
43
  * When multiple matching test files are found, retest asks you to confirm the file and save the answer.
42
44
  * When a test file is not found, retest runs the last run command or throw a 404.
43
45
 
44
- See more example with `retest -h`
46
+ ### Diff Check
47
+
48
+ You can diff a branch and test all the relevant test files before pushing your branch and trigger the full CI suite.
49
+
50
+ $ retest --diff origin/main
51
+
52
+ ### Help
53
+
54
+ See more examples with `retest -h`
45
55
 
46
56
  ```
47
57
  Usage: retest [OPTIONS] [COMMAND]
@@ -82,6 +92,10 @@ Examples:
82
92
  Let retest identify which command to run for all tests
83
93
  $ retest --all
84
94
  $ retest --auto --all
95
+
96
+ Run a sanity check on changed files from a branch
97
+ $ retest --diff origin/main --rails
98
+ $ retest --diff main --auto
85
99
  ```
86
100
 
87
101
  ## Why?
data/bin/debug CHANGED
@@ -13,6 +13,14 @@ if options.help?
13
13
  return
14
14
  end
15
15
 
16
- Retest.start(options.command) # not blocking
16
+ program = Retest::Program.new(
17
+ repository: Retest::Repository.new(files: Retest::VersionControl.files),
18
+ runner: Retest::Runner.for(Retest::Command.for_options(options))
19
+ )
17
20
 
18
- sleep
21
+ if options.params[:diff]
22
+ program.diff(options.params[:diff])
23
+ else
24
+ program.start # not blocking
25
+ sleep
26
+ end
data/bin/test/git-ruby ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+
3
+ bundle install
4
+ bundle exec rake build
5
+ ls -t pkg | head -n1 | xargs -I {} mv pkg/{} features/git-ruby/retest.gem
6
+ docker-compose -f features/git-ruby/docker-compose.yml up --build --exit-code-from retest
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+
3
+ bundle install
4
+ bundle exec rake build
5
+ ls -t pkg | head -n1 | xargs -I {} mv pkg/{} features/ruby-bare/retest.gem
6
+ docker-compose -f features/ruby-bare/docker-compose.yml up --build --exit-code-from retest
data/exe/retest CHANGED
@@ -11,6 +11,14 @@ if options.help?
11
11
  return
12
12
  end
13
13
 
14
- Retest.start(options.command) # not blocking
14
+ program = Retest::Program.new(
15
+ repository: Retest::Repository.new(files: Retest::VersionControl.files),
16
+ runner: Retest::Runner.for(Retest::Command.for_options(options))
17
+ )
15
18
 
16
- sleep
19
+ if options.params[:diff]
20
+ program.diff(options.params[:diff])
21
+ else
22
+ program.start # not blocking
23
+ sleep
24
+ end
data/lib/retest.rb CHANGED
@@ -8,23 +8,39 @@ require "retest/test_options"
8
8
  require "retest/options"
9
9
  require "retest/version_control"
10
10
  require "retest/setup"
11
+ require "retest/command"
12
+ require "retest/file_system"
11
13
 
12
14
  module Retest
13
15
  class Error < StandardError; end
14
16
 
15
- class << self
16
- def start(command)
17
+ class Program
18
+ attr_accessor :runner, :repository
19
+ def initialize(runner: nil, repository: nil)
20
+ @runner = runner
21
+ @repository = repository
22
+ end
23
+
24
+ def start
17
25
  puts "Launching Retest..."
26
+ build.start
27
+ puts "Ready to refactor! You can make file changes now"
28
+ end
18
29
 
19
- build(
20
- runner: Runner.for(command),
21
- repository: Repository.new(files: VersionControl.files)
22
- ).start
30
+ def diff(branch)
31
+ raise "Git not installed" unless VersionControl::Git.installed?
32
+ test_files = repository.find_tests VersionControl::Git.diff_files(branch)
23
33
 
24
- puts "Ready to refactor! You can make file changes now"
34
+ puts "Tests found:"
35
+ test_files.each { |test_file| puts " - #{test_file}" }
36
+
37
+ puts "Running tests..."
38
+ test_files.each { |test_file| runner.run test_file }
25
39
  end
26
40
 
27
- def build(runner:, repository:)
41
+ private
42
+
43
+ def build
28
44
  Listen.to('.', only: /\.rb$/, relative: true) do |modified, added, removed|
29
45
  begin
30
46
  repository.add(added)
@@ -32,11 +48,15 @@ module Retest
32
48
  runner.remove(removed)
33
49
  system('clear 2>/dev/null') || system('cls 2>/dev/null')
34
50
 
35
- runner.run repository.find_test (modified + added).first
51
+ runner.run test_file_to_run(modified + added)
36
52
  rescue => e
37
53
  puts "Something went wrong: #{e.message}"
38
54
  end
39
55
  end
40
56
  end
57
+
58
+ def test_file_to_run(changed_files)
59
+ repository.find_test changed_files.first if runner.matching?
60
+ end
41
61
  end
42
62
  end
@@ -0,0 +1,77 @@
1
+ require_relative 'command/rails'
2
+ require_relative 'command/rake'
3
+ require_relative 'command/rspec'
4
+ require_relative 'command/ruby'
5
+
6
+ module Retest
7
+ class Command
8
+ extend Forwardable
9
+
10
+ def self.for_options(options)
11
+ new(options: options).command
12
+ end
13
+
14
+ def self.for_setup(setup)
15
+ new(setup: setup).command
16
+ end
17
+
18
+ def_delegator :setup, :type
19
+ def_delegators :options, :params, :full_suite?, :auto?
20
+
21
+ attr_accessor :options, :setup
22
+ def initialize(options: Options.new, setup: Setup.new, output_stream: STDOUT)
23
+ @options = options
24
+ @setup = setup
25
+ @output_stream = output_stream
26
+ end
27
+
28
+ def command
29
+ return default_command if auto?
30
+ options_command || default_command
31
+ end
32
+
33
+ def options_command
34
+ return params[:command] if params[:command]
35
+
36
+ if params[:rspec] then rspec_command
37
+ elsif params[:rails] then rails_command
38
+ elsif params[:ruby] then ruby_command
39
+ elsif params[:rake] then rake_command
40
+ else
41
+ end
42
+ end
43
+
44
+ def setup_command
45
+ case type
46
+ when :rake then rake_command
47
+ when :rspec then rspec_command
48
+ when :rails then rails_command
49
+ when :ruby then ruby_command
50
+ else ruby_command
51
+ end
52
+ end
53
+
54
+ def default_command
55
+ @output_stream.puts "Setup identified: [#{type.upcase}]. Using command: '#{setup_command}'"
56
+ setup_command
57
+ end
58
+
59
+ private
60
+
61
+ def rspec_command
62
+ Rspec.command(all: full_suite?)
63
+ end
64
+
65
+ def rails_command
66
+ Rails.command(all: full_suite?)
67
+ end
68
+
69
+ def rake_command
70
+ Rake.command(all: full_suite?)
71
+ end
72
+
73
+ def ruby_command
74
+ Ruby.command(all: full_suite?)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,22 @@
1
+ module Retest
2
+ class Command
3
+ Rails = Struct.new(:all, :file_system) do
4
+ def self.command(all:, file_system: FileSystem)
5
+ new(all, file_system).command
6
+ end
7
+
8
+ def command
9
+ return "#{root_command} <test>" unless all
10
+ root_command
11
+ end
12
+
13
+ private
14
+
15
+ def root_command
16
+ return 'bin/rails test' if file_system.exist? 'bin/rails'
17
+
18
+ 'bundle exec rails test'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module Retest
2
+ class Command
3
+ Rake = Struct.new(:all, :file_system) do
4
+ def self.command(all:, file_system: FileSystem)
5
+ new(all, file_system).command
6
+ end
7
+
8
+ def command
9
+ return "#{root_command} TEST=<test>" unless all
10
+ root_command
11
+ end
12
+
13
+ private
14
+
15
+ def root_command
16
+ return 'bin/rake test' if file_system.exist? 'bin/rake'
17
+
18
+ 'bundle exec rake test'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module Retest
2
+ class Command
3
+ Rspec = Struct.new(:all, :file_system) do
4
+ def self.command(all:, file_system: FileSystem)
5
+ new(all, file_system).command
6
+ end
7
+
8
+ def command
9
+ return "#{root_command} <test>" unless all
10
+ root_command
11
+ end
12
+
13
+ private
14
+
15
+ def root_command
16
+ return 'bin/rspec' if file_system.exist? 'bin/rspec'
17
+
18
+ 'bundle exec rspec'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module Retest
2
+ class Command
3
+ module Ruby
4
+ module_function
5
+
6
+ def command(all: false, file_system: FileSystem)
7
+ if file_system.exist? 'Gemfile.lock'
8
+ 'bundle exec ruby <test>'
9
+ else
10
+ 'ruby <test>'
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module Retest
2
+ module FileSystem
3
+ module_function
4
+
5
+ def exist?(value)
6
+ File.exist? value
7
+ end
8
+ end
9
+ end
@@ -48,6 +48,12 @@ module Retest
48
48
  $ retest --all
49
49
  $ retest --auto --all
50
50
  EOS
51
+
52
+ example <<~EOS
53
+ Run a sanity check on changed files from a branch
54
+ $ retest --diff origin/main --rails
55
+ $ retest --diff main --auto
56
+ EOS
51
57
  end
52
58
 
53
59
  argument :command do
@@ -58,6 +64,11 @@ module Retest
58
64
  EOS
59
65
  end
60
66
 
67
+ option :diff do
68
+ desc "Pipes all matching tests from diffed branch to test command"
69
+ long "--diff=git-branch"
70
+ end
71
+
61
72
  flag :all do
62
73
  long "--all"
63
74
  desc "Run all the specs of a specificied ruby setup"
@@ -100,22 +111,8 @@ module Retest
100
111
  new(args).command
101
112
  end
102
113
 
103
- def initialize(args = [], output_stream: STDOUT, setup: Setup)
114
+ def initialize(args = [])
104
115
  self.args = args
105
- @output_stream = output_stream
106
- @setup = setup
107
- end
108
-
109
- def command
110
- return params[:command] if params[:command]
111
-
112
- if params[:rspec] then rspec_command
113
- elsif params[:rake] then rake_command
114
- elsif params[:rails] then rails_command
115
- elsif params[:ruby] then ruby_command
116
- elsif params[:auto] then default_command
117
- else default_command
118
- end
119
116
  end
120
117
 
121
118
  def args=(args)
@@ -127,45 +124,19 @@ module Retest
127
124
  params[:help]
128
125
  end
129
126
 
130
- private
131
-
132
127
  def full_suite?
133
128
  params[:all]
134
129
  end
135
130
 
136
- def default_command
137
- choose_command @setup.type, command_for(@setup.type)
131
+ def auto?
132
+ return true if no_options_passed?
133
+ params[:auto]
138
134
  end
139
135
 
140
- def command_for(type)
141
- case type
142
- when :rspec then rspec_command
143
- when :rails then rails_command
144
- when :rake then rake_command
145
- when :ruby then ruby_command
146
- else ruby_command
147
- end
148
- end
149
-
150
- def choose_command(type, command)
151
- @output_stream.puts "Setup identified: [#{type.upcase}]. Using command: '#{command}'"
152
- command
153
- end
154
-
155
- def rspec_command
156
- full_suite? ? ALL_RSPEC_COMMAND : RSPEC_COMMAND
157
- end
158
-
159
- def rails_command
160
- full_suite? ? ALL_RAILS_COMMAND : RAILS_COMMAND
161
- end
162
-
163
- def rake_command
164
- full_suite? ? ALL_RAKE_COMMAND : RAKE_COMMAND
165
- end
136
+ private
166
137
 
167
- def ruby_command
168
- RUBY_COMMAND
138
+ def no_options_passed?
139
+ params.to_h.values.compact.uniq == [false]
169
140
  end
170
141
  end
171
142
  end
@@ -13,7 +13,17 @@ module Retest
13
13
  return unless path
14
14
  return if path.empty?
15
15
 
16
- cache[path] ||= select_from TestOptions.for(path, files: files)
16
+ @path = path
17
+ cache[@path] ||= select_from TestOptions.for(@path, files: files)
18
+ end
19
+
20
+ def find_tests(paths)
21
+ paths
22
+ .select { |path| Regexp.new("\.rb$") =~ path }
23
+ .map { |path| find_test(path) }
24
+ .compact
25
+ .uniq
26
+ .sort
17
27
  end
18
28
 
19
29
  def add(added)
@@ -47,7 +57,7 @@ module Retest
47
57
 
48
58
  def ask_question(tests)
49
59
  output_stream.puts <<~QUESTION
50
- We found few tests matching:
60
+ We found few tests matching: #{@path}
51
61
  #{list_options(tests)}
52
62
 
53
63
  Which file do you want to use?
data/lib/retest/runner.rb CHANGED
@@ -52,6 +52,14 @@ module Retest
52
52
  end
53
53
  end
54
54
 
55
+ def unmatching?
56
+ !matching?
57
+ end
58
+
59
+ def matching?
60
+ true
61
+ end
62
+
55
63
  private
56
64
 
57
65
  def purge_cache
@@ -65,6 +73,14 @@ module Retest
65
73
  end
66
74
 
67
75
  def remove(_ = nil); end
76
+
77
+ def unmatching?
78
+ !matching?
79
+ end
80
+
81
+ def matching?
82
+ false
83
+ end
68
84
  end
69
85
  end
70
86
  end
data/lib/retest/setup.rb CHANGED
@@ -6,7 +6,7 @@ module Retest
6
6
 
7
7
  def type
8
8
  @type ||= begin
9
- return :ruby unless has_gemfile?
9
+ return :ruby unless has_lock_file?
10
10
 
11
11
  if rspec?
12
12
  :rspec
@@ -22,8 +22,8 @@ module Retest
22
22
 
23
23
  private
24
24
 
25
- def has_gemfile?
26
- File.exist? 'Gemfile'
25
+ def has_lock_file?
26
+ File.exist? 'Gemfile.lock'
27
27
  end
28
28
 
29
29
  def rspec?
@@ -31,7 +31,7 @@ module Retest
31
31
  end
32
32
 
33
33
  def rails?
34
- File.exist? 'bin/rails'
34
+ has_gem? 'rails'
35
35
  end
36
36
 
37
37
  def rake?
@@ -39,7 +39,7 @@ module Retest
39
39
  end
40
40
 
41
41
  def has_gem?(gem_name)
42
- !`cat Gemfile | grep #{gem_name}`.empty?
42
+ !`cat Gemfile.lock | grep #{gem_name}`.empty?
43
43
  end
44
44
  end
45
45
  end
@@ -1,3 +1,3 @@
1
1
  module Retest
2
- VERSION = "0.9.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -1,3 +1,6 @@
1
+ require_relative 'version_control/git'
2
+ require_relative 'version_control/no_version_control'
3
+
1
4
  module Retest
2
5
  class VersionControl
3
6
  def self.files
@@ -6,43 +9,5 @@ module Retest
6
9
 
7
10
  def name; end
8
11
  alias :to_s :name
9
-
10
- class NoVersionControl
11
- def self.installed?
12
- true
13
- end
14
-
15
- def name
16
- 'default'
17
- end
18
-
19
- def files
20
- Dir.glob('**/*') - Dir.glob('{tmp,node_modules}/**/*')
21
- end
22
- end
23
-
24
- class Git
25
- def self.installed?
26
- system "git -C . rev-parse 2>/dev/null"
27
- end
28
-
29
- def name
30
- 'git'
31
- end
32
-
33
- def files
34
- (untracked_files + tracked_files).sort
35
- end
36
-
37
- private
38
-
39
- def untracked_files
40
- `git ls-files --other --exclude-standard -z`.split("\x0")
41
- end
42
-
43
- def tracked_files
44
- `git ls-files -z`.split("\x0")
45
- end
46
- end
47
12
  end
48
13
  end
@@ -0,0 +1,33 @@
1
+ class Retest::VersionControl
2
+ class Git
3
+ def self.installed?
4
+ system "git -C . rev-parse 2>/dev/null"
5
+ end
6
+
7
+ def self.diff_files(branch)
8
+ new.diff_files(branch)
9
+ end
10
+
11
+ def name
12
+ 'git'
13
+ end
14
+
15
+ def files
16
+ (untracked_files + tracked_files).sort
17
+ end
18
+
19
+ def diff_files(branch)
20
+ `git diff #{branch} --name-only --diff-filter=ACMRT -z`.split("\x0")
21
+ end
22
+
23
+ private
24
+
25
+ def untracked_files
26
+ `git ls-files --other --exclude-standard -z`.split("\x0")
27
+ end
28
+
29
+ def tracked_files
30
+ `git ls-files -z`.split("\x0")
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ class Retest::VersionControl
2
+ class NoVersionControl
3
+ def self.installed?
4
+ true
5
+ end
6
+
7
+ def name
8
+ 'default'
9
+ end
10
+
11
+ def files
12
+ Dir.glob('**/*') - Dir.glob('{tmp,node_modules}/**/*')
13
+ end
14
+ end
15
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: retest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre Barret
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-16 00:00:00.000000000 Z
11
+ date: 2021-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: string-similarity
@@ -72,13 +72,21 @@ files:
72
72
  - bin/console
73
73
  - bin/debug
74
74
  - bin/setup
75
+ - bin/test/git-ruby
75
76
  - bin/test/hanami-app
76
77
  - bin/test/rails-app
77
78
  - bin/test/rspec-rails
78
79
  - bin/test/rspec-ruby
79
80
  - bin/test/ruby-app
81
+ - bin/test/ruby-bare
80
82
  - exe/retest
81
83
  - lib/retest.rb
84
+ - lib/retest/command.rb
85
+ - lib/retest/command/rails.rb
86
+ - lib/retest/command/rake.rb
87
+ - lib/retest/command/rspec.rb
88
+ - lib/retest/command/ruby.rb
89
+ - lib/retest/file_system.rb
82
90
  - lib/retest/options.rb
83
91
  - lib/retest/repository.rb
84
92
  - lib/retest/runner.rb
@@ -86,6 +94,8 @@ files:
86
94
  - lib/retest/test_options.rb
87
95
  - lib/retest/version.rb
88
96
  - lib/retest/version_control.rb
97
+ - lib/retest/version_control/git.rb
98
+ - lib/retest/version_control/no_version_control.rb
89
99
  - retest.gemspec
90
100
  homepage: https://github.com/AlexB52/retest
91
101
  licenses: