phlow 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +59 -0
- data/Rakefile +2 -0
- data/bin/phlow +46 -0
- data/lib/phlow/version.rb +3 -0
- data/lib/phlow.rb +171 -0
- data/phlow.gemspec +19 -0
- metadata +87 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Isa Goksu
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Phlow
|
2
|
+
|
3
|
+
Feature branching is awesome, but it has issues.. Some serious issues! This gem is just aiming to enhance it by creating a workflow around it to make it even work with CI tools like Teamcity, Jenkins, etc. Gem includes a command line wrapper utility around Git.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'phlow'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install phlow
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Just type:
|
22
|
+
|
23
|
+
$ phlow help
|
24
|
+
|
25
|
+
First of all, Git is not designed for Enterprise teams to work on a newly developed code base or an unstable codebase (unlike Linux kernel). This is just an attempt to ease that pain, but I'm underlining and making the next sentence bold. If you want to use Git in your Enterprise company, be careful and without having any workflow, don't even attempt to use Git blindly. I'll be publishing a white-paper soon around that. For the time being, you can email me for the details.
|
26
|
+
|
27
|
+
To have a successful Git workflow, I'm assuming you guys already have a central Git repository. If not, please use GitHub or GitLab. It'll reduce the pain a little bit. Let me try to explain how I expect you to work if you are adopting **Phlow**:
|
28
|
+
|
29
|
+
By default, **Phlow** will give you 4 branches. These are:
|
30
|
+
|
31
|
+
* master (origin/master)
|
32
|
+
* development (origin/development)
|
33
|
+
* operational (origin/operational)
|
34
|
+
* qa (origin/qa)
|
35
|
+
|
36
|
+
Let me explain the easy ones first! **Operational** branch is kind of a branch where you do your config changes, small library editions, updating a documentation etc. **QA** branch is for your QA work. Anything QA related goes into this branch. When I say QA, I'm more focusing on acceptance/load/performance testing. Nothing else. I believe unit, integration (contract) and functional (component) tests should be written by devs.
|
37
|
+
|
38
|
+
Keep in mind that above branches are not supposed to be manually merged to anywhere. **Phlow** will take care of it for you.
|
39
|
+
|
40
|
+
Now, let's get to the bottom of the real magic. Any time you want to work on a new topic/feature/story/bug/issue, you create a new branch for it by typing:
|
41
|
+
`phlow new my-awesome-feature`
|
42
|
+
|
43
|
+
Phlow will be creating a new branch for you with the necessary settings. You do your normal checkins into this branch. You can switch to another branch or feature any time and come back here using standard git commands. Just make sure that you are not messing anything by applying merging or rebasing (this includes pulls and fetches). If you do this, you are kinda beating the purpose of this gem. Basically, don't do it. Anyways, say you committed 3 checkins and now you want to send this changes to CI environment or other devs. All you need to do at this point is:
|
44
|
+
`phlow sync`
|
45
|
+
|
46
|
+
Phlow will take care of the rest for you. But bottom-line is, Phlow will sync everything over the **development** branch. Therefore your CI should run against **development** branch. This branch is nothing to be worried, all you will be seeing there is bunch of sync messages with feature names associated to them. The actual history will be fully kept in the master branch. Don't worry! You can sync as many as you want. Just remember, any conflicts on development branch, you gotta manually fix that (no merging back). Once you are done with your feature, just call your fellow colleague to review your changes. And if he is cool with it, then he can sign off to this feature by typing:
|
47
|
+
`phlow signoff my-awesome-feature`
|
48
|
+
|
49
|
+
As you as you sign off, all your history will be moved to master branch with no fast-forwarding.
|
50
|
+
|
51
|
+
Anyways, this is all for the time being. Keep in mind, **Phlow** is still in progress of development. We are actively using it every day and fine-tuning the problems. However, error-reporting mechanism is not that great yet. I'll be fixing that soon hopefully.
|
52
|
+
|
53
|
+
## Contributing
|
54
|
+
|
55
|
+
1. Fork it
|
56
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
57
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
58
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
59
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/phlow
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "phlow"
|
4
|
+
|
5
|
+
def print_usage
|
6
|
+
puts <<USAGE
|
7
|
+
|
8
|
+
Phlow v#{Phlow::VERSION}, your cute little Git workflow..
|
9
|
+
|
10
|
+
init <remote-repo> = Initialize a new repository with the default setup for given remote repository
|
11
|
+
new <feature> = Creates a new feature/bug branch with the given name
|
12
|
+
sync [continue|abort] = Syncs current branch with other users (pull & push)
|
13
|
+
signoff <feature> = Signs off to the given feature
|
14
|
+
version = Displays the version information
|
15
|
+
help = Displays this screen
|
16
|
+
|
17
|
+
USAGE
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
has_git = `which git`
|
22
|
+
if not $?.success?
|
23
|
+
puts "Please install Git first to continue.."
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
|
27
|
+
if ARGV.first
|
28
|
+
command, arg = ARGV.first, (ARGV.last unless ARGV.first == ARGV.last)
|
29
|
+
|
30
|
+
case command
|
31
|
+
when "init"
|
32
|
+
Phlow::init_repository arg
|
33
|
+
when "new"
|
34
|
+
Phlow::new_topic arg
|
35
|
+
when "sync"
|
36
|
+
Phlow::sync arg
|
37
|
+
when "signoff"
|
38
|
+
Phlow::signoff arg
|
39
|
+
when "version"
|
40
|
+
puts "Phlow, v#{Phlow::VERSION}"
|
41
|
+
else
|
42
|
+
print_usage
|
43
|
+
end
|
44
|
+
else
|
45
|
+
print_usage
|
46
|
+
end
|
data/lib/phlow.rb
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
require "phlow/version"
|
2
|
+
|
3
|
+
module Phlow
|
4
|
+
|
5
|
+
LICENSE = <<LICENSE
|
6
|
+
Copyright (c) #{Time.now.year}
|
7
|
+
|
8
|
+
MIT License
|
9
|
+
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
11
|
+
a copy of this software and associated documentation files (the
|
12
|
+
"Software"), to deal in the Software without restriction, including
|
13
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
14
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
15
|
+
permit persons to whom the Software is furnished to do so, subject to
|
16
|
+
the following conditions:
|
17
|
+
|
18
|
+
The above copyright notice and this permission notice shall be
|
19
|
+
included in all copies or substantial portions of the Software.
|
20
|
+
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
22
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
23
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
24
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
25
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
26
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
27
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
28
|
+
LICENSE
|
29
|
+
|
30
|
+
def self.init_repository(repo)
|
31
|
+
if repo.nil?
|
32
|
+
puts "Oops! Please specify a remote repository url!"
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
|
36
|
+
if not File.exists?(".git")
|
37
|
+
puts "Initializing the repo..."
|
38
|
+
result = `git clone #{repo} .`
|
39
|
+
end
|
40
|
+
|
41
|
+
if not File.exists?("LICENSE")
|
42
|
+
puts "Creating a license file..."
|
43
|
+
File.open("LICENSE", "w") {|f| f.write(LICENSE) }
|
44
|
+
|
45
|
+
puts "Committing for the first time..."
|
46
|
+
result = `git add -A && git commit -m 'First commit'`
|
47
|
+
end
|
48
|
+
|
49
|
+
puts "Creating necessary branches..."
|
50
|
+
result = `git push -u origin master &> /dev/null`
|
51
|
+
create_remote_branch 'development'
|
52
|
+
create_remote_branch 'operational'
|
53
|
+
create_remote_branch 'qa'
|
54
|
+
result = `git checkout master &> /dev/null`
|
55
|
+
|
56
|
+
puts "Done!"
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.new_topic(topic)
|
60
|
+
puts "Creating..."
|
61
|
+
result = `git pull &> /dev/null`
|
62
|
+
result = `git checkout -b #{topic} master &> /dev/null`
|
63
|
+
|
64
|
+
puts "#{topic} is ready for you to work on!"
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.sync(action)
|
68
|
+
puts "Syncing.."
|
69
|
+
result = `git status -s`
|
70
|
+
|
71
|
+
if result.nil?
|
72
|
+
puts "Please commit your changes first!"
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
|
76
|
+
feature = `echo $(git branch | grep "*" | sed "s/* //")`
|
77
|
+
|
78
|
+
# if there is no branch, it should just do the safe sync
|
79
|
+
if action.nil?
|
80
|
+
puts "Applying remote changes to the #{feature} branch..."
|
81
|
+
result = `git rebase master #{feature}`
|
82
|
+
if not $?.success?
|
83
|
+
puts result
|
84
|
+
exit 1
|
85
|
+
end
|
86
|
+
|
87
|
+
puts "Sending current changes..."
|
88
|
+
result = `git checkout development &> /dev/null`
|
89
|
+
result = `git pull`
|
90
|
+
result = `git merge --squash #{feature}`
|
91
|
+
if not $?.success?
|
92
|
+
puts result
|
93
|
+
exit 1
|
94
|
+
end
|
95
|
+
|
96
|
+
result = `git commit . -m '#{feature} syncing..' &> /dev/null`
|
97
|
+
|
98
|
+
sync_with_operational_branches 'development'
|
99
|
+
|
100
|
+
result = `git push -u origin development`
|
101
|
+
result = `git checkout #{feature} &> /dev/null`
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.signoff(feature)
|
106
|
+
if feature.nil?
|
107
|
+
puts "Please specify which feature you want to sign off!"
|
108
|
+
exit 1
|
109
|
+
end
|
110
|
+
|
111
|
+
print "Are you sure you want to sign off to #{feature}? Remember, this will delete the #{feature} [y/n]? "
|
112
|
+
answer = STDIN.gets.chomp
|
113
|
+
|
114
|
+
if answer.downcase == 'y' or answer.downcase == 'yes'
|
115
|
+
puts "Signing off [ #{feature} ]..."
|
116
|
+
print "Signee: "
|
117
|
+
signee = STDIN.gets.chomp
|
118
|
+
|
119
|
+
if signee.length < 5
|
120
|
+
puts "Please enter a valid name!"
|
121
|
+
exit 1
|
122
|
+
end
|
123
|
+
|
124
|
+
result = `git checkout master &> /dev/null`
|
125
|
+
result = `git pull &> /dev/null`
|
126
|
+
result = `git rebase master #{feature}`
|
127
|
+
result = `git checkout master &> /dev/null`
|
128
|
+
result = `git merge --no-ff #{feature} -m '#{feature} is signed off by #{signee}'`
|
129
|
+
if not $?.success?
|
130
|
+
puts result
|
131
|
+
exit 1
|
132
|
+
end
|
133
|
+
|
134
|
+
sync_with_operational_branches 'master'
|
135
|
+
result = `git branch -d #{feature}`
|
136
|
+
result = `git push -u origin master`
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def self.create_remote_branch(name)
|
143
|
+
result = `git checkout -b #{name} master &> /dev/null`
|
144
|
+
result = `git push -u origin #{name} &> /dev/null`
|
145
|
+
|
146
|
+
if not $?.success?
|
147
|
+
result = `git pull &> /dev/null`
|
148
|
+
result = `git branch #{name} --set-upstream origin/#{name} &> /dev/null`
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.sync_with_operational_branches(branch)
|
153
|
+
result = `git pull origin &> /dev/null`
|
154
|
+
result = `git checkout operational &> /dev/null`
|
155
|
+
result = `git checkout qa &> /dev/null`
|
156
|
+
|
157
|
+
result = `git checkout #{branch} &> /dev/null`
|
158
|
+
result = `git merge --no-ff operational`
|
159
|
+
if not $?.success?
|
160
|
+
puts result
|
161
|
+
exit 1
|
162
|
+
end
|
163
|
+
|
164
|
+
result = `git merge --no-ff qa`
|
165
|
+
if not $?.success?
|
166
|
+
puts result
|
167
|
+
exit 1
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
data/phlow.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/phlow/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Isa Goksu"]
|
6
|
+
gem.email = ["isa.goksu@gmail.com"]
|
7
|
+
gem.description = %q{A custom git workflow that actually works with CI environment}
|
8
|
+
gem.summary = %q{Git-flow is awesome, this gem is just enhancing the workflow to make it work with CI tools like Teamcity, Jenkins, etc. Gem includes bunch of command line wrapper utilities around Git.}
|
9
|
+
gem.homepage = "https://github.com/isa/phlow"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "phlow"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Phlow::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency('rspec')
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: phlow
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 3
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 7
|
9
|
+
- 0
|
10
|
+
version: 0.7.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Isa Goksu
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-05-15 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
description: A custom git workflow that actually works with CI environment
|
35
|
+
email:
|
36
|
+
- isa.goksu@gmail.com
|
37
|
+
executables:
|
38
|
+
- phlow
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
46
|
+
- LICENSE
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- bin/phlow
|
50
|
+
- lib/phlow.rb
|
51
|
+
- lib/phlow/version.rb
|
52
|
+
- phlow.gemspec
|
53
|
+
homepage: https://github.com/isa/phlow
|
54
|
+
licenses: []
|
55
|
+
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
hash: 3
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.8.23
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: Git-flow is awesome, this gem is just enhancing the workflow to make it work with CI tools like Teamcity, Jenkins, etc. Gem includes bunch of command line wrapper utilities around Git.
|
86
|
+
test_files: []
|
87
|
+
|