safe_pusher 0.2.1 → 0.4.2

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
- 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