rails-dev-tools 1.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8521d4f1cf1ae2731589db49050da30beb1b71b857cb47ae132f7c62be024af5
4
+ data.tar.gz: e6f4994b5adcd9ab50e043b2c348b58af9ae5ba837e78bff2503454d7fe40a0f
5
+ SHA512:
6
+ metadata.gz: aae21b0b0c2df5aa30e51e3beadeb801a233d3311ea36806b4dedc8680131f28a19872a01d2fe1b976b32242564ee9a52d4bccad059983cd08642861cdda8a16
7
+ data.tar.gz: 550f75d96be2edb8003d97ad4fec13a392e09e32e6ca1e5caccb377e393f78480fc09ca7704cda0b0e014ad3eba917a04e23847c439926fdecd3c1995245a8d8
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2018 Francesco Ballardin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # Dev
2
+ This gem installs an executable command named `dev` which aims to help you develop and maintain Ruby or Ruby on Rails projects.
3
+
4
+ This gem takes inspiration from the Git Workflow published on [this page](https://nvie.com/posts/a-successful-git-branching-model/).
5
+
6
+ This gem can be used with mini Ruby projects composed of just one directory and a few files and at the same time with big Rails projects with many main apps and engines.
7
+
8
+ To work with big project, it is assumed that you organized your folders as follows:
9
+
10
+ ```bash
11
+ /path/to/project/ # Main project directory
12
+ /path/to/project/main_apps # Main apps directory
13
+ /path/to/project/main_apps/app1 # Main app 1
14
+ /path/to/project/main_apps/app2 # Main app 2
15
+ ...
16
+ /path/to/project/engines # Engines directory
17
+ /path/to/project/engines/engine1 # Engine 1
18
+ /path/to/project/engines/engine2 # Engine 2
19
+ ...
20
+ ```
21
+
22
+ ## Installation
23
+ Install with:
24
+ ```bash
25
+ $ gem install rails-dev-tools
26
+ ```
27
+
28
+ This will install an executable command named `dev`.
29
+
30
+ ## Usage
31
+ From the shell run:
32
+ ```
33
+ $ dev help
34
+ ```
35
+
36
+ To list all the available commands.
37
+
38
+ ## Commands
39
+
40
+ Usual git commands are `pull` and `push`. If you have a big project, this helps you pulling and pushing without moving from the current directory.
41
+
42
+ ### Pull
43
+
44
+ To pull data for a specific main app or engine:
45
+
46
+ ```bash
47
+ dev pull app1
48
+ dev pull engine2
49
+ ```
50
+
51
+ To pull data for all main apps and engines:
52
+ ```
53
+ dev pull
54
+ ```
55
+
56
+ ### Push
57
+
58
+ To push data for a specific main app or engine:
59
+
60
+ ```bash
61
+ dev push app1 "commit message"
62
+ dev push engine2 "commit message"
63
+ ```
64
+
65
+ ### Feature
66
+
67
+ If you want to start developing a new feature:
68
+ ```bash
69
+ dev feature open my-new-feat
70
+ ```
71
+
72
+ You will be placed on a new branch called `feature/my-new-feat`. Do all your work and then push it. After that, you can close your feature with:
73
+ ```bash
74
+ dev feature close my-new-feat
75
+ ```
76
+
77
+ This will merge the feature branch on the `develop` branch.
78
+
79
+ ### Release
80
+
81
+ When all your work into the develop branch is ready to become a new release, run:
82
+
83
+ ```bash
84
+ dev release open 0.2.0
85
+ ```
86
+
87
+ You will be placed on a new branch called `release/0.2.0`. You can work on this branch until it becomes stable and passes all tests. At this point commit and push your work and then run:
88
+ ```
89
+ dev release close 0.2.0
90
+ ```
91
+
92
+ This will merge the release branch on the `master` branch.
93
+
94
+ ### Hotfix
95
+
96
+ If you need to quickly fix a bug that accidentally made it to production, run:
97
+ ```bash
98
+ dev hotfix open 0.2.1
99
+ ```
100
+
101
+ You will be placed on a new branch called `hotfix/0.2.1`. While on this branch, write only code that fixes the bug(s) found. Do not start new features or continue developing existing ones. When you have fixed the bug run:
102
+ ```bash
103
+ dev hotfix close 0.2.1
104
+ ```
105
+
106
+ This will merge the hotfix branch on the `master` branch and on the `develop` branch.
107
+
108
+ ## License
109
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Dev'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ load 'rails/tasks/statistics.rake'
18
+
19
+ require 'bundler/gem_tasks'
20
+
21
+ require 'rake/testtask'
22
+
23
+ Rake::TestTask.new(:test) do |t|
24
+ t.libs << 'test'
25
+ t.pattern = 'test/**/*_test.rb'
26
+ t.verbose = false
27
+ end
28
+
29
+ task default: :test
File without changes
data/bin/dev ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'active_support/all'
4
+ require 'dev'
5
+
6
+ exec = Dev::Executable.new(*ARGV)
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
data/lib/dev.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'rainbow'
2
+
3
+ require 'dev/executable'
4
+ require 'dev/rainbow'
5
+ require 'dev/version'
6
+
7
+ module Dev
8
+
9
+ # Carica il file rainbow.rb per stampare a colori.
10
+ load "#{File.expand_path('..', __dir__)}/lib/dev/rainbow.rb"
11
+
12
+ end
data/lib/dev/engine.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Dev
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,205 @@
1
+ require 'open3'
2
+ require 'dev/project'
3
+ require 'dev/executables/commands/version'
4
+ require 'dev/executables/commands/status'
5
+ require 'dev/executables/commands/feature'
6
+ require 'dev/executables/commands/hotfix'
7
+ require 'dev/executables/commands/release'
8
+ require 'dev/executables/commands/pull'
9
+ require 'dev/executables/commands/push'
10
+ require 'dev/executables/commands/test'
11
+
12
+ module Dev
13
+
14
+ ##
15
+ # Classe per gestire l'esecuzione del comando +dev+.
16
+ class Executable
17
+
18
+ ##
19
+ # Definisce la classe per tutti gli errori interni
20
+ # all'esecuzione.
21
+ class ExecutionError < StandardError; end
22
+
23
+ include Dev::Executables::Commands::Version
24
+ include Dev::Executables::Commands::Status
25
+ include Dev::Executables::Commands::Feature
26
+ include Dev::Executables::Commands::Hotfix
27
+ include Dev::Executables::Commands::Release
28
+ include Dev::Executables::Commands::Pull
29
+ include Dev::Executables::Commands::Push
30
+ include Dev::Executables::Commands::Test
31
+
32
+ # @return [Dev::Executables::Project] il progetto di riferimento.
33
+ attr_accessor :project
34
+ # @return [StandardError] l'errore riscontrato, se presente.
35
+ attr_accessor :error
36
+ # @return [String] il backtrace dell'errore, se presente.
37
+ attr_accessor :backtrace
38
+
39
+ ##
40
+ # Inizializza l'eseguibile, in base al comando passato.
41
+ #
42
+ # @param [Array] argv gli argomenti del comando.
43
+ def initialize(*argv)
44
+ begin
45
+ if argv[0].present?
46
+ if self.respond_to?(argv[0])
47
+ # Carica i dati del progetto
48
+ load_project
49
+ # Lancia il comando passato
50
+ if self.method(argv[0]).arity.abs > 0
51
+ self.send(argv[0], *argv[1..-1])
52
+ else
53
+ self.send(argv[0])
54
+ end
55
+ else
56
+ raise ExecutionError.new "Command '#{argv[0]}' is not supported. Run "\
57
+ "'dev help' for a list of available commands."
58
+ end
59
+ else
60
+ raise ExecutionError.new "Missing required parameters. Run 'dev help' "\
61
+ "for a list of available commands."
62
+ end
63
+ rescue Dev::Executable::ExecutionError => e
64
+ @error = e.message
65
+ puts @error.red
66
+ rescue StandardError => e
67
+ @error = "#{e.class}: #{e.message}"
68
+ @backtrace = e.backtrace.join("\n")
69
+ puts @error.red
70
+ puts @backtrace.red
71
+ end
72
+ end
73
+
74
+ ##
75
+ # Carica i dati del progetto prendendoli dal file
76
+ # di configurazione del file 'dev.yml'.
77
+ #
78
+ # @return [nil]
79
+ def load_project
80
+ config_file = Dir.glob("#{Dir.pwd}/**/dev.yml").first
81
+ raise ExecutionError.new "No valid configuration files found. Searched for a file named 'dev.yml' "\
82
+ "in folder #{Dir.pwd} and all its subdirectories." if config_file.nil?
83
+ @project = Dev::Project.new(config_file)
84
+ end
85
+
86
+ ##
87
+ # Determina de l'env è valido.
88
+ #
89
+ # @return [Boolean] se l'env è fra quelli validi.
90
+ def valid_env?
91
+ unless @env.in? [ :production, :staging ]
92
+ raise ExecutionError.new "The environment '#{@env}' is not valid. "\
93
+ "Valid environments are 'production' or 'staging'."
94
+ else
95
+ true
96
+ end
97
+ end
98
+
99
+ ##
100
+ # Esegue un comando e cattura l'output ritornandolo come
101
+ # risultato di questo metodo. Si può passare l'opzione
102
+ # +flush+ per stampare subito l'output come se non fosse stato
103
+ # catturato.
104
+ #
105
+ # @param [String] command il comando da eseguire.
106
+ # @param [Hash] options le opzioni.
107
+ #
108
+ # @return [nil]
109
+ def exec(command, options = {})
110
+ out, err, status = Open3.capture3(command)
111
+ command_output = [ out.presence, err.presence ].compact.join("\n")
112
+ if options[:flush] == true
113
+ puts command_output
114
+ else
115
+ command_output
116
+ end
117
+ end
118
+
119
+ ##
120
+ # Stampa i comandi possibili.
121
+ #
122
+ # @return [nil]
123
+ def help
124
+ puts
125
+ print "Dev".green
126
+ print " - available commands:\n"
127
+ puts
128
+
129
+ print "\tversion\t\t".limegreen
130
+ print "Prints current version.\n"
131
+ puts
132
+
133
+ print "\tfeature\t\t".limegreen
134
+ print "Opens or closes a feature for the current app.\n"
135
+ print "\t\t\tWarning: the app is determined from the current working directory!\n"
136
+ print "\t\t\tExample: "
137
+ print "dev feature open my-new-feature".springgreen
138
+ print " (opens a new feature for the current app)"
139
+ print ".\n"
140
+ print "\t\t\tExample: "
141
+ print "dev feature close my-new-feature".springgreen
142
+ print " (closes a developed new feature for the current app)"
143
+ print ".\n"
144
+ puts
145
+
146
+ print "\thotfix\t\t".limegreen
147
+ print "Opens or closes a hotfix for the current app.\n"
148
+ print "\t\t\tWarning: the app is determined from the current working directory!\n"
149
+ print "\t\t\tExample: "
150
+ print "dev hotfix open 0.2.1".springgreen
151
+ print " (opens a new hotfix for the current app)"
152
+ print ".\n"
153
+ print "\t\t\tExample: "
154
+ print "dev hotfix close 0.2.1".springgreen
155
+ print " (closes a developed new hotfix for the current app)"
156
+ print ".\n"
157
+ puts
158
+
159
+ print "\trelease\t\t".limegreen
160
+ print "Opens or closes a release for the current app.\n"
161
+ print "\t\t\tWarning: the app is determined from the current working directory!\n"
162
+ print "\t\t\tExample: "
163
+ print "dev release open 0.2.0".springgreen
164
+ print " (opens a new release for the current app)"
165
+ print ".\n"
166
+ print "\t\t\tExample: "
167
+ print "dev release close 0.2.0".springgreen
168
+ print " (closes a developed new release for the current app)"
169
+ print ".\n"
170
+ puts
171
+
172
+ print "\tpull\t\t".limegreen
173
+ print "Pulls specified app's git repository, or pulls all apps if none are specified.\n"
174
+ print "\t\t\tWarning: the pulled branch is the one the app is currently on!\n"
175
+ print "\t\t\tExample: "
176
+ print "dev pull [myapp]".springgreen
177
+ print ".\n"
178
+ puts
179
+
180
+ print "\tpush\t\t".limegreen
181
+ print "Commits and pushes the specified app.\n"
182
+ print "\t\t\tWarning: the pushed branch is the one the app is currently on!\n"
183
+ print "\t\t\tExample: "
184
+ print "dev push myapp \"commit message\"".springgreen
185
+ print ".\n"
186
+ puts
187
+
188
+ print "\ttest\t\t".limegreen
189
+ print "Runs the app's test suite. Tests must be written with rspec.\n"
190
+ print "\t\t\tIt is possibile to specify which app's test suite to run.\n"
191
+ print "\t\t\tIf nothing is specified, all main app's test suites are run.\n"
192
+ print "\t\t\tExample: "
193
+ print "dev test mymainapp myengine".springgreen
194
+ print " (runs tests for 'mymainapp' and 'myengine')"
195
+ print ".\n"
196
+ print "\t\t\tExample: "
197
+ print "dev test".springgreen
198
+ print " (runs tests for all main apps and engines within this project)"
199
+ print ".\n"
200
+ puts
201
+ end
202
+
203
+ end
204
+
205
+ end
@@ -0,0 +1,111 @@
1
+ module Dev
2
+ module Executables
3
+ module Commands
4
+ module Feature
5
+
6
+ ##
7
+ # Comandi per gestire l'apertura e la chiusura di una nuova feature.
8
+ #
9
+ # @param [String] command il comando da eseguire.
10
+ # @param [String] name il nome della feature.
11
+ #
12
+ # @return [nil]
13
+ def feature(command = nil, name = nil)
14
+ raise Dev::Executable::ExecutionError.new "Wrong command syntax: "\
15
+ "specify whether to open or close a feature. "\
16
+ "Example: dev feature open my-new-feature" unless command.in? [ 'open', 'close' ]
17
+ name = name.to_s.squish
18
+
19
+ if @project.valid_app?
20
+ case command
21
+ when 'open' then feature_open(name)
22
+ when 'close' then feature_close(name)
23
+ end
24
+ end
25
+ end
26
+
27
+ ##
28
+ # Apre una nuova feature.
29
+ #
30
+ # @param [String] name il nome della feature.
31
+ #
32
+ # @return [nil]
33
+ def feature_open(name)
34
+ print "Preparing to open a new feature for app "
35
+ print @project.current_app.teal
36
+ print " named "
37
+ puts name.teal
38
+ puts
39
+
40
+ branches = `git branch -a`
41
+ unless branches.include? ("develop\n")
42
+ print "\tCreating develop branch.."
43
+ exec "git checkout -b develop"
44
+ exec "git add ."
45
+ exec "git commit -m \"Dev: automatically created 'develop' branch\""
46
+ exec "git push -u origin develop"
47
+ print "√\n".green
48
+ puts
49
+ end
50
+
51
+ print "\tOpening.. "
52
+ git_output = exec "git checkout -b feature/#{name} develop"
53
+ if git_output.include?('fatal') or git_output.include?('rejected') or git_output.include?('error')
54
+ print "X\n".red
55
+ puts "\t\tSomething went wrong, take a look at the output from git:".indianred
56
+ puts "\t\t#{git_output.split("\n").map(&:squish).join("\n\t\t")}".indianred
57
+ puts
58
+ else
59
+ print "√\n".green
60
+ puts "\t\tDone. Output from git:".cadetblue
61
+ puts "\t\t#{git_output.split("\n").map(&:squish).join("\n\t\t")}".cadetblue
62
+ puts
63
+ end
64
+ end
65
+
66
+ ##
67
+ # Chiude una feature esistente.
68
+ #
69
+ # @param [String] name il nome della feature.
70
+ #
71
+ # @return [nil]
72
+ def feature_close(name)
73
+ print "Preparing to close the feature for app "
74
+ print @project.current_app.teal
75
+ print " named "
76
+ puts name.teal
77
+ puts
78
+
79
+ status = `git status`
80
+ if status.include? "Changes not staged for commit:"
81
+ raise Dev::Executable::ExecutionError.new "Your current branch has unstaged changes. Please "\
82
+ "commit or stash them before closing the feature."
83
+ end
84
+
85
+ branches = `git branch -a`
86
+ unless branches.include? ("feature/#{name}\n")
87
+ raise Dev::Executable::ExecutionError.new "No feature named '#{name}' could be found "\
88
+ "for this app's repository."
89
+ end
90
+
91
+ print "\tClosing.. "
92
+ exec "git checkout develop"
93
+ exec "git merge --no-ff feature/#{name}"
94
+ git_output = exec "git push origin develop"
95
+ if git_output.include?('fatal') or git_output.include?('rejected') or git_output.include?('error')
96
+ print "X\n".red
97
+ puts "\t\tSomething went wrong, take a look at the output from git:".indianred
98
+ puts "\t\t#{git_output.split("\n").map(&:squish).join("\n\t\t")}".indianred
99
+ puts
100
+ else
101
+ print "√\n".green
102
+ puts "\t\tDone. Output from git:".cadetblue
103
+ puts "\t\t#{git_output.split("\n").map(&:squish).join("\n\t\t")}".cadetblue
104
+ puts
105
+ end
106
+ end
107
+
108
+ end
109
+ end
110
+ end
111
+ end