sfb_scripts 1.9.0 → 2.0.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
  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