sfb_scripts 0.2.0 → 1.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: aa1bfa22f42bad325e3fae6d68a8cf56ae0ddadf
4
- data.tar.gz: ef3751b60b61a8ccf310cb1f4bc6ccd08dd54361
3
+ metadata.gz: 37feb93572e3de507db54fb6a99028c40e3cb35d
4
+ data.tar.gz: 108e6cc518c42438b967c84dcab6071ca033816d
5
5
  SHA512:
6
- metadata.gz: 623055c0dbf1357e7ca7c91ea2d1632d6456c5e842e89cc7d7691dcb0e2d98ce1b20902b28ef8b30d5af6a8d81fcbaba21ffd8fac848bc3b9f669d099ae54154
7
- data.tar.gz: 12c2377cf70bbfab5505e18847994f2538cc747a5ed6b6836e86b462877e13693da6e515f70b4a0aace25487ffeecf92f4522f15ce2733b935e1a52956bfd5df
6
+ metadata.gz: 2e4342556ab9a7b92933310ba7661b27ce371b32fd29ae938a43ead87c1d30c357f9f22a98e0aa208ac29a6de9ac6a49fb544254ea0ad1d07755328ca1399abb
7
+ data.tar.gz: 9305964ae8a97f4f234e388ad53f611e697b7608c4c9d0f779a3a717b715e0d5a9e56313de02827124172f10874298bd6687618983af045375a06a4b7ba8a8cd
data/bin/app_up CHANGED
@@ -13,10 +13,16 @@ class CLI < Thor
13
13
  option :loud, :type => :boolean, :desc => 'Pipe output to terminal or not (output is always piped to /tmp/app_up.log)'
14
14
  option :no_git, aliases: ['--no-pull', '--no-rebase'], :type => :boolean, :desc => "Don't update the repo, just bundle and migrate everywhere."
15
15
  option :ignore, type: :array, desc: "Directories matching this pattern will be ignored. Example: 'app_up --ignore engines' will not bundle or migrate in a directory matching the word engines. You can specify multiple patterns: 'app_up --ignore dir1 dir2"
16
+ option :on_branch, desc: "Rebase the current branch onto it's upstream counterpart. [Example: While on branch (feature_branch), using the --on-branch flag will yield the git command: 'git pull --rebase origin feature_branch'", default: 'master', default: false
17
+ option :git_action, desc: "Specify what command to pass to git [Example: app_up --git-action 'pull --rebase origin branch_name']. Defaults to 'pull --rebase origin master'."
16
18
 
17
19
  def up
18
20
  if options[:no_git]
19
21
  Upper.no_git(options)
22
+ elsif options[:on_branch]
23
+ Upper.rebase_on_branch!(options)
24
+ elsif options[:git_action]
25
+ Upper.arbitrary_action!(options[:git_action], options)
20
26
  else
21
27
  Upper.rebase_on_master!(options)
22
28
  end
data/bin/test_runner CHANGED
@@ -4,7 +4,8 @@ require 'thor'
4
4
  require_relative '../lib/sfb_scripts/tester'
5
5
 
6
6
  class CLI < Thor
7
-
7
+ class_option :verbose, type: :boolean, desc: "Pipe the log file to stdout."
8
+ class_option :loud, type: :boolean, desc: "Show all shell commands being run. This *does not* show the output of those commands, only what is being run."
8
9
  #
9
10
  # run
10
11
  #
@@ -21,8 +22,13 @@ class CLI < Thor
21
22
  desc "find", <<-DESC
22
23
  Find tests and run them. By trying to match an individual test or the name of a test file(s).
23
24
  DESC
24
- def find(*inputs)
25
- Tester.find(inputs, options)
25
+ def find(input)
26
+ if input == '--help'
27
+ puts "use 'test_runner --help find' to see the help"
28
+ exit
29
+ end
30
+
31
+ Tester.find(input, options)
26
32
  end
27
33
 
28
34
  desc "status_check", "Verify that you don't edit a file without editing its corresponding test file."
@@ -31,7 +37,7 @@ class CLI < Thor
31
37
  Tester.status_check(options)
32
38
  end
33
39
 
34
- default_task :status
40
+ default_task :status_check
35
41
 
36
42
  end
37
43
 
@@ -10,10 +10,11 @@ require_relative 'repositories/active_repo'
10
10
  require_relative 'repositories/lazy_repo'
11
11
  require_relative 'shells/shell_runner'
12
12
  require_relative 'shells/loud_shell_runner'
13
+ require_relative 'shells/verbose_shell_runner'
13
14
  require_relative 'test_running/status_checker'
14
15
  require_relative 'test_running/test_case'
15
16
  require_relative 'test_running/test_collection'
16
- require_relative 'test_running/test_file_runner'
17
- require_relative 'test_running/test_method_runner'
17
+ require_relative 'test_running/status_test_runner'
18
18
  require_relative 'test_running/test_runner'
19
+ require_relative 'test_running/test_finder'
19
20
  require_relative 'folder_guard'
@@ -41,7 +41,9 @@ class NeedsManager
41
41
  end
42
42
 
43
43
  def shell_class
44
- if options[:loud]
44
+ if options[:verbose]
45
+ VerboseShellRunner
46
+ elsif options[:loud]
45
47
  LoudShellRunner
46
48
  else
47
49
  ShellRunner
@@ -1,11 +1,11 @@
1
1
  class ActiveRepo < Repo
2
2
 
3
- def rebase_on_master!
3
+ def alter!(git_command)
4
4
  shell.notify "\nRebasing current branch on master:"
5
5
  up do
6
6
  # will raise an error with merge conflicts
7
7
  begin
8
- shell.run "git pull --rebase origin master"
8
+ shell.run "git #{git_command}"
9
9
  rescue ShellRunner::CommandFailureError
10
10
  puts "Unable to rebase. Maybe you need to stash local changes, or there are rebase conflicts"
11
11
  puts `git status`
@@ -1,8 +1,7 @@
1
1
  class LoudShellRunner < ShellRunner
2
2
 
3
- def run(*args)
4
- super(*args).tap do |results|
5
- puts results
6
- end
3
+ def handle_output_for(cmd)
4
+ puts cmd
5
+ log(cmd)
7
6
  end
8
7
  end
@@ -12,8 +12,11 @@ class ShellRunner
12
12
 
13
13
  def run(cmd, dir: working_directory)
14
14
  command = "cd #{dir} && #{cmd}"
15
- puts command
16
- log command
15
+ handle_output_for(command)
16
+ shell_out(command)
17
+ end
18
+
19
+ def shell_out(command)
17
20
  %x{ set -o pipefail && #{command} 2>> #{log_path} | tee -a #{log_path} }.chomp.tap do
18
21
  raise CommandFailureError, "The following command has failed: #{command}. See #{log_path} for a full log." if ($?.exitstatus != 0)
19
22
  end
@@ -65,4 +68,8 @@ class ShellRunner
65
68
  %x{echo "" > #{log_path}}
66
69
  end
67
70
 
71
+ def handle_output_for(cmd)
72
+ log(cmd)
73
+ end
74
+
68
75
  end
@@ -0,0 +1,8 @@
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,8 +1,4 @@
1
- class TestFileRunner
2
-
3
- def self.find(inputs, env)
4
- new(env, false).find(inputs)
5
- end
1
+ class StatusTestRunner
6
2
 
7
3
  def self.status(env, ignore_selenium=false)
8
4
  new(env, ignore_selenium).status
@@ -16,16 +12,6 @@ class TestFileRunner
16
12
  @ignore_selenium = ignore_selenium
17
13
  end
18
14
 
19
- def find(inputs)
20
- files = []
21
- inputs.each {|input| files << repo.find_files(input).map {|f| {:file => f} } }
22
- files.flatten!
23
- @tests = TestCollection.new(files)
24
-
25
- return false unless @tests.present?
26
- test_runner.run_files(tests)
27
- end
28
-
29
15
  def status
30
16
  files = repo.status_files.map {|f| {:file => f} }
31
17
  @tests = TestCollection.new(files)
@@ -3,8 +3,10 @@ class TestCase
3
3
 
4
4
  attr_reader :working_dir, :relative_path, :test_name, :full_path
5
5
 
6
- def initialize(full_path: raise, test_name: '')
7
- @test_name = test_name
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)
8
10
  @full_path = full_path
9
11
  end
10
12
 
@@ -17,6 +19,10 @@ class TestCase
17
19
  end
18
20
  end
19
21
 
22
+ def is_method?
23
+ ! @test_name.nil?
24
+ end
25
+
20
26
  def relative_path
21
27
  @relative_path ||= full_path.gsub(/^#{working_dir.gsub(/^\.\//, '')}/, '') || raise_file_path_error
22
28
  end
@@ -24,4 +30,9 @@ class TestCase
24
30
  def raise_file_path_error
25
31
  raise TestDirectoryError.new("Can't find test's relative path")
26
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
27
38
  end
@@ -2,20 +2,14 @@ class TestCollection
2
2
 
3
3
  MultipleWorkingDirectoriesError = Class.new(StandardError)
4
4
 
5
- def self.parse(grep_result)
6
- new(grep_result[:file], line: grep_result[:line]).parse
7
- end
8
-
9
-
10
- def self.from_file_path(file_path)
11
- new(file_path).from_file_path
12
- end
13
-
14
5
  attr_reader :tests
15
6
 
16
- def initialize(tests_data)
7
+ def initialize(tests_data=[])
17
8
  @tests = tests_data.map do |test_data|
18
- create_test_case(test_data)
9
+ TestCase.new(
10
+ full_path: test_data[:file],
11
+ line: test_data[:line]
12
+ )
19
13
  end.compact
20
14
  end
21
15
 
@@ -39,6 +33,10 @@ class TestCollection
39
33
  tests[*args]
40
34
  end
41
35
 
36
+ def all?(&block)
37
+ tests.all?(&block)
38
+ end
39
+
42
40
  def in_one_file?
43
41
  full_paths.size == 1
44
42
  end
@@ -81,23 +79,8 @@ class TestCollection
81
79
  return working_dirs.first
82
80
  end
83
81
 
84
- private
85
-
86
- def find_test_name(grepped_line)
87
- return nil unless grepped_line && grepped_line.match(/^\s*def\s+test_/)
88
-
89
- grepped_line.strip.gsub(/^\s*def /, '').strip
90
- end
91
-
92
- def create_test_case(test_data)
93
- file_path = test_data[:file]
94
- test_name = find_test_name(test_data[:line])
95
- return nil if ! file_path.match(/_test\.rb/)
96
-
97
- TestCase.new(
98
- full_path: file_path,
99
- test_name: test_name
100
- )
82
+ def is_one_test_method?
83
+ (size == 1) && tests.first.is_method?
101
84
  end
102
85
 
103
86
  end
@@ -0,0 +1,66 @@
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_name if tests_found_by_name.present?
17
+
18
+ return tests_found_by_file_name if tests_found_by_file_name.present?
19
+
20
+ return tests_found_by_full_regex if tests_found_by_full_regex.present?
21
+
22
+ return TestCollection.new
23
+ end
24
+
25
+ private
26
+
27
+ def tests_found_by_name
28
+ @tests_found_by_name ||=
29
+ begin
30
+ tests_found_by_full_regex("^\s*def .*#{query}.*")
31
+ end
32
+ end
33
+
34
+ def tests_found_by_full_regex(regex = query)
35
+ @regex_searches[regex] ||=
36
+ begin
37
+ test_matches = []
38
+ begin
39
+ test_matches = repo.grep(regex, file_pattern: '*_test.rb')
40
+ rescue ShellRunner::CommandFailureError
41
+ # git grep returns 1 if no results found
42
+ end
43
+
44
+ TestCollection.new(test_matches)
45
+ end
46
+ end
47
+
48
+ def tests_found_by_file_name
49
+ @tests_found_by_file_name ||=
50
+ begin
51
+ files = []
52
+ files << repo.find_files(query).map {|f| {:file => f} }
53
+ files.flatten!
54
+ TestCollection.new(files)
55
+ end
56
+ end
57
+
58
+ def might_be_method?(query)
59
+ ! is_file_path?(query)
60
+ end
61
+
62
+ def is_file_path?(query)
63
+ !! query.match(/\.rb/)
64
+ end
65
+
66
+ end
@@ -6,6 +6,27 @@ class TestRunner
6
6
  @all_engines_param = env[:all_engines]
7
7
  end
8
8
 
9
+ # this could use some love
10
+ def run(tests)
11
+ if tests.is_one_test_method?
12
+ run_method(tests.first)
13
+ elsif tests.in_one_file? && tests.all? {|t| t.is_method? }
14
+ shell.notify "Multiple matches in same file. Running that file."
15
+ run_files(tests)
16
+ elsif tests.in_one_file?
17
+ shell.notify "Matched one file."
18
+ run_files(tests)
19
+ elsif tests.in_one_engine? && tests.full_paths.size < 4 # hack: maybe should ask here?
20
+ shell.notify "Multiple matches across files in same engine. Running those files."
21
+ run_files(tests)
22
+ else
23
+ shell.warn 'Found too many tests:'
24
+ tests[0..10].each {|t| shell.notify "#{t.full_path}: #{t.test_name}" }
25
+ shell.notify '...'
26
+ exit
27
+ end
28
+ end
29
+
9
30
  def run_method(test)
10
31
  test_runner = named_test_runner(test.working_dir)
11
32
 
@@ -25,8 +46,6 @@ class TestRunner
25
46
  end
26
47
  end
27
48
 
28
- private
29
-
30
49
  def run_across_engines(tests)
31
50
  shell.notify "\nfinding test runners"
32
51
  tests.working_dirs.each do |engine_dir|
@@ -26,42 +26,19 @@ class Tester
26
26
  @env = env
27
27
  end
28
28
 
29
- def find(inputs)
30
- # each of these replaces this process if successful
31
- # so no need for logic control flow
32
- if query_might_be_method?(inputs)
33
- TestMethodRunner.run(inputs.first, env)
34
- end
35
-
36
- TestFileRunner.find(inputs, env)
37
-
38
- TestMethodRunner.run_file_with_match(inputs.first, env)
29
+ def find(input)
30
+ tests = TestFinder.find(input, env)
39
31
 
32
+ env[:test_runner].run(tests)
40
33
  env[:shell].warn "Giving up :("
41
34
  end
42
35
 
43
36
  def status(options)
44
- TestFileRunner.status(env, options[:no_selenium])
37
+ StatusTestRunner.status(env, options[:no_selenium])
45
38
  end
46
39
 
47
40
  def status_check(options)
48
41
  StatusChecker.report(env, options[:confirm_exit_status])
49
42
  end
50
43
 
51
- private
52
-
53
- def query_might_be_method?(inputs)
54
- if inputs.any? {|input| is_file_path?(input) }
55
- false
56
- elsif inputs.size > 1
57
- false
58
- else
59
- true
60
- end
61
- end
62
-
63
- def is_file_path?(input)
64
- !! input.match(/\.rb/)
65
- end
66
-
67
44
  end
@@ -6,28 +6,42 @@ class Upper
6
6
  [:shell, :repo, :bundler, :migrator]
7
7
  end
8
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
+
9
23
  def self.rebase_on_master!(options)
10
- env = NeedsManager.configure(:up, needs, options.merge(repo_type: :active))
11
- new(env).rebase_on_master!
24
+ env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :active))
25
+ new(env).arbitrary_action!("pull --rebase origin master")
12
26
  end
13
27
 
14
28
  def self.up_master!(options)
15
- env = NeedsManager.configure(:up, needs, options.merge(repo_type: :active))
29
+ env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :active))
16
30
  new(env).up_master!
17
31
  end
18
32
 
19
33
  def self.no_git(options)
20
- env = NeedsManager.configure(:up, needs, options.merge(repo_type: :lazy))
34
+ env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :lazy))
21
35
  new(env).no_git
22
36
  end
23
37
 
24
38
  def self.install_hooks(options)
25
- env = NeedsManager.configure(:up, needs, options.merge(repo_type: :lazy))
39
+ env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :lazy))
26
40
  new(env).install_hooks
27
41
  end
28
42
 
29
43
  def self.pre_push_hook(git_command, options)
30
- env = NeedsManager.configure(:up, needs, options.merge(repo_type: :lazy))
44
+ env = NeedsManager.configure(:up, needs, with_defaults(options).merge(repo_type: :lazy))
31
45
  new(env).pre_push_hook(git_command)
32
46
  end
33
47
 
@@ -46,8 +60,8 @@ class Upper
46
60
  migrator.migrate_where_necessary
47
61
  end
48
62
 
49
- def rebase_on_master!
50
- repo.rebase_on_master!
63
+ def arbitrary_action!(git_command)
64
+ repo.alter!(git_command)
51
65
  bundler.bundle_where_necessary
52
66
  migrator.migrate_where_necessary
53
67
  end
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: 0.2.0
4
+ version: 1.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: 2014-08-29 00:00:00.000000000 Z
11
+ date: 2014-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -72,11 +72,12 @@ files:
72
72
  - lib/sfb_scripts/repositories/repo.rb
73
73
  - lib/sfb_scripts/shells/loud_shell_runner.rb
74
74
  - lib/sfb_scripts/shells/shell_runner.rb
75
+ - lib/sfb_scripts/shells/verbose_shell_runner.rb
75
76
  - lib/sfb_scripts/test_running/status_checker.rb
77
+ - lib/sfb_scripts/test_running/status_test_runner.rb
76
78
  - lib/sfb_scripts/test_running/test_case.rb
77
79
  - lib/sfb_scripts/test_running/test_collection.rb
78
- - lib/sfb_scripts/test_running/test_file_runner.rb
79
- - lib/sfb_scripts/test_running/test_method_runner.rb
80
+ - lib/sfb_scripts/test_running/test_finder.rb
80
81
  - lib/sfb_scripts/test_running/test_runner.rb
81
82
  - lib/sfb_scripts/tester.rb
82
83
  - lib/sfb_scripts/upper.rb
@@ -1,59 +0,0 @@
1
- class TestMethodRunner
2
-
3
- def self.run(regex, env)
4
- new(env).run(regex)
5
- end
6
-
7
- def self.run_file_with_match(regex, env)
8
- new(env, pure_regex: true).run(regex)
9
- end
10
-
11
- attr_reader :regex, :repo, :shell, :test_runner
12
- def initialize(env, pure_regex: false)
13
- @repo = env[:repo]
14
- @shell = env[:shell]
15
- @test_runner = env[:test_runner]
16
- @pure_regex = pure_regex
17
- end
18
-
19
- def run(regex)
20
- @regex = regex
21
-
22
- if tests.empty?
23
- shell.notify "Could not find matching test method."
24
- return false
25
- elsif tests.size == 1
26
- if @pure_regex
27
- test_runner.run_files(tests)
28
- else
29
- test_runner.run_method(tests.first)
30
- end
31
- elsif tests.in_one_file?
32
- shell.notify "Multiple matches in same file. Running that file."
33
- test_runner.run_files(tests)
34
- elsif tests.in_one_engine? && tests.full_paths.size < 4 # hack: maybe should ask here?
35
- shell.notify "Multiple matches across files in same engine. Running those files."
36
- test_runner.run_files(tests)
37
- else
38
- shell.warn 'Found too many tests:'
39
- tests[0..10].each {|t| shell.notify "#{t.full_path}: #{t.test_name}" }
40
- shell.notify '...'
41
- exit
42
- end
43
- end
44
-
45
- def tests
46
- @test_collection ||= TestCollection.new(find_tests_by_name)
47
- end
48
-
49
- def find_tests_by_name
50
- test_def_regex = @pure_regex ? regex : "^\s*def .*#{regex}.*"
51
- begin
52
- return repo.grep(test_def_regex, file_pattern: '*_test.rb')
53
- rescue ShellRunner::CommandFailureError
54
- # git grep exits with 1 if no results
55
- return []
56
- end
57
- end
58
-
59
- end