sfb_scripts 1.9.0 → 2.0.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
  SHA1:
3
- metadata.gz: 498e977aaa2988859e2162edc371e32f65fbb19d
4
- data.tar.gz: 839ee5851b096005e3700d3732537163abbd7cba
3
+ metadata.gz: a4146f286959b332098dde53e71bb82ec044b97e
4
+ data.tar.gz: 2d5a529036e5af8cc65dbd45a2a96c68cea21b4e
5
5
  SHA512:
6
- metadata.gz: bd061700b515123a5038e79564173cf75f0b02a4e5c3c3bf58b7c45d3cc00335d765a2b4bf9ba019fdc68e78fcd14012cb4962086299c131e1c7542cd48bf6b9
7
- data.tar.gz: a14b0991f1764915a03ed21d76d21c819bed3a8c7e39bf5293830bbe2fdcd591b13c8e5d5bd609ef5147fbd9cb2034cab0b6f53ad3a997dcc12b1fd6c53ab52a
6
+ metadata.gz: 458eb666e7f48ed93e9b9db28e1506a1b8a793ae9f983e402866766aca856c0309ea61dba8da1f6f0dec25fb0b8db7cb714e4ec7e6aa320fa20830664637df83
7
+ data.tar.gz: d23e50573381d2a6526931af2293e27e43e95f98ab8dafdd2888ec8f64cc312510c1b959ceadbf6e369d7dc7ac167715249bd6c91eabc1e4bece917f1b928f7e
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfb_scripts
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Kinnecom
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-13 00:00:00.000000000 Z
11
+ date: 2016-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: app_up
@@ -30,45 +30,21 @@ dependencies:
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.1.0
33
+ version: 1.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.1.0
40
+ version: 1.0.0
41
41
  description: Easily update your rails app and run tests from command line
42
42
  email:
43
43
  - pete.kinnecom@gmail.com
44
44
  executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
- files:
48
- - lib/sfb_scripts/bundler/bundle_manager.rb
49
- - lib/sfb_scripts/dependency_loader.rb
50
- - lib/sfb_scripts/folder_guard.rb
51
- - lib/sfb_scripts/hook_manager.rb
52
- - lib/sfb_scripts/hooks/pre_push_hook.rb
53
- - lib/sfb_scripts/migrations/migrator.rb
54
- - lib/sfb_scripts/monkey_patches/string_extension.rb
55
- - lib/sfb_scripts/needs_manager.rb
56
- - lib/sfb_scripts/repositories/active_repo.rb
57
- - lib/sfb_scripts/repositories/lazy_repo.rb
58
- - lib/sfb_scripts/repositories/repo.rb
59
- - lib/sfb_scripts/shells/loud_shell_runner.rb
60
- - lib/sfb_scripts/shells/shell_runner.rb
61
- - lib/sfb_scripts/shells/verbose_shell_runner.rb
62
- - lib/sfb_scripts/test_running/status_checker.rb
63
- - lib/sfb_scripts/test_running/status_test_runner.rb
64
- - lib/sfb_scripts/test_running/test_case.rb
65
- - lib/sfb_scripts/test_running/test_collection.rb
66
- - lib/sfb_scripts/test_running/test_filter.rb
67
- - lib/sfb_scripts/test_running/test_finder.rb
68
- - lib/sfb_scripts/test_running/test_runner.rb
69
- - lib/sfb_scripts/tester.rb
70
- - lib/sfb_scripts/upper.rb
71
- - lib/sfb_scripts/version.rb
47
+ files: []
72
48
  homepage: http://github.com/petekinnecom/sfb_scripts/
73
49
  licenses:
74
50
  - MIT
@@ -89,9 +65,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
65
  version: '0'
90
66
  requirements: []
91
67
  rubyforge_project:
92
- rubygems_version: 2.4.3
68
+ rubygems_version: 2.4.5.1
93
69
  signing_key:
94
70
  specification_version: 4
95
71
  summary: Easily update your rails app and run tests from command line
96
72
  test_files: []
97
- has_rdoc:
@@ -1,59 +0,0 @@
1
- class BundleManager
2
- attr_accessor :shell, :repo, :queue, :folder_guard
3
-
4
- def initialize(repo: raise, shell: raise, queue: raise, folder_guard: folder_guard)
5
- @shell = shell
6
- @repo = repo
7
- @queue = queue
8
- @folder_guard = folder_guard
9
- end
10
-
11
- def bundle_where_necessary
12
- shell.notify "\nBundling:"
13
- directories_to_bundle.each do |dir|
14
- queue.enqueue_b do
15
- bundle(dir)
16
- end
17
- end
18
- queue.join
19
- end
20
-
21
- private
22
-
23
- def bundle(gemfile_directory)
24
- begin
25
- shell.run "bundle install --local", dir: gemfile_directory
26
- rescue ShellRunner::CommandFailureError
27
- puts 'trying without --local'
28
- shell.run "bundle install", dir: gemfile_directory
29
- end
30
- end
31
-
32
- def directories_to_bundle
33
- changed_gemfile_locks.map do |gemfile_lock|
34
- directory_of(gemfile_lock)
35
- end
36
- .select do |dir|
37
- folder_guard.allowed?(dir)
38
- end
39
- end
40
-
41
- def changed_gemfile_locks
42
- all_gemfile_locks.select do |gemfile_lock|
43
- repo.changed?(gemfile_lock)
44
- end
45
- end
46
-
47
- def all_gemfile_locks
48
- find("Gemfile.lock")
49
- end
50
-
51
- def find(file_name)
52
- Dir.glob("**/#{file_name}")
53
- end
54
-
55
- def directory_of(file_path)
56
- File.dirname(file_path)
57
- end
58
-
59
- end
@@ -1,22 +0,0 @@
1
- require 'work_queue'
2
-
3
- # this is a bummer...
4
- require_relative 'monkey_patches/string_extension'
5
- require_relative 'bundler/bundle_manager'
6
- require_relative 'hooks/pre_push_hook'
7
- require_relative 'hook_manager'
8
- require_relative 'migrations/migrator'
9
- require_relative 'repositories/repo'
10
- require_relative 'repositories/active_repo'
11
- require_relative 'repositories/lazy_repo'
12
- require_relative 'shells/shell_runner'
13
- require_relative 'shells/loud_shell_runner'
14
- require_relative 'shells/verbose_shell_runner'
15
- require_relative 'test_running/status_checker'
16
- require_relative 'test_running/test_case'
17
- require_relative 'test_running/test_collection'
18
- require_relative 'test_running/status_test_runner'
19
- require_relative 'test_running/test_runner'
20
- require_relative 'test_running/test_finder'
21
- require_relative 'test_running/test_filter'
22
- require_relative 'folder_guard'
@@ -1,11 +0,0 @@
1
- class FolderGuard
2
-
3
- attr_reader :denied_matches
4
- def initialize(denied_matches)
5
- @denied_matches = denied_matches
6
- end
7
-
8
- def allowed?(folder)
9
- denied_matches.select { |d| folder.match(d) }.empty?
10
- end
11
- end
@@ -1,36 +0,0 @@
1
- class HookManager
2
-
3
- def self.install!(env)
4
- new(env).install!
5
- end
6
-
7
- attr_reader :shell, :repo
8
-
9
- def initialize(env)
10
- @shell = env[:shell]
11
- @repo = env[:repo]
12
- end
13
-
14
- def is_installed?
15
- File.file?('.git/hooks/pre-push')
16
- end
17
-
18
- def install!
19
- return if is_installed?
20
-
21
- create_file
22
- make_executable
23
- end
24
-
25
- private
26
-
27
- def create_file
28
- shell.run %{echo 'app_up pre_push_hook "$(ps -ocommand= -p $PPID)"' > .git/hooks/pre-push}
29
- shell.run %{echo 'test_runner status_check --confirm_exit_status' > .git/hooks/pre-commit}
30
- end
31
-
32
- def make_executable
33
- shell.run "chmod +x .git/hooks/pre-push"
34
- shell.run "chmod +x .git/hooks/pre-commit"
35
- end
36
- end
@@ -1,31 +0,0 @@
1
- class PrePushHook
2
-
3
- def self.check(command, env)
4
- new(command, env).check
5
- end
6
-
7
- attr_reader :shell, :repo, :push_command
8
- def initialize(command, env)
9
- @shell = env[:shell]
10
- @repo = env[:repo]
11
- @push_command = command
12
- end
13
-
14
- def check
15
- if affects_master? && is_destructive?
16
- shell.warn "[Policy] Don't force push or delete master. (Denied by pre-push hook)"
17
- exit 1
18
- end
19
- end
20
-
21
- private
22
-
23
- def affects_master?
24
- push_command.match(/master/) || (repo.current_branch == 'master')
25
- end
26
-
27
- def is_destructive?
28
- push_command.match(/-f|delete|force| :master/)
29
- end
30
-
31
- end
@@ -1,42 +0,0 @@
1
- class Migrator
2
- attr_accessor :shell, :repo, :queue, :folder_guard, :drop_dbs
3
-
4
- def initialize(repo:, shell:, queue:, folder_guard:, drop_dbs: false)
5
- @shell = shell
6
- @repo = repo
7
- @queue = queue
8
- @drop_dbs = drop_dbs
9
- @folder_guard = folder_guard
10
- end
11
-
12
- def migrate_where_necessary
13
- shell.notify "\nMigrating:"
14
- migrations.each do |migration|
15
- queue.enqueue_b do
16
- shell.run "RAILS_ENV=#{migration[:env]} bundle exec rake #{drop_dbs ? 'db:drop' : ''} db:create 2> /dev/null;\n RAILS_ENV=#{migration[:env]} bundle exec rake db:migrate", dir: migration[:dir]
17
- end
18
- end
19
- queue.join
20
- end
21
-
22
- def directories_to_migrate
23
- migrate_dirs = repo.files_changed.select {|f| f.match("/migrate/") }.map {|f| File.dirname(f) }.map {|dir| dir.gsub(/\/db\/migrate$/, '')}.uniq
24
- migrate_dirs.select {|d| folder_guard.allowed?(d) };
25
- end
26
-
27
- private
28
-
29
- def migrations
30
- directories_to_migrate.map do |dir|
31
- [
32
- {env: "development",dir: dir},
33
- {env: "test", dir: dir}
34
- ]
35
- end.flatten
36
- end
37
-
38
- def in_rack_application?(migrate_dir)
39
- folder_guard.allowed?(migrate_dir)
40
- end
41
-
42
- end
@@ -1,22 +0,0 @@
1
- class String
2
- # colorization
3
- def colorize(color_code)
4
- "\e[#{color_code}m#{self}\e[0m"
5
- end
6
-
7
- def red
8
- colorize(31)
9
- end
10
-
11
- def green
12
- colorize(32)
13
- end
14
-
15
- def yellow
16
- colorize(33)
17
- end
18
-
19
- def pink
20
- colorize(35)
21
- end
22
- end
@@ -1,94 +0,0 @@
1
- require_relative 'dependency_loader'
2
-
3
- class NeedsManager
4
-
5
- BUNDLER_MAX_THREAD_COUNT = 4
6
- MIGRATOR_MAX_THREAD_COUNT = 8
7
-
8
- def self.configure(task, needs, options)
9
- new(task, needs, options).configure
10
- end
11
-
12
- attr_reader :needs, :options, :env, :log_file
13
- def initialize(task, needs, options)
14
- @log_file = log_file_for(task)
15
- @needs = needs
16
- # symbolize_keys
17
- @options = options.inject({}){|results,(k,v)| results[k.to_sym] = v; results}
18
- @env = {}
19
- end
20
-
21
- def configure
22
- set_working_directory
23
-
24
- create_shell
25
- create_folder_guard
26
-
27
- create_repo if needs.include? :repo
28
- create_bundler if needs.include? :bundler
29
- create_migrator if needs.include? :migrator
30
- create_test_runner if needs.include? :test_runner
31
-
32
- return env
33
- end
34
-
35
- def set_working_directory
36
- @working_directory = Repo.root_dir
37
- Dir.chdir(@working_directory)
38
- end
39
-
40
- def create_shell
41
- env[:shell] = shell_class.new(log_file, @working_directory)
42
- end
43
-
44
- def shell_class
45
- if options[:verbose]
46
- VerboseShellRunner
47
- elsif options[:loud]
48
- LoudShellRunner
49
- else
50
- ShellRunner
51
- end
52
- end
53
-
54
- def create_folder_guard
55
- denied_folders = options[:ignore] || []
56
- env[:folder_guard] = FolderGuard.new(denied_folders)
57
- end
58
-
59
- def create_repo
60
- env[:repo] = repo_class.new(shell: env[:shell])
61
- end
62
-
63
- def repo_class
64
- if options[:repo_type] == :active
65
- ActiveRepo
66
- elsif options[:repo_type] == :lazy
67
- LazyRepo
68
- else
69
- Repo
70
- end
71
- end
72
-
73
- def create_bundler
74
- queue = WorkQueue.new(BUNDLER_MAX_THREAD_COUNT, nil)
75
- env[:bundler] = BundleManager.new(shell: env[:shell], repo: env[:repo], queue: queue, folder_guard: env[:folder_guard])
76
- end
77
-
78
- def create_migrator
79
- queue = WorkQueue.new(MIGRATOR_MAX_THREAD_COUNT, nil)
80
- env[:migrator] = Migrator.new(shell: env[:shell], repo: env[:repo], queue: queue, folder_guard: env[:folder_guard], drop_dbs: options[:reset])
81
- end
82
-
83
- def create_test_runner
84
- env[:test_runner] = TestRunner.new(
85
- shell: env[:shell],
86
- all_engines: options[:all_engines],
87
- always_ask_before_grouping_tests: options[:timid]
88
- )
89
- end
90
-
91
- def log_file_for(task)
92
- "/tmp/#{task}.log"
93
- end
94
- end
@@ -1,60 +0,0 @@
1
- class ActiveRepo < Repo
2
-
3
- def alter!(git_command)
4
- shell.notify "\nUpdating repo state:"
5
- up do
6
- # will raise an error with merge conflicts
7
- begin
8
- shell.run "git #{git_command}"
9
- rescue ShellRunner::CommandFailureError
10
- puts "Unable to rebase. Maybe you need to stash local changes, or there are rebase conflicts"
11
- exit
12
- end
13
- end
14
- end
15
-
16
- def up_master!
17
- move_to_master!
18
- rebase_on_master!
19
- end
20
-
21
- def up
22
- old_sha = current_sha
23
- yield
24
-
25
- set_files_changed(old_sha)
26
- end
27
-
28
- def set_files_changed(old_sha)
29
- shell.notify "\nIdentifying changed files:"
30
- @files_changed = (shell.run "git diff --name-only #{old_sha}").split("\n")
31
- end
32
-
33
- def files_changed
34
- @files_changed
35
- end
36
-
37
- def pull_origin_master!
38
- up do
39
- fetch_origin
40
- reset_hard_origin_master!
41
- end
42
- end
43
-
44
- def compare_with_reflog
45
- old_sha = shell.run "git rev-parse HEAD@{2}"
46
- set_files_changed(old_sha)
47
- end
48
-
49
- def fetch_origin
50
- shell.run 'git fetch origin'
51
- end
52
-
53
- def reset_hard_origin_master!
54
- shell.run "git reset --hard origin/master"
55
- end
56
-
57
- def move_to_master!
58
- shell.run "git checkout master"
59
- end
60
- end
@@ -1,16 +0,0 @@
1
- class LazyRepo < Repo
2
-
3
- def initialize(*args)
4
- super
5
- set_all_files
6
- end
7
-
8
- def files_changed
9
- @all_files
10
- end
11
-
12
- def set_all_files
13
- shell.notify "\nIdentifying all files:"
14
- @all_files = shell.run("git ls-tree --full-tree -r HEAD --name-only").split("\n")
15
- end
16
- end
@@ -1,70 +0,0 @@
1
- class Repo
2
-
3
- def self.root_dir
4
- @root_dir ||= %x[ git rev-parse --show-toplevel ].chomp
5
- end
6
-
7
- attr_reader :shell
8
-
9
- def initialize(shell: shell)
10
- @shell = shell
11
- end
12
-
13
- def changed?(file_path)
14
- files_changed.include? file_path
15
- end
16
-
17
- def find_files(pattern)
18
- shell.run("git ls-files '*#{pattern}*'").split("\n")
19
- end
20
-
21
- def status_files
22
- statii = shell.run("git status -s").split("\n")
23
- r = statii.map do |status|
24
- status.strip!
25
- if status[0] == 'D'
26
- nil
27
- else
28
- status.split(' ').last
29
- end
30
- end.compact
31
- end
32
-
33
- def grep(regex, file_pattern: '*')
34
- results = shell.run("git grep --untracked '#{regex}' -- '#{file_pattern}'").split("\n")
35
- results.map do |result|
36
- interpret_grep_result(result)
37
- end
38
- end
39
-
40
- def current_branch
41
- shell.run 'git rev-parse --abbrev-ref HEAD'
42
- end
43
-
44
- private
45
-
46
- def interpret_grep_result(grep_result)
47
- splits = grep_result.split(/:/)
48
- file = splits.shift.strip
49
- # we rejoin on ':' because our
50
- # code may have colons inside of it.
51
- #
52
- # example:
53
- # path/to/file: run_method(a: A, b: B)
54
- #
55
- # so shift the first one out, then
56
- # rejoin the rest
57
- line = splits.join(':').strip
58
-
59
- {
60
- :file => file,
61
- :line => line,
62
- }
63
- end
64
-
65
- def current_sha
66
- shell.run "git rev-parse HEAD"
67
- end
68
-
69
-
70
- end
@@ -1,7 +0,0 @@
1
- class LoudShellRunner < ShellRunner
2
-
3
- def handle_output_for(cmd)
4
- puts cmd
5
- log(cmd)
6
- end
7
- end
@@ -1,88 +0,0 @@
1
- class ShellRunner
2
- CommandFailureError = Class.new(StandardError)
3
-
4
- attr_accessor :working_directory, :log_path
5
-
6
- def initialize(log_path, working_directory)
7
- @working_directory = working_directory
8
- @queue = ''
9
- @log_path = log_path
10
- reset_log
11
- end
12
-
13
- def run(cmd, dir: working_directory)
14
- command = "cd #{dir} && #{cmd}"
15
- handle_output_for(command)
16
- shell_out(command)
17
- end
18
-
19
- def shell_out(command)
20
- %x{ set -o pipefail && #{command} 2>> #{log_path} | tee -a #{log_path} }.chomp.tap do
21
- raise CommandFailureError, "The following command has failed: #{command}. See #{log_path} for a full log." if ($?.exitstatus != 0)
22
- end
23
- end
24
-
25
- def exec(cmd, dir: working_directory)
26
- command = "cd #{dir} && #{cmd}"
27
- notify "\n#{command}"
28
- Kernel.exec command
29
- end
30
-
31
- def enqueue(cmd, dir: working_directory)
32
- command = "cd #{dir} && #{cmd} && cd -"
33
- @queue += "#{command};\n"
34
- end
35
-
36
- def confirm?(question)
37
- warn "#{question} [Yn]"
38
- answer = STDIN.gets.strip.downcase
39
- return answer != 'n'
40
- end
41
-
42
- def get_number_list_for_question(question)
43
- warn question
44
- answer = STDIN.gets.strip
45
-
46
- answer.split(',').map do |term|
47
- if term.include?('-')
48
- (term.split('-')[0].to_i..term.split('-')[1].to_i).to_a
49
- else
50
- term.to_i
51
- end
52
- end.flatten
53
- end
54
-
55
- def deny?(question)
56
- ! confirm?(question)
57
- end
58
-
59
- def exec_queue
60
- notify 'running: '
61
- notify ''
62
- notify @queue
63
- Kernel.exec @queue
64
- end
65
-
66
- def warn(msg)
67
- log msg
68
- puts msg.red
69
- end
70
-
71
- def notify(msg)
72
- log msg
73
- puts msg.yellow
74
- end
75
-
76
- def log(msg)
77
- %x{echo "#{msg}" >> #{log_path}}
78
- end
79
-
80
- def reset_log
81
- %x{echo "" > #{log_path}}
82
- end
83
-
84
- def handle_output_for(cmd)
85
- log(cmd)
86
- end
87
-
88
- end
@@ -1,8 +0,0 @@
1
- class VerboseShellRunner < LoudShellRunner
2
-
3
- def run(*args)
4
- super(*args).tap do |results|
5
- puts results
6
- end
7
- end
8
- end
@@ -1,62 +0,0 @@
1
- class StatusChecker
2
- def self.report(env, confirm_exit_status)
3
- new(env, confirm_exit_status).report
4
- end
5
-
6
- attr_reader :repo, :shell, :untested_files
7
- def initialize(env, confirm_exit_status)
8
- @repo = env[:repo]
9
- @shell = env[:shell]
10
- @untested_files = []
11
- @confirm_exit_status = confirm_exit_status
12
- end
13
-
14
- def report
15
- non_test_files.each do |file|
16
- if ! test_files.include? "#{file}_test"
17
- untested_files << full_path_by_basename(file)
18
- end
19
- end
20
-
21
- if untested_files.empty?
22
- shell.notify "All ruby files are tested!"
23
- exit 0
24
- else
25
- shell.warn "The following files have changed without being tested:\n\n#{untested_files.join("\n")}"
26
-
27
- STDIN.reopen('/dev/tty')
28
- if confirm_exit_status? && shell.confirm?("\nDo you still wish to commit?")
29
- exit 0
30
- else
31
- exit 1
32
- end
33
- end
34
-
35
- end
36
-
37
- private
38
-
39
- def test_files
40
- TestFilter.select_tests(file_names)
41
- end
42
-
43
- def non_test_files
44
- TestFilter.reject_tests(file_names)
45
- end
46
-
47
- def file_names
48
- @file_names ||= files.select {|f| f.match(/\.rb$/)}.map {|f| File.basename(f, '.rb') }
49
- end
50
-
51
- def files
52
- @files ||= repo.status_files
53
- end
54
-
55
- def full_path_by_basename(file)
56
- files.select {|f| File.basename(f, '.rb') == file }.first
57
- end
58
-
59
- def confirm_exit_status?
60
- @confirm_exit_status
61
- end
62
- end
@@ -1,41 +0,0 @@
1
- class StatusTestRunner
2
-
3
- def self.status(env, ignore_selenium=false)
4
- new(env, ignore_selenium).status
5
- end
6
-
7
- attr_reader :repo, :shell, :test_runner, :status_tests, :ignore_selenium
8
- def initialize(env, ignore_selenium)
9
- @repo = env[:repo]
10
- @shell = env[:shell]
11
- @test_runner = env[:test_runner]
12
- @ignore_selenium = ignore_selenium
13
- @status_tests = get_status_tests
14
- end
15
-
16
- def status
17
- if status_tests.include_selenium?
18
- handle_selenium
19
- end
20
-
21
- if status_tests.empty?
22
- shell.notify 'No tests to run'
23
- exit
24
- end
25
-
26
- test_runner.run_files(status_tests)
27
- end
28
-
29
- private
30
-
31
- def handle_selenium
32
- if ignore_selenium || shell.deny?("The status includes some selenium files. Do you wish to run those?")
33
- status_tests.remove_selenium!
34
- end
35
- end
36
-
37
- def get_status_tests
38
- files = TestFilter.select_tests(repo.status_files)
39
- TestCollection.new(files)
40
- end
41
- end
@@ -1,38 +0,0 @@
1
- class TestCase
2
- TestDirectoryError = Class.new(StandardError)
3
-
4
- attr_reader :working_dir, :relative_path, :test_name, :full_path
5
-
6
- def initialize(full_path: raise, line: '')
7
- raise 'Bad Test File' unless full_path.match(/_test\.rb/)
8
-
9
- @test_name = test_name_from_grepped_line(line)
10
- @full_path = full_path
11
- end
12
-
13
- def working_dir
14
- @working_dir ||=
15
- if full_path.match(/^(.*)test\//)
16
- File.join(".", full_path.match(/^(.*)test\//)[1])
17
- else
18
- raise TestDirectoryError.new("Can't find test's working directory")
19
- end
20
- end
21
-
22
- def is_method?
23
- ! @test_name.nil?
24
- end
25
-
26
- def relative_path
27
- @relative_path ||= full_path.gsub(/^#{working_dir.gsub(/^\.\//, '')}/, '') || raise_file_path_error
28
- end
29
-
30
- def raise_file_path_error
31
- raise TestDirectoryError.new("Can't find test's relative path")
32
- end
33
-
34
- def test_name_from_grepped_line(line)
35
- return unless line && line.match(/^\s*def\s+test_/)
36
- @test_name = line.strip.gsub(/^\s*def\s+/, '').strip
37
- end
38
- end
@@ -1,97 +0,0 @@
1
- class TestCollection
2
-
3
- MultipleWorkingDirectoriesError = Class.new(StandardError)
4
-
5
- attr_reader :tests, :query
6
-
7
- def initialize(tests_data=[], query: '')
8
- @query = query
9
- @tests = tests_data.map do |test_data|
10
- if test_data.is_a? TestCase
11
- test_data
12
- else
13
- test_data = {file: test_data} if test_data.is_a?(String)
14
-
15
- TestCase.new(
16
- full_path: test_data[:file],
17
- line: test_data[:line]
18
- )
19
- end
20
- end.compact
21
- end
22
-
23
- def empty?
24
- tests.empty?
25
- end
26
-
27
- def uniq!
28
- @tests = @tests.uniq {|e| "#{e.full_path} #{e.test_name} #{e.working_dir}" }
29
- end
30
-
31
- def present?
32
- ! empty?
33
- end
34
-
35
- def size
36
- tests.size
37
- end
38
-
39
- def first
40
- tests.first
41
- end
42
-
43
- def [](*args)
44
- tests[*args]
45
- end
46
-
47
- def all?(&block)
48
- tests.all?(&block)
49
- end
50
-
51
- def in_one_file?
52
- full_paths.size == 1
53
- end
54
-
55
- def in_one_engine?
56
- working_dirs.size == 1
57
- end
58
-
59
- def full_paths
60
- @full_paths ||= tests.map {|t| t.full_path }.uniq
61
- end
62
-
63
- def relative_paths
64
- @relative_paths ||= tests.map {|t| t.relative_path }.uniq
65
- end
66
-
67
- def working_dirs
68
- @working_dirs ||= tests.map {|t| t.working_dir }.uniq
69
- end
70
-
71
- def relative_paths_in(working_directory)
72
- tests.select {|t| t.working_dir == working_directory}.map {|t| t.relative_path }.uniq
73
- end
74
-
75
- def include_selenium?
76
- ! selenium_tests.empty?
77
- end
78
-
79
- def remove_selenium!
80
- @tests = tests - selenium_tests
81
- end
82
-
83
- def selenium_tests
84
- tests.select {|t| t.full_path.match(/selenium/)}
85
- end
86
-
87
- def working_dir
88
- raise MultipleWorkingDirectoriesError.new("Can't run tests for more than one engine") unless working_dirs.size == 1
89
-
90
- return working_dirs.first
91
- end
92
-
93
- def is_one_test_method?
94
- (size == 1) && tests.first.is_method?
95
- end
96
-
97
- end
@@ -1,15 +0,0 @@
1
- class TestFilter
2
- def self.select_tests(files)
3
- filter(action: :select, files: files)
4
- end
5
-
6
- def self.reject_tests(files)
7
- filter(action: :reject, files: files)
8
- end
9
-
10
- private
11
-
12
- def self.filter(action:, files:)
13
- files.send(action) {|f| f.match(/_test(\.rb)?$/) }
14
- end
15
- end
@@ -1,70 +0,0 @@
1
- class TestFinder
2
-
3
- def self.find(query, env)
4
- new(env, query).find
5
- end
6
-
7
- attr_accessor :shell, :repo, :query
8
- def initialize(env, query)
9
- @shell = env[:shell]
10
- @repo = env[:repo]
11
- @query = query
12
- @regex_searches = {}
13
- end
14
-
15
- def find
16
- return tests_found_by_absolute_path if query.match(Repo.root_dir)
17
-
18
- return tests_found_by_name if tests_found_by_name.present?
19
-
20
- return tests_found_by_file_name if tests_found_by_file_name.present?
21
-
22
- return tests_found_by_full_regex if tests_found_by_full_regex.present?
23
-
24
- return TestCollection.new
25
- end
26
-
27
- private
28
-
29
- def tests_found_by_absolute_path
30
- TestCollection.new([file: query.gsub(Repo.root_dir, '')])
31
- end
32
-
33
- def tests_found_by_name
34
- @tests_found_by_name ||=
35
- begin
36
- tests_found_by_full_regex("^\s*def .*#{query}.*")
37
- end
38
- end
39
-
40
- def tests_found_by_full_regex(regex = query)
41
- @regex_searches[regex] ||=
42
- begin
43
- test_matches = []
44
- begin
45
- test_matches = repo.grep(regex, file_pattern: '*_test.rb')
46
- rescue ShellRunner::CommandFailureError
47
- # git grep returns 1 if no results found
48
- end
49
-
50
- TestCollection.new(test_matches, query: query)
51
- end
52
- end
53
-
54
- def tests_found_by_file_name
55
- @tests_found_by_file_name ||=
56
- begin
57
- files = TestFilter.select_tests(repo.find_files(query))
58
- TestCollection.new(files)
59
- end
60
- end
61
-
62
- def might_be_method?(query)
63
- ! is_file_path?(query)
64
- end
65
-
66
- def is_file_path?(query)
67
- !! query.match(/\.rb/)
68
- end
69
-
70
- end
@@ -1,121 +0,0 @@
1
- class TestRunner
2
-
3
- attr_reader :shell, :all_engines_param, :always_ask_before_grouping_tests
4
- def initialize(env)
5
- @shell = env[:shell]
6
- @all_engines_param = env[:all_engines]
7
- @always_ask_before_grouping_tests = env[:always_ask_before_grouping_tests]
8
- end
9
-
10
- # Hack: this could use *a lot* of love
11
- # this could use some love
12
- def run(tests)
13
-
14
- if tests.empty?
15
- shell.warn "Unable to identify any tests."
16
- exit
17
-
18
- elsif tests.is_one_test_method?
19
- test = tests.first
20
- run_method(path: test.relative_path, name: test.test_name, dir: test.working_dir)
21
- elsif always_ask_before_grouping_tests
22
- ask_user_which_tests_to_run(tests)
23
- elsif tests.in_one_file? && tests.all? {|t| t.is_method? }
24
- shell.notify "Multiple matches in same file. Running those tests"
25
- test = tests.first
26
- run_method(path: test.relative_path, name: tests.query, dir: test.working_dir)
27
-
28
- elsif tests.in_one_file? #catches regex that matched a test file or other regex that matched in the body
29
- shell.notify "Matched one file. Running that file."
30
- run_files(tests)
31
-
32
- elsif tests.in_one_engine? && tests.full_paths.size < 4 # hack: maybe should ask here?
33
- shell.notify "Multiple matches across files in same engine. Running those files."
34
- run_files(tests)
35
-
36
- else
37
- ask_user_which_tests_to_run(tests)
38
- end
39
- end
40
-
41
- def run_method(path:, name:, dir:)
42
- test_runner = named_test_runner(dir)
43
- shell.exec("#{test_runner} #{path} --name=/#{name}/", dir: dir)
44
- end
45
-
46
- def ask_user_which_tests_to_run(tests)
47
- shell.warn 'Found too many tests. Please choose which matches you would like to run:'
48
-
49
- tests.uniq!.each_with_index do |t, index|
50
- shell.notify "(#{index}) #{t.full_path}: #{t.test_name}"
51
- end
52
-
53
- tests_to_run = shell.get_number_list_for_question('Please enter the match numbers you would like to run(comma seperated)')
54
-
55
- new_tests = tests_to_run.map do |index|
56
- tests[index]
57
- end
58
- @always_ask_before_grouping_tests = false
59
- run(TestCollection.new(new_tests))
60
- end
61
-
62
- def run_files(tests)
63
- begin
64
- test_runner = test_collection_runner(tests.working_dir)
65
- test_files = tests.relative_paths.join(' ')
66
-
67
- shell.exec("#{test_runner} #{test_files}", dir: tests.working_dir)
68
- rescue TestCollection::MultipleWorkingDirectoriesError => e
69
- if run_across_engines?
70
- run_across_engines(tests)
71
- end
72
- end
73
- end
74
-
75
- def run_across_engines(tests)
76
- shell.notify "\nfinding test runners"
77
- tests.working_dirs.each do |engine_dir|
78
- test_files = tests.relative_paths_in(engine_dir).join(' ')
79
- test_runner = test_collection_runner(engine_dir)
80
-
81
- shell.enqueue("#{test_runner} #{test_files}", dir: engine_dir)
82
- end
83
- shell.exec_queue
84
- end
85
-
86
- def test_runner_type(working_dir)
87
- if shell.run("ls bin", dir: working_dir).split("\n").include? 'testunit'
88
- :spring
89
- else
90
- :ruby
91
- end
92
- rescue ShellRunner::CommandFailureError
93
- :ruby
94
- end
95
-
96
- def named_test_runner(working_dir)
97
- if test_runner_type(working_dir) == :spring
98
- # hack:
99
- # Add some options for using spring.
100
- #
101
- #"bin/testunit"
102
- "ruby -I test"
103
- else
104
- "ruby -I test"
105
- end
106
- end
107
-
108
- def test_collection_runner(working_dir)
109
- if test_runner_type(working_dir) == :spring
110
- #"bin/testunit"
111
- %{ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + "/" + file) }'}
112
- else
113
- %{ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + "/" + file) }'}
114
- end
115
- end
116
-
117
- def run_across_engines?
118
- all_engines_param || shell.confirm?("Test files are in multiple engines. Run them all?")
119
- end
120
-
121
- end
@@ -1,44 +0,0 @@
1
- require_relative 'needs_manager'
2
-
3
- class Tester
4
-
5
- def self.needs
6
- [:shell, :repo, :test_runner]
7
- end
8
-
9
- def self.find(inputs, options)
10
- env = NeedsManager.configure(:test_runner, needs, options.merge(repo_type: :info))
11
- new(env).find(inputs)
12
- end
13
-
14
- def self.status(options)
15
- env = NeedsManager.configure(:test_runner, needs, options.merge(repo_type: :info))
16
- new(env).status(options)
17
- end
18
-
19
- def self.status_check(options)
20
- env = NeedsManager.configure(:test_runner, (needs - [:test_runner]), options.merge(repo_type: :info))
21
- new(env).status_check(options)
22
- end
23
-
24
- attr_accessor :env
25
- def initialize(env)
26
- @env = env
27
- end
28
-
29
- def find(input)
30
- tests = TestFinder.find(input, env)
31
-
32
- env[:test_runner].run(tests)
33
- env[:shell].warn "Giving up :("
34
- end
35
-
36
- def status(options)
37
- StatusTestRunner.status(env, options[:no_selenium])
38
- end
39
-
40
- def status_check(options)
41
- StatusChecker.report(env, options[:confirm_exit_status])
42
- end
43
-
44
- end
@@ -1,93 +0,0 @@
1
- require_relative 'needs_manager'
2
-
3
- class Upper
4
-
5
- def self.needs
6
- [:shell, :repo, :bundler, :migrator]
7
- end
8
-
9
- def self.with_defaults(options)
10
- {loud: true}.merge(options)
11
- end
12
-
13
- def self.arbitrary_action!(git_command, options)
14
- env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :active))
15
- new(env).arbitrary_action!(git_command)
16
- end
17
-
18
- def self.rebase_on_branch!(options)
19
- env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :active))
20
- new(env).arbitrary_action!("pull --rebase origin #{env[:repo].current_branch}")
21
- end
22
-
23
- def self.rebase_on_master!(options)
24
- env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :active))
25
- new(env).arbitrary_action!("pull --rebase origin master")
26
- end
27
-
28
- def self.up_master!(options)
29
- env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :active))
30
- new(env).up_master!
31
- end
32
-
33
- def self.no_git(options)
34
- env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :lazy))
35
- new(env).no_git
36
- end
37
-
38
- def self.finish_rebase(options)
39
- env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :active))
40
- new(env).finish_rebase
41
- end
42
-
43
- def self.install_hooks(options)
44
- env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :lazy))
45
- new(env).install_hooks
46
- end
47
-
48
- def self.pre_push_hook(git_command, options)
49
- env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :active))
50
- new(env).pre_push_hook(git_command)
51
- end
52
-
53
- attr_reader :env, :repo, :bundler, :migrator
54
-
55
- def initialize(env)
56
- @env = env
57
- @repo = env[:repo]
58
- @bundler = env[:bundler]
59
- @migrator = env[:migrator]
60
- end
61
-
62
- def up_master!
63
- repo.up_master!
64
- bundler.bundle_where_necessary
65
- migrator.migrate_where_necessary
66
- end
67
-
68
- def arbitrary_action!(git_command)
69
- repo.alter!(git_command)
70
- bundler.bundle_where_necessary
71
- migrator.migrate_where_necessary
72
- end
73
-
74
- def no_git
75
- env[:shell].notify "\nBundling and migrating without checking diffs:"
76
- bundler.bundle_where_necessary
77
- migrator.migrate_where_necessary
78
- end
79
-
80
- def finish_rebase
81
- repo.compare_with_reflog
82
- bundler.bundle_where_necessary
83
- migrator.migrate_where_necessary
84
- end
85
-
86
- def install_hooks
87
- HookManager.install!(env)
88
- end
89
-
90
- def pre_push_hook(git_command)
91
- PrePushHook.check(git_command, env)
92
- end
93
- end
@@ -1,3 +0,0 @@
1
- module SfbScripts
2
- VERSION = "1.9.0"
3
- end