safe_pusher 0.2.1 → 0.4.2

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
- SHA1:
3
- metadata.gz: 8dd851e29beb0acaa544597d36c9ba03c6ef4620
4
- data.tar.gz: b87276b61f21dfe2ec419ac90f7eaff97e7eb89d
2
+ SHA256:
3
+ metadata.gz: 5b35c0d67956c4dcd646f9766458d69524ca43b9fc0bfe44f316ca1e114d8b61
4
+ data.tar.gz: 959b5176de2e4a3fa97c449c684fc15c4e0c87bfa132efa6045b03b25a0c8ad6
5
5
  SHA512:
6
- metadata.gz: ce3fff993eaffda06bcc60c6a3a71f4ff798496157b9b350201af19a9fea34296fa419f6b257c1313709cd831885b1993c34b073be00a093174fb0859b20b326
7
- data.tar.gz: 2c8c6c017755eebe779459c981eceddaed229ea7c3338f03a91d79684b138e20d85942e05a35066e193f1d9ccebb895c854c50b44d81a1bcf0b84c435572d227
6
+ metadata.gz: ce2ca9a10f18e3a0f242fea8509c30310f2c040d8dc54ff5d91f65034ecfb9a1f28675624699285da5f1b8c9aabb03fa797d3cb8b805bf8dd27215798806baff
7
+ data.tar.gz: e17fcb0668567c566cff46cc8a4aff2b89c5537d2be983c27f27eb95fe11eabadaba96afaf32dbd099380555c6b3f15fd037101381d1ee1accd5890333d88fe0
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Screenshots**
24
+ If applicable, add screenshots to help explain your problem.
25
+
26
+ **Desktop (please complete the following information):**
27
+ - OS: [e.g. iOS]
28
+ - Browser [e.g. chrome, safari]
29
+ - Version [e.g. 22]
30
+
31
+ **Smartphone (please complete the following information):**
32
+ - Device: [e.g. iPhone6]
33
+ - OS: [e.g. iOS8.1]
34
+ - Browser [e.g. stock browser, safari]
35
+ - Version [e.g. 22]
36
+
37
+ **Additional context**
38
+ Add any other context about the problem here.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Is your feature request related to a problem? Please describe.**
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ **Describe the solution you'd like**
14
+ A clear and concise description of what you want to happen.
15
+
16
+ **Describe alternatives you've considered**
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ **Additional context**
20
+ Add any other context or screenshots about the feature request here.
@@ -63,10 +63,11 @@ Documentation:
63
63
  # Do not verify the length of the blocks in DSLs.
64
64
  Metrics/BlockLength:
65
65
  Exclude:
66
- - "**/*/spec/**/*"
66
+ - spec/**/*
67
67
  - lib/tasks/**/*
68
68
  - app/admin/**/*
69
69
  - config/routes.rb
70
+ - safe_pusher.gemspec
70
71
  ExcludedMethods:
71
72
  - included
72
73
 
@@ -136,27 +137,3 @@ Style/FormatStringToken:
136
137
  # Prefer `->` to `lambda`.
137
138
  Style/Lambda:
138
139
  EnforcedStyle: literal
139
-
140
- # Deactivate rule that makes `lambda` mandatory in defavor of `->`
141
- # when having blocks.
142
- Style/Lambda:
143
- Enabled: false
144
-
145
- # Do not verify empty lines around blocks in specs
146
- Layout/EmptyLinesAroundBlockBody:
147
- Exclude:
148
- - spec/**/*
149
-
150
- # Allow using normal test doubles, since they are useful for mocking.
151
- # See https://github.com/KissKissBankBank/fashion_police/pull/34
152
- RSpec/VerifiedDoubles:
153
- Enabled: false
154
-
155
- # Enable long blocs for Gemspec files
156
- Metrics/BlockLength:
157
- Exclude:
158
- - safe_pusher.gemspec
159
-
160
- Metrics/BlockLength:
161
- Exclude:
162
- - spec/**/*
@@ -1,8 +1,18 @@
1
1
  ---
2
+ env:
3
+ global:
4
+ - CC_TEST_REPORTER_ID=5e03a69363f26aba0c9c779a841db044295bf61762f9b7d719e2c064497f24e0
2
5
  sudo: false
3
6
  language: ruby
4
7
  cache: bundler
5
8
  rvm:
6
9
  - 2.3.7
7
10
  before_install: gem install bundler -v 1.16.3
11
+
12
+ before_script:
13
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
14
+ - chmod +x ./cc-test-reporter
15
+ - ./cc-test-reporter before-build
8
16
  script: bundle exec rspec spec
17
+ after_script:
18
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
@@ -2,6 +2,31 @@
2
2
 
3
3
  This project adheres to [Semantic Versioning](http://semver.org)
4
4
 
5
+ ## [0.4.2] - 2020-08-28
6
+ Fix:
7
+ - Do not inject the locales files directly in the load path but add them instead.
8
+
9
+ ## [0.4.1] - 2019-12-04
10
+ Improvement:
11
+ - Generate the folder of a spec, if not already existing
12
+
13
+ ## [0.4.0] - 2019-11-29
14
+ Features:
15
+ - Add `add`, `commit` and `amend` commands to the cli
16
+
17
+ ## [0.3.0] - 2019-09-30
18
+ Improvement:
19
+ - Reduce RSpec runner verbosity
20
+ - Allow configuring the base branch
21
+
22
+ Fix:
23
+ - Add `--version` to the CLI
24
+
25
+ ## [0.2.2] - 2019-01-05
26
+ Improvements:
27
+ - Removing thor
28
+ - Using custom CLI to handle multiple commands
29
+
5
30
  ## [0.2.1] - 2018-12-31
6
31
  Improvement:
7
32
  - Deprecating rainbow to install pronto and pronto Rubocop
@@ -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/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in safe_pusher.gemspec
6
6
  gemspec
data/README.md CHANGED
@@ -1,15 +1,18 @@
1
- # SafePusher
2
-
3
1
  [![Build Status](https://travis-ci.com/williampollet/safe_pusher.svg?branch=master)](https://travis-ci.com/williampollet/safe_pusher)
2
+ [![Maintainability](https://api.codeclimate.com/v1/badges/1aa6c275f9ce4d4c6ec3/maintainability)](https://codeclimate.com/github/williampollet/safe_pusher/maintainability)
3
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/1aa6c275f9ce4d4c6ec3/test_coverage)](https://codeclimate.com/github/williampollet/safe_pusher/test_coverage)
4
+
5
+ # SafePusher
4
6
 
5
- 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.
6
8
 
7
9
  ## Installation
8
10
 
9
- Add this line to your application's Gemfile:
11
+ Add these lines to your application's Gemfile:
10
12
 
11
13
  ```ruby
12
- gem 'safe_pusher'
14
+ # Lint and launch specs before pushing.
15
+ gem 'safe_pusher', require: false
13
16
  ```
14
17
 
15
18
  And then execute:
@@ -20,44 +23,109 @@ Or install it yourself as:
20
23
 
21
24
  $ gem install safe_pusher
22
25
 
23
-
24
26
  To use the gem fully, you should install [pronto](https://github.com/prontolabs/pronto) and [rspec](https://github.com/rspec/rspec) first.
25
27
 
26
28
  ## Configuration
27
29
 
28
- Generate the `binstubs` for `pronto` and `rspec`:
30
+ Generate the `binstubs` for `pronto`, `rspec` and `safepush`:
29
31
 
30
- $ bundler binstubs pronto
31
- $ bundler binstubs rspec-core
32
+ $ bundler binstubs pronto rspec-core safe_pusher
32
33
 
33
- create the `safe_pusher.yml` file at the root of your application
34
+ Create the `safe_pusher.yml` file at the root of your application:
34
35
 
35
36
  ```yaml
36
37
  files_to_skip:
37
38
  - file/to/skip_1
38
39
  - file/to/skip/2
40
+ base_branch: developement # default master
39
41
  app_base_directory: app
40
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
41
52
  ```
42
53
 
43
54
  ## Usage
44
-
45
55
  To see the commands available, type:
46
56
 
47
57
  $ safepush
48
58
 
49
- To run pronto checks before to push on github run:
59
+ To run pronto checks before you push to GitHub run:
60
+
61
+ $ safepush lint push open
50
62
 
51
- $ safepush ppush
63
+ or
52
64
 
53
- To run specs and pronto before to push on github run:
65
+ $ safepush l p o
54
66
 
55
- $ safepush ppushtest
67
+ To run specs and pronto before you push to GitHub run:
68
+
69
+ $ safepush test lint push open
70
+
71
+ or
72
+
73
+ $ safepush t l p o
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)
56
83
 
57
84
  ## Contributing
58
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
+
59
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.
60
102
 
103
+ ## Development
104
+
105
+ Setup development:
106
+
107
+ ```sh
108
+ $ bin/setup
109
+ ```
110
+
111
+ Open a console:
112
+
113
+ ```sh
114
+ $ bin/console
115
+ ```
116
+
117
+ Test the CLI:
118
+
119
+ ```sh
120
+ $ ruby -Ilib exe/safepush
121
+ ```
122
+
123
+ Launch specs and lint:
124
+
125
+ ```sh
126
+ $ rake
127
+ ```
128
+
61
129
  ## License
62
130
 
63
131
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  # Rspec
5
5
  RSpec::Core::RakeTask.new(:spec)
@@ -8,4 +8,4 @@ RSpec::Core::RakeTask.new(:spec)
8
8
  require 'rubocop/rake_task'
9
9
  RuboCop::RakeTask.new
10
10
 
11
- task :default => %i[spec, rubocop]
11
+ task default: %i[spec rubocop]
@@ -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,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'safe_pusher'
3
3
 
4
- SafePusher::CLI.start
4
+ SafePusher::CLI.new(arguments: ARGV).start
@@ -1,11 +1,19 @@
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/rspec_runner'
7
- require 'safe_pusher/pronto_runner'
8
- 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.config.available_locales = :en
16
+ I18n.load_path += Dir[File.expand_path('config/locales') + '/*.yml']
9
17
 
10
18
  module SafePusher
11
19
  # Configuration setup
@@ -1,91 +1,74 @@
1
1
  module SafePusher
2
- class CLI < Thor
3
- desc 'test (t)', 'launch the test suite'
4
- def test
5
- puts '##########################'.yellow
6
- puts '## Testing new files... ##'.yellow
7
- puts '##########################'.yellow
8
-
9
- results = SafePusher::RspecRunner.new.call
10
-
11
- exit results unless results == 0
2
+ class CLI
3
+ def initialize(arguments:)
4
+ @arguments = arguments
12
5
  end
13
- map 't' => :test
14
6
 
15
- desc 'lint (l)', 'launch the linters'
16
- def lint
17
- puts '#######################'.yellow
18
- puts '## Running linter... ##'.yellow
19
- puts '#######################'.yellow
7
+ def start
8
+ return version if arguments.first == '--version'
20
9
 
21
- results = SafePusher::ProntoRunner.new.call
10
+ help if commands.include?(nil)
22
11
 
23
- exit results unless results == 0
12
+ commands.compact.each { |command| execute_command(command) }
24
13
  end
25
- map 'l' => :lint
26
14
 
27
- desc 'push (p)', 'push your code on github'
28
- def push
29
- puts '##########################'.yellow
30
- puts '## Pushing to Github... ##'.yellow
31
- puts '##########################'.yellow
15
+ private
32
16
 
33
- results = SafePusher::GithubRunner.new.push
17
+ attr_reader :arguments
18
+
19
+ def execute_command(command)
20
+ explain(command) if verbose
21
+
22
+ results = SafePusher::Client
23
+ .const_get(services[command].capitalize)
24
+ .new
25
+ .public_send(command)
34
26
 
35
27
  exit results unless results == 0
36
28
  end
37
- map 'p' => :push
38
29
 
39
- desc 'open (o)', 'open a pull request on github'
40
- def open
41
- puts '#########################################'.yellow
42
- puts '## Opening a pull request on Github... ##'.yellow
43
- puts '#########################################'.yellow
30
+ def commands
31
+ @commands ||= arguments.map do |arg|
32
+ next unless arg =~ valid_commands_regexp
44
33
 
45
- results = SafePusher::GithubRunner.new.open
34
+ shortcut_to_command[arg] || arg
35
+ end
36
+ end
46
37
 
47
- exit results unless results == 0
38
+ def version
39
+ puts SafePusher::VERSION
48
40
  end
49
- map 'o' => :open
50
41
 
51
- desc 'push_and_open (po)', 'push your code on github,'\
52
- ' and open a Pull Request on Github if none is openned'
53
- def push_and_open
54
- puts '##########################'.yellow
55
- puts '## Pushing to Github... ##'.yellow
56
- puts '##########################'.yellow
42
+ def explain(command)
43
+ puts I18n.t("command.#{command}.verbose").yellow
44
+ end
57
45
 
58
- results = SafePusher::GithubRunner.new.push_and_open
46
+ def help
47
+ puts I18n.t('help')
48
+ end
59
49
 
60
- exit results unless results == 0
50
+ def valid_commands_regexp
51
+ @valid_commands_regexp ||= /^(?!\s*$)(?:#{available_commands})$/
61
52
  end
62
- map 'po' => :push_and_open
63
53
 
64
- desc 'test_and_lint (tl)',
65
- 'launch the test suite, then the linters if it is successful'
66
- def test_and_lint
67
- invoke :test
68
- invoke :lint
54
+ def available_commands
55
+ @available_commands ||= (
56
+ shortcut_to_command.keys + shortcut_to_command.values
57
+ ).join('|')
69
58
  end
70
- map 'tl' => :test_and_lint
71
-
72
- desc 'lint_push_and_open (lpo)',
73
- 'lanch the linters, then push on github and open a'\
74
- ' Pull Request on Github if none is openned'
75
- def lint_push_and_open
76
- invoke :lint
77
- invoke :push_and_open
59
+
60
+ def verbose
61
+ @verbose ||= SafePusher.configuration.verbose
78
62
  end
79
- map 'lpo' => :lint_push_and_open
80
-
81
- desc 'test_lint_push_and_open (tlpo)',
82
- 'lanch the linters, launch test suite, then push on github and open'\
83
- 'a Pull Request if none is openned'
84
- def test_lint_push_and_open
85
- invoke :test
86
- invoke :lint
87
- invoke :push_and_open
63
+
64
+ def services
65
+ @services ||= SafePusher.configuration.services
66
+ end
67
+
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) }
88
72
  end
89
- map 'tlpo' => :test_lint_push_and_open
90
73
  end
91
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,23 +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
- :repo_url
5
+ :repo_url,
6
+ :base_branch,
7
+ :verbose,
8
+ :services
9
9
 
10
10
  def initialize
11
- application_config =
12
- if File.exist?('safe_pusher.yml')
13
- YAML.load_file('safe_pusher.yml')
14
- else
15
- {}
16
- end
17
-
11
+ @verbose = application_config['verbose'] || true
12
+ @base_branch = application_config['base_branch'] || 'master'
18
13
  @files_to_skip = application_config['files_to_skip'] || []
19
14
  @app_base_directory = application_config['app_base_directory']
20
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
+ {}
21
32
  end
22
33
  end
23
34
  end
@@ -1,3 +1,3 @@
1
1
  module SafePusher
2
- VERSION = '0.2.1'.freeze
2
+ VERSION = '0.4.2'.freeze
3
3
  end
@@ -37,9 +37,9 @@ 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 'thor', '~> 0.19.4'
40
+ spec.add_dependency 'i18n', '~> 1.6.0'
41
41
 
42
- spec.add_development_dependency 'bundler', '~> 1.16'
42
+ spec.add_development_dependency 'bundler', '>= 1.16'
43
43
  spec.add_development_dependency 'fashion_police', '~> 1.2'
44
44
  spec.add_development_dependency 'pronto', '~> 0.9.5'
45
45
  spec.add_development_dependency 'pronto-rubocop', '~> 0.9.1'
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.2.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Pollet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-31 00:00:00.000000000 Z
11
+ date: 2020-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -25,31 +25,31 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.8.1
27
27
  - !ruby/object:Gem::Dependency
28
- name: thor
28
+ name: i18n
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.19.4
33
+ version: 1.6.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.19.4
40
+ version: 1.6.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.16'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.16'
55
55
  - !ruby/object:Gem::Dependency
@@ -186,6 +186,8 @@ executables:
186
186
  extensions: []
187
187
  extra_rdoc_files: []
188
188
  files:
189
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
190
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
189
191
  - ".gitignore"
190
192
  - ".hound.yml"
191
193
  - ".rspec"
@@ -193,19 +195,23 @@ files:
193
195
  - ".travis.yml"
194
196
  - CHANGELOG.md
195
197
  - CODE_OF_CONDUCT.md
198
+ - CONTRIBUTING.md
196
199
  - Gemfile
197
200
  - LICENSE.txt
198
201
  - README.md
199
202
  - Rakefile
200
203
  - bin/console
201
204
  - bin/setup
205
+ - config/commands.yml
206
+ - config/locales/en.yml
202
207
  - exe/safepush
203
208
  - lib/safe_pusher.rb
204
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
205
214
  - lib/safe_pusher/configuration.rb
206
- - lib/safe_pusher/github_runner.rb
207
- - lib/safe_pusher/pronto_runner.rb
208
- - lib/safe_pusher/rspec_runner.rb
209
215
  - lib/safe_pusher/version.rb
210
216
  - safe_pusher.gemspec
211
217
  homepage: https://github.com/williampollet/safe_pusher
@@ -228,8 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
234
  - !ruby/object:Gem::Version
229
235
  version: '0'
230
236
  requirements: []
231
- rubyforge_project:
232
- rubygems_version: 2.6.11
237
+ rubygems_version: 3.0.3
233
238
  signing_key:
234
239
  specification_version: 4
235
240
  summary: a small CLI that lints your code and run your tests before you push
@@ -1,44 +0,0 @@
1
- require 'colorize'
2
- require 'English'
3
-
4
- module SafePusher
5
- class GithubRunner
6
- def push_and_open
7
- push
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
-
18
- open if exit_status == 0
19
- end
20
-
21
- exit_status
22
- end
23
-
24
- def push
25
- system('git push origin')
26
- end
27
-
28
- def open
29
- system(
30
- "open '#{SafePusher.configuration.repo_url}/pull/new/#{branch}'",
31
- )
32
- end
33
-
34
- private
35
-
36
- def push_and_set_upstream
37
- system("git push --set-upstream origin #{branch}")
38
- end
39
-
40
- def branch
41
- `git rev-parse --symbolic-full-name --abbrev-ref HEAD`.delete("\n")
42
- end
43
- end
44
- end
@@ -1,26 +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 master!'.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')
24
- end
25
- end
26
- end
@@ -1,115 +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} master) #{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
- puts "#{file} has been modified, searching for specs..."
47
-
48
- spec_path = file.gsub(
49
- "#{SafePusher.configuration.app_base_directory}/",
50
- 'spec/',
51
- ).gsub('.rb', '_spec.rb')
52
-
53
- return create_new_spec(spec_path, file) unless File.exist?(spec_path)
54
-
55
- puts "Spec found for #{file}, putting #{spec_path}"\
56
- ' in the list of specs to run'
57
- specs_to_execute << spec_path
58
- end
59
-
60
- def index_file(file)
61
- puts "#{file} modified, putting it in the list of specs to run"
62
- specs_to_execute << file
63
- end
64
-
65
- def files_to_skip
66
- Regexp.new(
67
- SafePusher.configuration.files_to_skip.join('|').gsub('/', '\/'),
68
- )
69
- end
70
-
71
- def run_specs
72
- if specs_to_execute.empty?
73
- puts 'no spec analyzed, passing to the next step'.green
74
- return 0
75
- end
76
-
77
- system("bin/rspec #{specs_to_execute.join(' ')}")
78
-
79
- exit_status = $CHILD_STATUS.exitstatus
80
-
81
- if exit_status != 0
82
- puts 'Oops, a spec seems to be red or empty, '\
83
- 'be sure to complete it before you push'.red
84
- else
85
- puts 'Every spec operational, '\
86
- 'passing to the next step!'.green
87
- end
88
-
89
- exit_status
90
- end
91
-
92
- def create_new_spec(spec_path, file_matched)
93
- puts "no spec found for file #{file_matched},"\
94
- " would you like to add #{spec_path}? (Yn)"
95
- result = STDIN.gets.chomp
96
-
97
- if result.casecmp('n') == 0
98
- puts 'Alright, skipping the test for now!'
99
- return 0
100
- else
101
- File.open(spec_path, 'w') {}
102
- warn 'A spec needs to be written!'.red
103
- return 1
104
- end
105
- end
106
-
107
- def branch
108
- `git rev-parse --abbrev-ref HEAD`.delete("\n")
109
- end
110
-
111
- def app_base_directory
112
- %r{#{SafePusher.configuration.app_base_directory}\/.*\.rb$}
113
- end
114
- end
115
- end