safe_pusher 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c05663b02c0ccf6604a9e3054e8ea9456ffcb5694e25440db41edf4e087cb827
4
- data.tar.gz: edf3051adc55cd6492d35ae31f17c69f5444407e2f71a91a51239dad48f85f98
3
+ metadata.gz: ab33cda1facd75afc5f638e376520008a5ccd78ccfb12737d7518b4dbd65daf0
4
+ data.tar.gz: f654b9f9dbd1e5f1985f1c3d8e1f8ec40067f452bd88d9cc88fa2e3268fc7672
5
5
  SHA512:
6
- metadata.gz: d93caa5d43e32f373334afc458647266be8f4d505899d9f83c9ee23bfde83274c7f799b539630508818f11d708db84ffba46bd758989b4809c12031d79cd179c
7
- data.tar.gz: 88dff6746dbd6543e40152e856a5a0e6040bdf27eaaedaafe561805e435947e6d3aef472a93c64b9df7325c45c0dc85f9bd44b3d891e89c78d5a1f91279ce162
6
+ metadata.gz: c4f90a3d8ae6a56f485c041226b86127577465808d032fce4618cde458b9caf12e24341fb2b5010259841d89a6d8286493fe69afc9cd7fe5fa7cea9e9cdae61f
7
+ data.tar.gz: 7e1bfedcb25c89df9207752f1f9007d49facf1052d5b050ae5503dd924f838ad98ec27aeca46e8ec8eb88c63257f36e78a5582cb316329098e3833ca33e50948
@@ -2,6 +2,10 @@
2
2
 
3
3
  This project adheres to [Semantic Versioning](http://semver.org)
4
4
 
5
+ ## [0.4.1] - 2019-12-04
6
+ Improvement:
7
+ - Generate the folder of a spec, if not already existing
8
+
5
9
  ## [0.4.0] - 2019-11-29
6
10
  Features:
7
11
  - Add `add`, `commit` and `amend` commands to the cli
@@ -0,0 +1,33 @@
1
+ # Contributing
2
+
3
+ You can easily add a new client, or a new command.
4
+
5
+ ## To add a client
6
+ - create the client api under lib/safe_pusher/client/***.rb
7
+ - require it in lib/safe_pusher.rb
8
+ - write the specs for your client, then submit a PR
9
+
10
+ You will be able to specify in which command to use it, via the configuration !
11
+
12
+ ## To add a command
13
+ - configure your command and its client in config/commands.yml
14
+ - create your safepusher client api, as detailed above (if necessary)
15
+ - include your command's description in the help, in config/en.yml
16
+
17
+ # Guidelines
18
+
19
+ Bug reports and pull requests are welcome on GitHub at williampollet/safe_pusher. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
20
+
21
+ # Development
22
+ Setup development:
23
+ `$ bin/setup`
24
+
25
+ Open a console:
26
+ `$ bin/console`
27
+
28
+ Test the CLI:
29
+ `$ ruby -Ilib exe/safepush`
30
+
31
+ Launch specs and lint:
32
+
33
+ `$ rake`
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # SafePusher
6
6
 
7
- Run your favorite linters and specs on the files you touched, before pushing your branch.
7
+ Run your favorite linters and specs on the files you touched, before committing and pushing your branch.
8
8
 
9
9
  ## Installation
10
10
 
@@ -40,10 +40,18 @@ files_to_skip:
40
40
  base_branch: developement # default master
41
41
  app_base_directory: app
42
42
  repo_url: https://github.com/williampollet/safe_pusher
43
+ services:
44
+ test: rspec
45
+ lint: pronto
46
+ push: github
47
+ open: github
48
+ add: git
49
+ amend: git
50
+ commit: git
51
+ verbose: true
43
52
  ```
44
53
 
45
54
  ## Usage
46
-
47
55
  To see the commands available, type:
48
56
 
49
57
  $ safepush
@@ -64,8 +72,32 @@ or
64
72
 
65
73
  $ safepush t l p o
66
74
 
75
+ ### Available commands so far
76
+ - `test` (runs the tests only on the files you touched)
77
+ - `lint` (runs a linter only on the files you touched)
78
+ - `commit` (commit your changes)
79
+ - `add` (track your changes)
80
+ - `amend` (amend your tracked changes to your last commit)
81
+ - `push` (push and set upstream your local branch on github)
82
+ - `open` (open a pull request on github)
83
+
67
84
  ## Contributing
68
85
 
86
+ You can easily add a new client, or a new command.
87
+
88
+ ### To add a client
89
+ - create the client api under `lib/safe_pusher/client/***.rb`
90
+ - require it in `lib/safe_pusher.rb`
91
+ - write the specs for your client, then submit a PR
92
+ - You will be able to specify in which command to use it, via the configuration !
93
+
94
+ ### To add a command
95
+ - configure your command and its client in `config/commands.yml`
96
+ - create your safepusher client api, as detailed above (if necessary)
97
+ - include your command's description in the help, in `config/en.yml`
98
+
99
+ ### Guidelines
100
+
69
101
  Bug reports and pull requests are welcome on GitHub at https://github.com/williampollet/safe_pusher. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
70
102
 
71
103
  ## Development
@@ -0,0 +1,21 @@
1
+ test:
2
+ shortcut: t
3
+ default_client: rspec
4
+ lint:
5
+ shortcut: l
6
+ default_client: pronto
7
+ push:
8
+ shortcut: p
9
+ default_client: github
10
+ open:
11
+ shortcut: o
12
+ default_client: github
13
+ add:
14
+ shortcut: a
15
+ default_client: git
16
+ amend:
17
+ shortcut: m
18
+ default_client: git
19
+ commit:
20
+ shortcut: c
21
+ default_client: git
@@ -0,0 +1,37 @@
1
+ en:
2
+ help: |
3
+ Usage:
4
+ help (h) # show this usage message
5
+ --version # print SafePusher version
6
+ ##########################################################
7
+ # you can use any combination of theese commands
8
+ ##########################################################
9
+ test (t) # run the test suite
10
+ lint (l) # run the linters
11
+ amend (m) # amend your last commit
12
+ add (a) # add changes to be committed
13
+ commit (c) # commit your staged changes
14
+ push (p) # push on distant repository
15
+ open (o) # open a pull request on the distant repository
16
+ command:
17
+ add:
18
+ verbose: Testing new files...
19
+ commit:
20
+ verbose: Commiting last changes...
21
+ amend:
22
+ verbose: Amending last commit...
23
+ push:
24
+ verbose: Pushing to Github...
25
+ open:
26
+ verbose: Opening a pull request on Github...
27
+ lint:
28
+ verbose: Linting tracked changes...
29
+ test:
30
+ verbose: 'Testing new files...'
31
+ test_skipped: 'Alright, skipping the test for now!'
32
+ no_spec_found_for_file: 'No spec found for file %{file_matched}, would you like to add %{spec_path}? (Yn)'
33
+ spec_needs_to_be_written: 'A spec needs to be written!'
34
+ no_spec_analyzed: 'No spec found, going to the next step'
35
+ file_put_in_test_list: '%{file} modified, putting it in the list of specs to run'
36
+ spec_failing_or_missing: 'Oops, a spec seems to be red or empty, be sure to complete it before you push'
37
+ every_spec_operational: 'Every spec operational, going to the next step!'
@@ -1,12 +1,18 @@
1
1
  require 'safe_pusher/configuration'
2
2
  require 'thor'
3
3
  require 'colorize'
4
+ require 'English'
5
+ require 'i18n'
6
+ require 'yaml'
7
+ require 'fileutils'
4
8
  require 'safe_pusher/cli'
5
9
  require 'safe_pusher/version'
6
- require 'safe_pusher/git_runner'
7
- require 'safe_pusher/rspec_runner'
8
- require 'safe_pusher/pronto_runner'
9
- require 'safe_pusher/github_runner'
10
+ require 'safe_pusher/client/git'
11
+ require 'safe_pusher/client/rspec'
12
+ require 'safe_pusher/client/pronto'
13
+ require 'safe_pusher/client/github'
14
+
15
+ I18n.load_path << Dir[File.expand_path('config/locales/*.yml')]
10
16
 
11
17
  module SafePusher
12
18
  # Configuration setup
@@ -1,17 +1,5 @@
1
1
  module SafePusher
2
2
  class CLI
3
- SHORTCUTS = {
4
- 't' => 'test',
5
- 'l' => 'lint',
6
- 'p' => 'push',
7
- 'o' => 'open',
8
- 'm' => 'amend',
9
- 'a' => 'add',
10
- 'c' => 'commit',
11
- }.freeze
12
-
13
- private_constant :SHORTCUTS
14
-
15
3
  def initialize(arguments:)
16
4
  @arguments = arguments
17
5
  end
@@ -19,15 +7,9 @@ module SafePusher
19
7
  def start
20
8
  return version if arguments.first == '--version'
21
9
 
22
- unless arguments_valid?
23
- help
24
-
25
- return
26
- end
10
+ help if commands.include?(nil)
27
11
 
28
- arguments.each do |command|
29
- execute_command(command)
30
- end
12
+ commands.compact.each { |command| execute_command(command) }
31
13
  end
32
14
 
33
15
  private
@@ -35,111 +17,58 @@ module SafePusher
35
17
  attr_reader :arguments
36
18
 
37
19
  def execute_command(command)
38
- if SHORTCUTS[command]
39
- send(SHORTCUTS[command])
40
- else
41
- send(command)
42
- end
43
- end
44
-
45
- def test
46
- puts '##########################'.yellow
47
- puts '## Testing new files... ##'.yellow
48
- puts '##########################'.yellow
49
- results = SafePusher::RspecRunner.new.call
50
-
51
- exit results unless results == 0
52
- end
53
-
54
- def lint
55
- puts '#######################'.yellow
56
- puts '## Running linter... ##'.yellow
57
- puts '#######################'.yellow
20
+ explain(command) if verbose
58
21
 
59
- results = SafePusher::ProntoRunner.new.call
22
+ results = SafePusher::Client
23
+ .const_get(services[command].capitalize)
24
+ .new
25
+ .public_send(command)
60
26
 
61
27
  exit results unless results == 0
62
28
  end
63
29
 
64
- def push
65
- puts '##########################'.yellow
66
- puts '## Pushing to Github... ##'.yellow
67
- puts '##########################'.yellow
68
-
69
- results = SafePusher::GithubRunner.new.push
30
+ def commands
31
+ @commands ||= arguments.map do |arg|
32
+ next unless arg =~ valid_commands_regexp
70
33
 
71
- exit results unless results == 0
34
+ shortcut_to_command[arg] || arg
35
+ end
72
36
  end
73
37
 
74
- def amend
75
- puts '###################################'.yellow
76
- puts '## Amending your last commit... ###'.yellow
77
- puts '###################################'.yellow
78
-
79
- results = SafePusher::GitRunner.new.amend
80
-
81
- exit results unless results == 0
38
+ def version
39
+ puts SafePusher::VERSION
82
40
  end
83
41
 
84
- def add
85
- puts '######################'.yellow
86
- puts '## Adding files... ###'.yellow
87
- puts '######################'.yellow
88
-
89
- results = SafePusher::GitRunner.new.add
90
-
91
- exit results unless results == 0
42
+ def explain(command)
43
+ puts I18n.t("command.#{command}.verbose").yellow
92
44
  end
93
45
 
94
- def commit
95
- puts '################################'.yellow
96
- puts '## Commiting last changes... ###'.yellow
97
- puts '################################'.yellow
98
-
99
- results = SafePusher::GitRunner.new.commit
100
-
101
- exit results unless results == 0
46
+ def help
47
+ puts I18n.t('help')
102
48
  end
103
49
 
104
- def open
105
- puts '#########################################'.yellow
106
- puts '## Opening a pull request on Github... ##'.yellow
107
- puts '#########################################'.yellow
108
-
109
- results = SafePusher::GithubRunner.new.open
110
-
111
- exit results unless results == 0
50
+ def valid_commands_regexp
51
+ @valid_commands_regexp ||= /^(?!\s*$)(?:#{available_commands})$/
112
52
  end
113
53
 
114
- def arguments_valid?
115
- arguments.join(' ') =~ valid_commands_regexp
54
+ def available_commands
55
+ @available_commands ||= (
56
+ shortcut_to_command.keys + shortcut_to_command.values
57
+ ).join('|')
116
58
  end
117
59
 
118
- def valid_commands_regexp
119
- valid_commands = "#{SHORTCUTS.keys.join('|')}|"\
120
- "#{SHORTCUTS.values.join('|')}"
121
-
122
- /^(?!\s*$)(?:#{valid_commands}| )+$/
60
+ def verbose
61
+ @verbose ||= SafePusher.configuration.verbose
123
62
  end
124
63
 
125
- def help
126
- puts "Usage:\n"\
127
- " help (h) # show this usage message\n"\
128
- " --version # print SafePusher version\n"\
129
- " ##########################################################\n"\
130
- " # you can use any combination of theese commands \n"\
131
- " ##########################################################\n"\
132
- " test (t) # run the test suite\n"\
133
- " lint (l) # run the linters\n"\
134
- " amend (m) # amend your last commit \n"\
135
- " add (a) # add changes to be committed \n"\
136
- " commit (c) # commit your staged changes \n"\
137
- " push (p) # push on distant repository\n"\
138
- ' open (o) # open a pull request on the distant repository'
64
+ def services
65
+ @services ||= SafePusher.configuration.services
139
66
  end
140
67
 
141
- def version
142
- puts SafePusher::VERSION
68
+ def shortcut_to_command
69
+ @shortcut_to_command ||= YAML
70
+ .load_file('config/commands.yml')
71
+ .reduce({}) { |o, (k, v)| o.update(v['shortcut'] => k) }
143
72
  end
144
73
  end
145
74
  end
@@ -0,0 +1,27 @@
1
+ module SafePusher
2
+ module Client
3
+ class Git
4
+ def amend
5
+ system('git commit --amend')
6
+
7
+ $CHILD_STATUS.exitstatus
8
+ end
9
+
10
+ def add
11
+ system('git add --interactive')
12
+
13
+ $CHILD_STATUS.exitstatus
14
+ end
15
+
16
+ def commit
17
+ puts 'Enter a message for your commit:'
18
+
19
+ result = STDIN.gets.chomp
20
+
21
+ system("git commit -m '#{result}'")
22
+
23
+ $CHILD_STATUS.exitstatus
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ module SafePusher
2
+ module Client
3
+ class Github
4
+ def push
5
+ system('git push origin')
6
+
7
+ exit_status = $CHILD_STATUS.exitstatus
8
+
9
+ if exit_status == 128
10
+ puts 'Syncing with github...'.green
11
+
12
+ push_and_set_upstream
13
+
14
+ exit_status = $CHILD_STATUS.exitstatus
15
+ end
16
+
17
+ exit_status
18
+ end
19
+
20
+ def open
21
+ system(
22
+ "open '#{SafePusher.configuration.repo_url}/pull/new/#{branch}'",
23
+ )
24
+ end
25
+
26
+ private
27
+
28
+ def push_and_set_upstream
29
+ system("git push --set-upstream origin #{branch}")
30
+ end
31
+
32
+ def branch
33
+ `git rev-parse --symbolic-full-name --abbrev-ref HEAD`.delete("\n")
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ module SafePusher
2
+ module Client
3
+ class Pronto
4
+ def lint
5
+ run_pronto
6
+ exit_status = $CHILD_STATUS.exitstatus
7
+
8
+ if exit_status != 0
9
+ warn 'Pronto found somme errors… ' \
10
+ 'Fix them before pushing to GitHub!'.red
11
+ else
12
+ puts 'No errors found by pronto, go for next step!'.green
13
+ end
14
+
15
+ exit_status
16
+ end
17
+
18
+ private
19
+
20
+ def run_pronto
21
+ system("bin/pronto run --exit-code -c #{base_branch}")
22
+ end
23
+
24
+ def base_branch
25
+ SafePusher.configuration.base_branch
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,136 @@
1
+ module SafePusher
2
+ module Client
3
+ class Rspec
4
+ def initialize
5
+ @specs_to_execute = []
6
+ end
7
+
8
+ def test
9
+ return 1 if list_files_to_execute == 1
10
+
11
+ run_specs
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :specs_to_execute
17
+
18
+ def list_files_to_execute
19
+ modified_files.map do |f|
20
+ return 1 if analyze_file(f) == 1
21
+ end.compact
22
+ end
23
+
24
+ def modified_files
25
+ diff = 'git diff --diff-filter=A --diff-filter=M --name-only'
26
+
27
+ `#{diff} $(git merge-base #{branch} #{base_branch}) #{branch}`
28
+ .split("\n")
29
+ .uniq
30
+ end
31
+
32
+ def analyze_file(file)
33
+ if file.match(app_base_directory) &&
34
+ !file.match(files_to_skip)
35
+ search_or_create_spec(file)
36
+ elsif file.match(/spec/) &&
37
+ !specs_to_execute.include?(file) &&
38
+ !file.match(files_to_skip)
39
+ index_file(file)
40
+ end
41
+ end
42
+
43
+ def search_or_create_spec(file)
44
+ spec_path = file.gsub(
45
+ "#{SafePusher.configuration.app_base_directory}/",
46
+ 'spec/',
47
+ ).gsub('.rb', '_spec.rb')
48
+
49
+ return create_new_spec(spec_path, file) unless File.exist?(spec_path)
50
+
51
+ puts spec_path
52
+
53
+ specs_to_execute << spec_path
54
+ end
55
+
56
+ def index_file(file)
57
+ puts I18n.t('command.test.file_put_in_test_list', file: file)
58
+ specs_to_execute << file
59
+ end
60
+
61
+ def files_to_skip
62
+ Regexp.new(
63
+ SafePusher.configuration.files_to_skip.join('|').gsub('/', '\/'),
64
+ )
65
+ end
66
+
67
+ def run_specs
68
+ if specs_to_execute.empty?
69
+ puts I18n.t('command.test.no_spec_analyzed').green
70
+ return 0
71
+ end
72
+
73
+ system("bin/rspec #{specs_to_execute.join(' ')}")
74
+
75
+ exit_status = $CHILD_STATUS.exitstatus
76
+
77
+ if exit_status != 0
78
+ puts spec_failing_or_missing
79
+ else
80
+ puts every_spec_operational
81
+ end
82
+
83
+ exit_status
84
+ end
85
+
86
+ def create_new_spec(spec_path, file_matched)
87
+ puts I18n.t(
88
+ 'command.test.no_spec_found_for_file',
89
+ file_matched: file_matched,
90
+ spec_path: spec_path,
91
+ )
92
+
93
+ result = STDIN.gets.chomp
94
+
95
+ if result.casecmp('n') == 0
96
+ puts I18n.t('command.test.test_skipped')
97
+
98
+ 0
99
+ else
100
+ create_new_file(spec_path)
101
+
102
+ warn I18n.t('command.test.spec_needs_to_be_written').red
103
+
104
+ 1
105
+ end
106
+ end
107
+
108
+ def branch
109
+ `git rev-parse --abbrev-ref HEAD`.delete("\n")
110
+ end
111
+
112
+ def create_new_file(path)
113
+ parent_directory = File.dirname(path)
114
+
115
+ FileUtils.mkdir_p(parent_directory) unless File.exist?(parent_directory)
116
+ FileUtils.touch(path)
117
+ end
118
+
119
+ def app_base_directory
120
+ %r{#{SafePusher.configuration.app_base_directory}\/.*\.rb$}
121
+ end
122
+
123
+ def base_branch
124
+ SafePusher.configuration.base_branch
125
+ end
126
+
127
+ def spec_failing_or_missing
128
+ I18n.t('command.test.spec_failing_or_missing').red
129
+ end
130
+
131
+ def every_spec_operational
132
+ I18n.t('command.test.every_spec_operational').green
133
+ end
134
+ end
135
+ end
136
+ end
@@ -1,25 +1,34 @@
1
- require 'yaml'
2
- # Configuration variables and defaults
3
1
  module SafePusher
4
2
  class Configuration
5
- # The configuration singleton
6
3
  attr_accessor :files_to_skip,
7
4
  :app_base_directory,
8
5
  :repo_url,
9
- :base_branch
6
+ :base_branch,
7
+ :verbose,
8
+ :services
10
9
 
11
10
  def initialize
12
- application_config =
13
- if File.exist?('safe_pusher.yml')
14
- YAML.load_file('safe_pusher.yml')
15
- else
16
- {}
17
- end
18
-
11
+ @verbose = application_config['verbose'] || true
19
12
  @base_branch = application_config['base_branch'] || 'master'
20
13
  @files_to_skip = application_config['files_to_skip'] || []
21
14
  @app_base_directory = application_config['app_base_directory']
22
15
  @repo_url = application_config['repo_url']
16
+ @services = load_services
17
+ end
18
+
19
+ private
20
+
21
+ def load_services
22
+ YAML
23
+ .load_file('config/commands.yml')
24
+ .reduce({}) { |o, (k, v)| o.update(k => v['default_client']) }
25
+ .merge(application_config['services'] || {})
26
+ end
27
+
28
+ def application_config
29
+ return YAML.load_file('safe_pusher.yml') if File.exist?('safe_pusher.yml')
30
+
31
+ {}
23
32
  end
24
33
  end
25
34
  end
@@ -1,3 +1,3 @@
1
1
  module SafePusher
2
- VERSION = '0.4.0'.freeze
2
+ VERSION = '0.4.1'.freeze
3
3
  end
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.require_paths = ['lib']
38
38
 
39
39
  spec.add_dependency 'colorize', '~> 0.8.1'
40
+ spec.add_dependency 'i18n', '~> 1.6.0'
40
41
 
41
42
  spec.add_development_dependency 'bundler', '>= 1.16'
42
43
  spec.add_development_dependency 'fashion_police', '~> 1.2'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safe_pusher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Pollet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-29 00:00:00.000000000 Z
11
+ date: 2019-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.8.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: i18n
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.6.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.6.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -181,20 +195,23 @@ files:
181
195
  - ".travis.yml"
182
196
  - CHANGELOG.md
183
197
  - CODE_OF_CONDUCT.md
198
+ - CONTRIBUTING.md
184
199
  - Gemfile
185
200
  - LICENSE.txt
186
201
  - README.md
187
202
  - Rakefile
188
203
  - bin/console
189
204
  - bin/setup
205
+ - config/commands.yml
206
+ - config/locales/en.yml
190
207
  - exe/safepush
191
208
  - lib/safe_pusher.rb
192
209
  - lib/safe_pusher/cli.rb
210
+ - lib/safe_pusher/client/git.rb
211
+ - lib/safe_pusher/client/github.rb
212
+ - lib/safe_pusher/client/pronto.rb
213
+ - lib/safe_pusher/client/rspec.rb
193
214
  - lib/safe_pusher/configuration.rb
194
- - lib/safe_pusher/git_runner.rb
195
- - lib/safe_pusher/github_runner.rb
196
- - lib/safe_pusher/pronto_runner.rb
197
- - lib/safe_pusher/rspec_runner.rb
198
215
  - lib/safe_pusher/version.rb
199
216
  - safe_pusher.gemspec
200
217
  homepage: https://github.com/williampollet/safe_pusher
@@ -217,7 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
234
  - !ruby/object:Gem::Version
218
235
  version: '0'
219
236
  requirements: []
220
- rubygems_version: 3.0.4
237
+ rubygems_version: 3.0.6
221
238
  signing_key:
222
239
  specification_version: 4
223
240
  summary: a small CLI that lints your code and run your tests before you push
@@ -1,28 +0,0 @@
1
- require 'colorize'
2
- require 'English'
3
-
4
- module SafePusher
5
- class GitRunner
6
- def amend
7
- system('git commit --amend')
8
-
9
- $CHILD_STATUS.exitstatus
10
- end
11
-
12
- def add
13
- system('git add --interactive')
14
-
15
- $CHILD_STATUS.exitstatus
16
- end
17
-
18
- def commit
19
- puts 'Enter a message for your commit:'
20
-
21
- result = STDIN.gets.chomp
22
-
23
- system("git commit -m '#{result}'")
24
-
25
- $CHILD_STATUS.exitstatus
26
- end
27
- end
28
- end
@@ -1,38 +0,0 @@
1
- require 'colorize'
2
- require 'English'
3
-
4
- module SafePusher
5
- class GithubRunner
6
- def push
7
- system('git push origin')
8
-
9
- exit_status = $CHILD_STATUS.exitstatus
10
-
11
- if exit_status == 128
12
- puts 'Syncing with github...'.green
13
-
14
- push_and_set_upstream
15
-
16
- exit_status = $CHILD_STATUS.exitstatus
17
- end
18
-
19
- exit_status
20
- end
21
-
22
- def open
23
- system(
24
- "open '#{SafePusher.configuration.repo_url}/pull/new/#{branch}'",
25
- )
26
- end
27
-
28
- private
29
-
30
- def push_and_set_upstream
31
- system("git push --set-upstream origin #{branch}")
32
- end
33
-
34
- def branch
35
- `git rev-parse --symbolic-full-name --abbrev-ref HEAD`.delete("\n")
36
- end
37
- end
38
- end
@@ -1,30 +0,0 @@
1
- require 'colorize'
2
- require 'English'
3
-
4
- module SafePusher
5
- class ProntoRunner
6
- def call
7
- run_pronto
8
- exit_status = $CHILD_STATUS.exitstatus
9
-
10
- if exit_status != 0
11
- warn 'Pronto found somme errors… ' \
12
- 'Fix them before pushing to GitHub!'.red
13
- else
14
- puts 'No errors found by pronto, go for next step!'.green
15
- end
16
-
17
- exit_status
18
- end
19
-
20
- private
21
-
22
- def run_pronto
23
- system("bin/pronto run --exit-code -c #{base_branch}")
24
- end
25
-
26
- def base_branch
27
- SafePusher.configuration.base_branch
28
- end
29
- end
30
- end
@@ -1,117 +0,0 @@
1
- require 'colorize'
2
- require 'English'
3
-
4
- module SafePusher
5
- class RspecRunner
6
- def initialize
7
- @specs_to_execute = []
8
- end
9
-
10
- def call
11
- return 1 if list_files_to_execute == 1
12
-
13
- run_specs
14
- end
15
-
16
- private
17
-
18
- attr_reader :specs_to_execute
19
-
20
- def list_files_to_execute
21
- modified_files.map do |f|
22
- return 1 if analyze_file(f) == 1
23
- end.compact
24
- end
25
-
26
- def modified_files
27
- diff = 'git diff --diff-filter=A --diff-filter=M --name-only'
28
-
29
- `#{diff} $(git merge-base #{branch} #{base_branch}) #{branch}`
30
- .split("\n")
31
- .uniq
32
- end
33
-
34
- def analyze_file(file)
35
- if file.match(app_base_directory) &&
36
- !file.match(files_to_skip)
37
- search_or_create_spec(file)
38
- elsif file.match(/spec/) &&
39
- !specs_to_execute.include?(file) &&
40
- !file.match(files_to_skip)
41
- index_file(file)
42
- end
43
- end
44
-
45
- def search_or_create_spec(file)
46
- spec_path = file.gsub(
47
- "#{SafePusher.configuration.app_base_directory}/",
48
- 'spec/',
49
- ).gsub('.rb', '_spec.rb')
50
-
51
- return create_new_spec(spec_path, file) unless File.exist?(spec_path)
52
-
53
- puts spec_path
54
-
55
- specs_to_execute << spec_path
56
- end
57
-
58
- def index_file(file)
59
- puts "#{file} modified, putting it in the list of specs to run"
60
- specs_to_execute << file
61
- end
62
-
63
- def files_to_skip
64
- Regexp.new(
65
- SafePusher.configuration.files_to_skip.join('|').gsub('/', '\/'),
66
- )
67
- end
68
-
69
- def run_specs
70
- if specs_to_execute.empty?
71
- puts 'no spec analyzed, passing to the next step'.green
72
- return 0
73
- end
74
-
75
- system("bin/rspec #{specs_to_execute.join(' ')}")
76
-
77
- exit_status = $CHILD_STATUS.exitstatus
78
-
79
- if exit_status != 0
80
- puts 'Oops, a spec seems to be red or empty, '\
81
- 'be sure to complete it before you push'.red
82
- else
83
- puts 'Every spec operational, '\
84
- 'passing to the next step!'.green
85
- end
86
-
87
- exit_status
88
- end
89
-
90
- def create_new_spec(spec_path, file_matched)
91
- puts "no spec found for file #{file_matched},"\
92
- " would you like to add #{spec_path}? (Yn)"
93
- result = STDIN.gets.chomp
94
-
95
- if result.casecmp('n') == 0
96
- puts 'Alright, skipping the test for now!'
97
- return 0
98
- else
99
- File.open(spec_path, 'w') {}
100
- warn 'A spec needs to be written!'.red
101
- return 1
102
- end
103
- end
104
-
105
- def branch
106
- `git rev-parse --abbrev-ref HEAD`.delete("\n")
107
- end
108
-
109
- def app_base_directory
110
- %r{#{SafePusher.configuration.app_base_directory}\/.*\.rb$}
111
- end
112
-
113
- def base_branch
114
- SafePusher.configuration.base_branch
115
- end
116
- end
117
- end