buildr 1.3.3-java → 1.3.4-java
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +76 -0
- data/NOTICE +1 -1
- data/README.rdoc +9 -21
- data/Rakefile +17 -34
- data/_buildr +3 -12
- data/{doc/print.toc.yaml → _jbuildr} +14 -14
- data/addon/buildr/cobertura.rb +5 -219
- data/addon/buildr/drb.rb +281 -0
- data/addon/buildr/emma.rb +5 -221
- data/addon/buildr/nailgun.rb +93 -689
- data/bin/buildr +0 -9
- data/buildr.buildfile +4 -4
- data/buildr.gemspec +27 -21
- data/doc/_layouts/default.html +82 -0
- data/doc/_layouts/preface.html +22 -0
- data/doc/{pages/artifacts.textile → artifacts.textile} +82 -42
- data/doc/{pages/building.textile → building.textile} +89 -47
- data/doc/{pages/contributing.textile → contributing.textile} +53 -45
- data/doc/css/default.css +6 -5
- data/doc/css/print.css +17 -24
- data/doc/css/syntax.css +7 -36
- data/doc/download.textile +68 -0
- data/doc/{pages/extending.textile → extending.textile} +45 -24
- data/doc/{pages/getting_started.textile → getting_started.textile} +158 -88
- data/doc/images/asf-logo.gif +0 -0
- data/doc/images/note.png +0 -0
- data/doc/index.textile +47 -0
- data/doc/{pages/languages.textile → languages.textile} +108 -54
- data/doc/mailing_lists.textile +25 -0
- data/doc/{pages/more_stuff.textile → more_stuff.textile} +152 -73
- data/doc/{pages/packaging.textile → packaging.textile} +181 -96
- data/doc/preface.textile +28 -0
- data/doc/{pages/projects.textile → projects.textile} +55 -40
- data/doc/scripts/buildr-git.rb +364 -264
- data/doc/scripts/gitflow.rb +296 -0
- data/doc/scripts/install-jruby.sh +2 -2
- data/doc/scripts/install-linux.sh +6 -6
- data/doc/scripts/install-osx.sh +2 -2
- data/doc/{pages/settings_profiles.textile → settings_profiles.textile} +83 -45
- data/doc/{pages/testing.textile → testing.textile} +77 -41
- data/lib/buildr.rb +5 -5
- data/lib/buildr/core.rb +2 -0
- data/lib/buildr/core/application.rb +321 -151
- data/lib/buildr/core/build.rb +298 -167
- data/lib/buildr/core/checks.rb +4 -132
- data/lib/buildr/core/common.rb +1 -5
- data/lib/buildr/core/compile.rb +3 -9
- data/lib/buildr/core/environment.rb +12 -3
- data/lib/buildr/core/filter.rb +20 -18
- data/lib/buildr/core/generate.rb +36 -36
- data/lib/buildr/core/help.rb +2 -1
- data/lib/buildr/core/osx.rb +46 -0
- data/lib/buildr/core/progressbar.rb +1 -1
- data/lib/buildr/core/project.rb +7 -34
- data/lib/buildr/core/test.rb +12 -6
- data/lib/buildr/core/transports.rb +13 -11
- data/lib/buildr/core/util.rb +14 -23
- data/lib/buildr/groovy/bdd.rb +3 -2
- data/lib/buildr/groovy/compiler.rb +1 -1
- data/lib/buildr/ide/eclipse.rb +31 -21
- data/lib/buildr/ide/idea.rb +3 -2
- data/lib/buildr/ide/idea7x.rb +6 -4
- data/lib/buildr/java/ant.rb +3 -1
- data/lib/buildr/java/bdd.rb +9 -7
- data/lib/buildr/java/cobertura.rb +243 -0
- data/lib/buildr/java/compiler.rb +5 -4
- data/lib/buildr/java/emma.rb +244 -0
- data/lib/buildr/java/packaging.rb +11 -8
- data/lib/buildr/java/pom.rb +0 -4
- data/lib/buildr/java/rjb.rb +1 -1
- data/lib/buildr/java/test_result.rb +5 -7
- data/lib/buildr/java/tests.rb +17 -11
- data/lib/buildr/packaging.rb +5 -2
- data/lib/buildr/packaging/archive.rb +488 -0
- data/lib/buildr/packaging/artifact.rb +48 -29
- data/lib/buildr/packaging/artifact_namespace.rb +6 -6
- data/lib/buildr/packaging/gems.rb +4 -4
- data/lib/buildr/packaging/package.rb +3 -2
- data/lib/buildr/packaging/tar.rb +85 -3
- data/lib/buildr/packaging/version_requirement.rb +172 -0
- data/lib/buildr/packaging/zip.rb +24 -682
- data/lib/buildr/packaging/ziptask.rb +313 -0
- data/lib/buildr/scala.rb +5 -0
- data/lib/buildr/scala/bdd.rb +100 -0
- data/lib/buildr/scala/compiler.rb +45 -4
- data/lib/buildr/scala/tests.rb +12 -59
- data/rakelib/checks.rake +57 -0
- data/rakelib/doc.rake +58 -68
- data/rakelib/jekylltask.rb +110 -0
- data/rakelib/package.rake +35 -37
- data/rakelib/release.rake +119 -35
- data/rakelib/rspec.rake +29 -39
- data/rakelib/setup.rake +21 -59
- data/rakelib/stage.rake +184 -26
- data/spec/addon/drb_spec.rb +328 -0
- data/spec/core/application_spec.rb +32 -25
- data/spec/core/build_spec.rb +336 -126
- data/spec/core/checks_spec.rb +292 -310
- data/spec/core/common_spec.rb +8 -2
- data/spec/core/compile_spec.rb +17 -1
- data/spec/core/generate_spec.rb +3 -3
- data/spec/core/project_spec.rb +18 -10
- data/spec/core/test_spec.rb +8 -1
- data/spec/core/transport_spec.rb +40 -3
- data/spec/core/util_spec.rb +67 -0
- data/spec/ide/eclipse_spec.rb +96 -28
- data/spec/ide/idea7x_spec.rb +84 -0
- data/spec/java/ant.rb +5 -0
- data/spec/java/bdd_spec.rb +12 -3
- data/spec/{addon → java}/cobertura_spec.rb +6 -6
- data/spec/{addon → java}/emma_spec.rb +5 -6
- data/spec/java/java_spec.rb +12 -2
- data/spec/java/packaging_spec.rb +31 -2
- data/spec/{addon → java}/test_coverage_spec.rb +3 -3
- data/spec/java/tests_spec.rb +5 -0
- data/spec/packaging/archive_spec.rb +11 -1
- data/spec/{core → packaging}/artifact_namespace_spec.rb +10 -2
- data/spec/packaging/artifact_spec.rb +44 -3
- data/spec/packaging/packaging_spec.rb +1 -1
- data/spec/sandbox.rb +17 -14
- data/spec/scala/bdd_spec.rb +150 -0
- data/spec/scala/compiler_spec.rb +27 -0
- data/spec/scala/scala.rb +38 -0
- data/spec/scala/tests_spec.rb +78 -33
- data/spec/spec_helpers.rb +29 -5
- data/spec/version_requirement_spec.rb +6 -0
- metadata +176 -172
- data/DISCLAIMER +0 -7
- data/doc/images/apache-incubator-logo.png +0 -0
- data/doc/pages/download.textile +0 -51
- data/doc/pages/index.textile +0 -42
- data/doc/pages/mailing_lists.textile +0 -17
- data/doc/pages/recipes.textile +0 -103
- data/doc/pages/troubleshooting.textile +0 -103
- data/doc/pages/whats_new.textile +0 -323
- data/doc/print.haml +0 -51
- data/doc/site.haml +0 -56
- data/doc/site.toc.yaml +0 -47
- data/etc/git-svn-authors +0 -16
- data/lib/buildr/core/application_cli.rb +0 -139
- data/rakelib/apache.rake +0 -191
- data/rakelib/changelog.rake +0 -57
- data/rakelib/rubyforge.rake +0 -53
- data/rakelib/scm.rake +0 -49
data/doc/preface.textile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
layout: preface
|
3
|
+
---
|
4
|
+
|
5
|
+
div(title). !{width:20em}images/buildr-hires.png!
|
6
|
+
|
7
|
+
#(toc) "Getting Started":getting_started.html
|
8
|
+
# "Projects":projects.html
|
9
|
+
# "Building":building.html
|
10
|
+
# "Artifacts":artifacts.html
|
11
|
+
# "Packaging":packaging.html
|
12
|
+
# "Testing":testing.html
|
13
|
+
# "Settings & Profiles":settings_profiles.html
|
14
|
+
# "Languages":languages.html
|
15
|
+
# "More Stuff":more_stuff.html
|
16
|
+
# "Extending Buildr":extending.html
|
17
|
+
# "Contributing":contributing.html
|
18
|
+
|
19
|
+
|
20
|
+
p(preface). Copyright 2007-2009 Apache Buildr
|
21
|
+
|
22
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
23
|
+
|
24
|
+
"http://www.apache.org/licenses/LICENSE-2.0":http://www.apache.org/licenses/LICENSE-2.0
|
25
|
+
|
26
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
27
|
+
|
28
|
+
p(preface). <blank>
|
@@ -1,6 +1,10 @@
|
|
1
|
-
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Projects
|
4
|
+
---
|
2
5
|
|
3
|
-
|
6
|
+
|
7
|
+
h2(#starting). Starting Out
|
4
8
|
|
5
9
|
In Java, most projects are built the same way: compile source code, run test cases, package the code, release it. Rinse, repeat.
|
6
10
|
|
@@ -8,16 +12,17 @@ Feed it a project definition, and Buildr will set up all these tasks for you. Th
|
|
8
12
|
|
9
13
|
The remainder of this guide deals with what it takes to build a project. But first, let's pick up a sample project to work with. We'll call it _killer-app_:
|
10
14
|
|
11
|
-
|
15
|
+
<notextile>
|
16
|
+
{% highlight ruby %}
|
12
17
|
require 'buildr'
|
13
18
|
|
14
19
|
VERSION_NUMBER = '1.0'
|
15
20
|
|
16
21
|
AXIS2 = 'org.apache.axis2:axis2:jar:1.2'
|
17
|
-
AXIOM
|
22
|
+
AXIOM = group('axiom-api', 'axiom-impl', 'axiom-dom',
|
18
23
|
:under=>'org.apache.ws.commons.axiom', :version=>'1.2.4')
|
19
24
|
AXIS_OF_WS = [AXIOM, AXIS2]
|
20
|
-
OPENJPA = ['org.apache.openjpa:openjpa
|
25
|
+
OPENJPA = ['org.apache.openjpa:openjpa:jar:1.2.0',
|
21
26
|
'net.sourceforge.serp:serp:jar:1.12.0']
|
22
27
|
|
23
28
|
repositories.remote << 'http://www.ibiblio.org/maven2/'
|
@@ -44,7 +49,7 @@ define 'killer-app' do
|
|
44
49
|
|
45
50
|
desc 'What our users see'
|
46
51
|
define 'la-web' do
|
47
|
-
test.
|
52
|
+
test.with AXIS_OF_WS
|
48
53
|
package(:war).with :libs=>projects('teh-api', 'teh-impl')
|
49
54
|
end
|
50
55
|
|
@@ -52,14 +57,15 @@ define 'killer-app' do
|
|
52
57
|
package :javadoc
|
53
58
|
|
54
59
|
end
|
55
|
-
}
|
60
|
+
{% endhighlight %}
|
61
|
+
</notextile>
|
56
62
|
|
57
63
|
A project definition requires four pieces of information: the project name, group identifier, version number and base directory. The project name ... do we need to explain why its necessary? The group identifier and version number are used for packaging and deployment, we'll talk more about that in the "Packaging":packaging.html section. The base directory lets you find files inside the project.
|
58
64
|
|
59
65
|
Everything else depends on what that particular project is building. And it all goes inside the project definition block, the piece of code that comes between @define <name> .. do@ and @end@.
|
60
66
|
|
61
67
|
|
62
|
-
h2. The Directory Structure
|
68
|
+
h2(#dir_structure). The Directory Structure
|
63
69
|
|
64
70
|
Buildr follows a convention we picked from years of working with Apache projects.
|
65
71
|
|
@@ -84,7 +90,7 @@ And yes, you can have two top projects in the same Buildfile. For example, you
|
|
84
90
|
When you start with a new project you won't see the @target@ or @reports@ directories. Buildr creates these when it needs to. Just know that they're there.
|
85
91
|
|
86
92
|
|
87
|
-
h2. Naming And Finding Projects
|
93
|
+
h2(#naming). Naming And Finding Projects
|
88
94
|
|
89
95
|
Each project has a given name, the first argument you pass when calling @define@. The project name is just a string, but we advise to stay clear of colon (@:@) and slashes (@/@ and @\@), which could conflict with other task and file names. Also, avoid using common Buildr task names, don't pick @compile@ or @build@ for your project name.
|
90
96
|
|
@@ -96,7 +102,8 @@ The @projects@ method takes a list of names and returns a list of projects. If
|
|
96
102
|
|
97
103
|
Let's illustrate this with a few examples:
|
98
104
|
|
99
|
-
|
105
|
+
<notextile>
|
106
|
+
{% highlight ruby %}
|
100
107
|
puts projects.inspect
|
101
108
|
=> [project("killer-app"), project("killer-app:teh-api") ... ]
|
102
109
|
|
@@ -111,20 +118,18 @@ puts project('killer-app:teh-api').inspect
|
|
111
118
|
|
112
119
|
puts project('killer-app').project('teh-api').inspect
|
113
120
|
=> project("killer-app:teh-api")
|
114
|
-
}
|
115
|
-
|
116
|
-
To see a list of all projects defined in your Buildfile:
|
121
|
+
{% endhighlight %}
|
122
|
+
</notextile>
|
117
123
|
|
118
|
-
|
119
|
-
$ buildr help:projects
|
120
|
-
}}}
|
124
|
+
To see a list of all projects defined in your Buildfile run @buildr help:projects@.
|
121
125
|
|
122
126
|
|
123
|
-
h2. Running Project Tasks
|
127
|
+
h2(#tasks). Running Project Tasks
|
124
128
|
|
125
129
|
Most times, you run tasks like @build@ or @package@ that operate on the current project and recursively on its sub-projects. The "current project" is the one that uses the current working directory. So if you're in the @la-web/src@ directory looking at source files, _la-web_ is the current project. For example:
|
126
130
|
|
127
|
-
|
131
|
+
<notextile>
|
132
|
+
{% highlight sh %}
|
128
133
|
# build killer-app and all its sub-projects
|
129
134
|
$ buildr build
|
130
135
|
|
@@ -135,11 +140,13 @@ $ buildr test
|
|
135
140
|
# switch to and package only la-web
|
136
141
|
$ cd ../la-web
|
137
142
|
$ buildr package
|
138
|
-
}
|
143
|
+
{% endhighlight %}
|
144
|
+
</notextile>
|
139
145
|
|
140
146
|
You can use the project's full name to invoke one of its tasks directly, and it doesn't matter which directory you're in. For example:
|
141
147
|
|
142
|
-
|
148
|
+
<notextile>
|
149
|
+
{% highlight sh %}
|
143
150
|
# build killer-app and all its sub-projects
|
144
151
|
$ buildr killer-app:build
|
145
152
|
|
@@ -148,11 +155,13 @@ $ buildr killer-app:teh-impl:test
|
|
148
155
|
|
149
156
|
# package only la-web
|
150
157
|
$ buildr killer-app:la-web:package
|
151
|
-
}
|
158
|
+
{% endhighlight %}
|
159
|
+
</notextile>
|
152
160
|
|
153
161
|
Buildr provides the following tasks that you can run on the current project, or on a specific project by prefixing them with the project's full name:
|
154
162
|
|
155
|
-
|
163
|
+
<notextile>
|
164
|
+
{% highlight text %}
|
156
165
|
clean # Clean files generated during a build
|
157
166
|
compile # Compile all projects
|
158
167
|
build # Build the project
|
@@ -162,21 +171,20 @@ javadoc # Create the Javadocs for this project
|
|
162
171
|
package # Create packages
|
163
172
|
test # Run all test cases
|
164
173
|
uninstall # Remove previously installed packages
|
165
|
-
}
|
174
|
+
{% endhighlight %}
|
175
|
+
</notextile>
|
166
176
|
|
167
|
-
To see a list of all the tasks provided by Buildr:
|
177
|
+
To see a list of all the tasks provided by Buildr run @buildr help:tasks@.
|
168
178
|
|
169
|
-
{{{!sh
|
170
|
-
$ buildr help:tasks
|
171
|
-
}}}
|
172
179
|
|
173
|
-
h2. Setting Project Properties
|
180
|
+
h2(#properties). Setting Project Properties
|
174
181
|
|
175
182
|
We mentioned the group identifier, version number and base directory. These are project properties. There are a few more properties we'll cover later on.
|
176
183
|
|
177
184
|
There are two ways to set project properties. You can pass them as a hash when you call @define@, or use accessors to set them on the project directly. For example:
|
178
185
|
|
179
|
-
|
186
|
+
<notextile>
|
187
|
+
{% highlight ruby %}
|
180
188
|
define 'silly', :version=>'1.0' do
|
181
189
|
project.group = 'acme'
|
182
190
|
end
|
@@ -185,12 +193,13 @@ puts project('silly').version
|
|
185
193
|
=> 1.0
|
186
194
|
puts project('silly').group
|
187
195
|
=> acme
|
188
|
-
}
|
196
|
+
{% endhighlight %}
|
197
|
+
</notextile>
|
189
198
|
|
190
199
|
Project properties are inherited. You can specify them once in the parent project, and they'll have the same value in all its sub-projects. In the example, we only specify the version number once, for use in all sub-projects.
|
191
200
|
|
192
201
|
|
193
|
-
h2. Resolving Paths
|
202
|
+
h2(#paths). Resolving Paths
|
194
203
|
|
195
204
|
You can run @buildr@ from any directory in your project. To keep tasks consistent and happy, it switches over to the Buildfile directory and executes all the tasks from there, before returning back to your working directory. Your tasks can all rely on relative paths that start from the same directory as the Buildfile.
|
196
205
|
|
@@ -200,7 +209,8 @@ The @path_to@ method takes an array of strings and concatenates them into a path
|
|
200
209
|
|
201
210
|
For example:
|
202
211
|
|
203
|
-
|
212
|
+
<notextile>
|
213
|
+
{% highlight ruby %}
|
204
214
|
# Relative to the current project
|
205
215
|
path_to('src', 'main', 'java')
|
206
216
|
|
@@ -209,16 +219,18 @@ _('src/main/java')
|
|
209
219
|
|
210
220
|
# Relative to the teh-impl project
|
211
221
|
project('teh-impl')._('src/main/java')
|
212
|
-
}
|
222
|
+
{% endhighlight %}
|
223
|
+
</notextile>
|
213
224
|
|
214
225
|
|
215
|
-
h2. Defining The Project
|
226
|
+
h2(#defining). Defining The Project
|
216
227
|
|
217
228
|
The project definition itself gives you a lot of pre-canned tasks to start with, but that's not enough to build a project. You need to specify what gets built and how, which dependencies to use, the packages you want to create and so forth. You can configure existing tasks, extend them to do additional work, and create new tasks. All that magic happens inside the project definition block.
|
218
229
|
|
219
230
|
Since the project definition executes each time you run Buildr, you don't want to perform any work directly inside the project definition block. Rather, you want to use it to specify how different build task work when you invoke them. Here's an example to illustrate the point:
|
220
231
|
|
221
|
-
|
232
|
+
<notextile>
|
233
|
+
{% highlight ruby %}
|
222
234
|
define 'silly' do
|
223
235
|
puts 'Running buildr'
|
224
236
|
|
@@ -226,7 +238,8 @@ define 'silly' do
|
|
226
238
|
puts 'Building silly'
|
227
239
|
end
|
228
240
|
end
|
229
|
-
}
|
241
|
+
{% endhighlight %}
|
242
|
+
</notextile>
|
230
243
|
|
231
244
|
Each time you run Buildr, it will execute the project definition and print out "Running buildr". We also extend the @build@ task, and whenever we run it, it will print "Building silly". Incidentally, @build@ is the default task, so if you run Buildr with no arguments, it will print both messages while executing the build. If you run Buildr with a different task, say @clean@, it will only print the first message.
|
232
245
|
|
@@ -240,7 +253,8 @@ One project can reference another ahead of its definition. If Buildr detects a
|
|
240
253
|
|
241
254
|
In this example we define one project in terms of another, using the same dependencies, so we only need to specify them once:
|
242
255
|
|
243
|
-
|
256
|
+
<notextile>
|
257
|
+
{% highlight ruby %}
|
244
258
|
define 'bar' do
|
245
259
|
compile.with project('foo').compile.dependencies
|
246
260
|
end
|
@@ -248,20 +262,21 @@ end
|
|
248
262
|
define 'foo' do
|
249
263
|
compile.with ..lots of stuff..
|
250
264
|
end
|
251
|
-
}
|
265
|
+
{% endhighlight %}
|
266
|
+
</notextile>
|
252
267
|
|
253
268
|
One last thing to remember. Actually three, but they all go hand in hand.
|
254
269
|
|
255
270
|
*Self is project* Each of these project definition blocks executes in the context of that project, just as if it was a method defined on the project. So when you call the @compile@ method, you're essentially calling that method on the current project: @compile@, @self.compile@ and @project.compile@ are all the same.
|
256
271
|
|
257
|
-
*Blocks are closures* The project definition is also a closure, which can reference variables from enclosing scopes. You can use that, for example, to define constants, variables and even functions in your Buildfile, and reference them from your project definition. As you'll see later on, in the "Artifacts"
|
272
|
+
*Blocks are closures* The project definition is also a closure, which can reference variables from enclosing scopes. You can use that, for example, to define constants, variables and even functions in your Buildfile, and reference them from your project definition. As you'll see later on, in the "Artifacts":artifacts.html section, it will save you a lot of work.
|
258
273
|
|
259
274
|
*Projects are namespaces* While executing the project definition, Buildr switches the namespace to the project name. If you define the task "do-this" inside the _teh-impl_ project, the actual task name is "killer-app:teh-impl:do-this". Likewise, the @compile@ task is actually "killer-app:teh-impl:compile".
|
260
275
|
|
261
276
|
From outside the project you can reference a task by its full name, either @task('foo:do')@ or @project('foo').task('do')@. If you need to reference a task defined outside the project from within the project, prefix it with "rake:", for example, @task('rake:globally-defined')@.
|
262
277
|
|
263
278
|
|
264
|
-
h2. Writing Your Own Tasks
|
279
|
+
h2(#your_own_tasks). Writing Your Own Tasks
|
265
280
|
|
266
281
|
Of all the features Buildr provide, it doesn't have a task for making coffee. Yet. If you need to write your own tasks, you get all the power of Rake: you can use regular tasks, file tasks, task rules and even write your own custom task classes. Check out the "Rake documentation":http://docs.rubyrake.org/ for more information.
|
267
282
|
|
data/doc/scripts/buildr-git.rb
CHANGED
@@ -16,79 +16,377 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
# This script helps buildr developers to obtain their own git clone from
|
19
|
-
# github,
|
19
|
+
# github, and also provides GitFlow commands to keep the git mirror in sync
|
20
|
+
# with Apache SVN.
|
20
21
|
#
|
21
|
-
#
|
22
|
+
# If you already have a buildr clone, just do the following:
|
22
23
|
#
|
23
|
-
#
|
24
|
+
# git config alias.apache '!'"ruby $PWD/doc/scripts/buildr-git.rb"
|
25
|
+
#
|
26
|
+
# After this, you have a 'git apache' command and you can try (be sure to read the help)
|
27
|
+
#
|
28
|
+
# git apache help
|
29
|
+
# git apache setup svn --help
|
30
|
+
# git apache sync --help
|
31
|
+
#
|
32
|
+
# To configure your local repo for svn synchronization,
|
33
|
+
#
|
34
|
+
# git apache update-authors
|
35
|
+
# git remote add upstream git@github.com:buildr/buildr.git
|
36
|
+
# git apache setup svn --username apacheLogin --apache-git upstream
|
37
|
+
# git apache sync
|
38
|
+
#
|
39
|
+
# This script can also be run without having a local buildr clone:
|
40
|
+
#
|
41
|
+
# ruby -ropen-uri -e 'eval(open("http://svn.apache.org/viewvc/buildr/trunk/doc/scripts/buildr-git.rb?view=co").read)' help
|
42
|
+
|
43
|
+
|
24
44
|
|
25
45
|
require 'yaml'
|
26
|
-
require '
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
46
|
+
require 'open-uri'
|
47
|
+
|
48
|
+
if $0 == '-e' # invoked from open-uri
|
49
|
+
gitflow = "http://svn.apache.org/viewvc/buildr/trunk/doc/scripts/gitflow.rb?view=co"
|
50
|
+
eval(open(gitflow).read)
|
51
|
+
else
|
52
|
+
require File.expand_path('gitflow', File.dirname(__FILE__))
|
53
|
+
end
|
54
|
+
|
55
|
+
GitFlow.program = 'buildr-git'
|
56
|
+
|
57
|
+
module BuildrGit
|
58
|
+
|
59
|
+
class UpdateUsersCommand < GitFlow/'update-users'
|
60
|
+
|
61
|
+
@help = "Update list of Apache SVN committers from Jukka's list."
|
62
|
+
@@url = 'http://people.apache.org/~jukka/authors.txt'
|
63
|
+
|
64
|
+
def self.authors_file
|
65
|
+
File.expand_path('.git/authors.txt', Dir.pwd)
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.user_email(apache_login, authors_file = nil)
|
69
|
+
authors_file ||= self.authors_file
|
70
|
+
authors = YAML.load(File.read(authors_file).gsub!(/\s+=\s+/, ': '))
|
71
|
+
contact = authors[apache_login]
|
72
|
+
fail "You are not listed as apache commiter on #{authors_file}" unless contact
|
73
|
+
fail "Not a valid contact line: #{contact}" unless contact =~ /\s+<(.*)>/
|
74
|
+
[$`, $1]
|
75
|
+
end
|
76
|
+
|
77
|
+
def options(opts)
|
78
|
+
opts.url = @@url
|
79
|
+
opts.file = self.class.authors_file
|
80
|
+
[['-u', '--url URL',
|
81
|
+
"From URL. defaults to: #{opts.url}", lambda { |url|
|
82
|
+
opts.url = url
|
83
|
+
}],
|
84
|
+
['-f', '--file FILE',
|
85
|
+
"Write to FILE, defaults to #{opts.file}", lambda { |path|
|
86
|
+
opts.file = path
|
87
|
+
}]
|
88
|
+
]
|
89
|
+
end
|
90
|
+
|
91
|
+
def execute(opts, argv)
|
92
|
+
FileUtils.mkdir_p(File.dirname(opts.file))
|
93
|
+
content = open(opts.url).read
|
94
|
+
File.open(opts.file, "w") { |f| f.print content }
|
95
|
+
end
|
42
96
|
end
|
43
97
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
98
|
+
class CloneCommand < GitFlow/:clone
|
99
|
+
@help = "Create a clone from github.com/buildr repository."
|
100
|
+
|
101
|
+
def options(opts)
|
102
|
+
opts.origin = 'git://github.com/buildr/buildr.git'
|
103
|
+
opts.svn_prefix = 'apache'
|
104
|
+
opts.project = 'buildr'
|
105
|
+
opts.local = expand_path(opts.project)
|
106
|
+
[['--prefix SVN_PREFIX', opts.svn_prefix, lambda { |p|
|
107
|
+
opts.svn_prefix = p }],
|
108
|
+
['--origin GIT_ORIGIN', opts.origin, lambda { |o|
|
109
|
+
opts.origin = o }],
|
110
|
+
['-d', '--dir DIR', opts.local, lambda { |d| opts.local = d }]
|
111
|
+
]
|
112
|
+
end
|
48
113
|
|
49
|
-
|
114
|
+
def execute(opts, argv)
|
115
|
+
git 'clone', opts.origin, opts.local
|
116
|
+
Dir.chdir(opts.local) do
|
117
|
+
run 'update-users'
|
118
|
+
run 'setup'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
50
122
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
123
|
+
class SetupCommand < GitFlow/:setup
|
124
|
+
@help = "Setup your buildr clone to be used with git mirror."
|
125
|
+
def options(opt)
|
126
|
+
[]
|
127
|
+
end
|
128
|
+
|
129
|
+
def execute(opt, argv)
|
130
|
+
run 'setup', 'alias'
|
131
|
+
run 'setup', 'svn'
|
132
|
+
end
|
133
|
+
end
|
55
134
|
|
56
|
-
|
57
|
-
|
135
|
+
class SetupAliasCommand < SetupCommand/:alias
|
136
|
+
def execute(opt, argv)
|
137
|
+
me = expand_path('doc/scripts/buildr-git.rb')
|
138
|
+
git 'config', 'alias.apache', "!ruby #{me}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class SetupSvnCommand < SetupCommand/:svn
|
143
|
+
@help = "Setup for getting changes from Apache SVN."
|
144
|
+
|
145
|
+
def options(opt)
|
146
|
+
opt.svn_prefix = 'apache'
|
147
|
+
opt.svn_path = 'buildr'
|
148
|
+
opt.townhall = 'origin'
|
149
|
+
[['--username SVN_USER', 'Use Apache svn username for this svn remote',
|
150
|
+
lambda { |e| opt.apache_login = e }],
|
151
|
+
['--svn-prefix PREFIX', 'The name of svn remote to use for project.',
|
152
|
+
"Defaults to #{opt.svn_prefix}",
|
153
|
+
lambda{|p| opt.svn_prefix = p }],
|
154
|
+
['--svn-uri URI', lambda {|p| opt.svn_uri = p }],
|
155
|
+
['--svn-rev REVISION', lambda {|p| opt.svn_rev = p }],
|
156
|
+
['--svn-path PATH', 'The path to append to svn-uri.',
|
157
|
+
"Defaults to #{opt.svn_path}", lambda {|p| opt.svn_path = p }],
|
158
|
+
['--apache-git REMOTE', 'The name of remote you are using as town-hall git repo.',
|
159
|
+
"Defaults to #{opt.townhall}",
|
160
|
+
lambda {|p| opt.townhall = p }]
|
161
|
+
]
|
162
|
+
end
|
163
|
+
|
164
|
+
def execute(opt, argv)
|
165
|
+
authors_file = UpdateUsersCommand.authors_file
|
166
|
+
git 'config', 'svn.authorsfile', authors_file
|
167
|
+
git 'config', 'apache.svn', opt.svn_prefix
|
168
|
+
git 'config', 'apache.git', opt.townhall
|
169
|
+
|
170
|
+
if opt.apache_login
|
171
|
+
user, email = UpdateUsersCommand.user_email(opt.apache_login, authors_file)
|
172
|
+
puts "You claim to be #{user} <#{email}> with apache login: #{opt.apache_login}"
|
173
|
+
git('config', 'user.name', user)
|
174
|
+
git('config', 'user.email', email)
|
175
|
+
end
|
176
|
+
|
177
|
+
if opt.svn_rev
|
178
|
+
revision = opt.svn_rev
|
179
|
+
else
|
180
|
+
location, revision = svn_loc_rev
|
181
|
+
revision = opt.svn_rev || revision
|
182
|
+
end
|
183
|
+
|
184
|
+
if opt.svn_uri
|
185
|
+
repo = opt.svn_uri
|
186
|
+
else
|
187
|
+
fail "No #{opt.svn_path} directory on #{location}" unless
|
188
|
+
location =~ /\/#{opt.svn_path}/
|
189
|
+
repo = $`
|
190
|
+
end
|
191
|
+
|
192
|
+
# Tell git where the svn repository is
|
193
|
+
git('config', "svn-remote.#{opt.svn_prefix}.url", repo)
|
194
|
+
git('config', "svn-remote.#{opt.svn_prefix}.fetch",
|
195
|
+
"#{opt.svn_path}/trunk:refs/remotes/#{opt.svn_prefix}/trunk")
|
196
|
+
git('config', "svn-remote.#{opt.svn_prefix}.branches",
|
197
|
+
"#{opt.svn_path}/branches/*:refs/remotes/#{opt.svn_prefix}/*")
|
198
|
+
git('config', "svn-remote.#{opt.svn_prefix}.tags",
|
199
|
+
"#{opt.svn_path}/tags/*:refs/remotes/#{opt.svn_prefix}/tags/*")
|
200
|
+
|
201
|
+
# Store the user for svn dcommit
|
202
|
+
if opt.apache_login
|
203
|
+
git('config', "svn-remote.#{opt.svn_prefix}.username", opt.apache_login)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Create the svn branch, do this instead of pulling the full svn history
|
207
|
+
git('update-ref', "refs/remotes/#{opt.svn_prefix}/trunk",
|
208
|
+
'refs/remotes/origin/master')
|
209
|
+
# create tags from git
|
210
|
+
git('tag').split.each do |tag|
|
211
|
+
git('update-ref', "refs/remotes/#{opt.svn_prefix}/tags/#{tag}",
|
212
|
+
"refs/tags/#{tag}")
|
213
|
+
end
|
214
|
+
# update svn metadata
|
215
|
+
mkdir_p(expand_path('.git/svn'))
|
216
|
+
svn_meta = expand_path('.git/svn/.metadata')
|
217
|
+
git('config', '--file', svn_meta,
|
218
|
+
"svn-remote.#{opt.svn_prefix}.branches-maxRev", revision)
|
219
|
+
git('config', '--file', svn_meta,
|
220
|
+
"svn-remote.#{opt.svn_prefix}.tags-maxRev", revision)
|
221
|
+
end
|
222
|
+
|
223
|
+
def svn_loc_rev
|
224
|
+
meta = sh('git log -n 10 | grep git-svn-id | head -n 1').chomp
|
225
|
+
fail "No svn metadata on last 10 commits" if meta.empty?
|
226
|
+
meta.split[1].split('@')
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
class FetchCommand < GitFlow/:fetch
|
231
|
+
@help = "Get changes from svn, creating tags, branches on townhall"
|
232
|
+
@documentation = <<-DOC
|
233
|
+
This command can be used to fetch changes from Apache\'s SVN repo.
|
234
|
+
|
235
|
+
GIT CONFIG VALUES:
|
236
|
+
|
237
|
+
apache.svn - The svn remote using to get changes from Apache SVN.
|
238
|
+
Set by setup-svn --svn-prefix.
|
239
|
+
DOC
|
240
|
+
|
241
|
+
def options(opt)
|
242
|
+
opt.apache_svn = git('config', '--get', 'apache.svn').chomp rescue nil
|
243
|
+
[['--apache-svn SVN_REMOTE', 'The SVN remote used to get changes from Apache',
|
244
|
+
"Current value: #{opt.apache_svn}",
|
245
|
+
lambda { |r| opt.apache_svn = r }]
|
246
|
+
]
|
247
|
+
end
|
248
|
+
|
249
|
+
def execute(opt, argv)
|
250
|
+
fail "Missing apache.svn config value" unless opt.apache_svn
|
251
|
+
git('svn', 'fetch', opt.apache_svn)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
class SyncCommand < GitFlow/:sync
|
256
|
+
@help = "Synchronizes between Apache svn and git townhall."
|
257
|
+
@documentation = <<-DOC
|
258
|
+
This command will perform the following actions:
|
259
|
+
* fetch changes from apache svn.
|
260
|
+
* rebase them on the current branch or on the one specified with --onto
|
261
|
+
* dcommit (this will push your changes to Apache trunk)
|
262
|
+
|
263
|
+
GIT CONFIG VALUES:
|
264
|
+
|
265
|
+
apache.svn
|
266
|
+
The svn remote using to get changes from Apache SVN.
|
267
|
+
Set by setup-svn --svn-prefix.
|
268
|
+
|
269
|
+
apache.git
|
270
|
+
The git remote used as townhall repository.
|
271
|
+
Set by setup-svn --townhall.
|
272
|
+
|
273
|
+
svn-remote.APACHE_GIT.username
|
274
|
+
If configured, sync will use this svn username while dcommiting.
|
275
|
+
DOC
|
276
|
+
|
277
|
+
def options(opt)
|
278
|
+
git('branch').split.tap { |n| opt.current = n[n.index('*')+1] }
|
279
|
+
opt.branch = opt.current
|
280
|
+
opt.svn_branch = 'trunk'
|
281
|
+
opt.git_branch = 'master'
|
282
|
+
opt.apache_git = git('config', '--get', 'apache.git').chomp rescue nil
|
283
|
+
opt.apache_svn = git('config', '--get', 'apache.svn').chomp rescue nil
|
284
|
+
opt.svn_username = git('config', '--get',
|
285
|
+
"svn-remote.#{opt.apache_svn}.username").chomp rescue nil
|
286
|
+
[['--apache-svn SVN_REMOTE', 'The SVN remote used to get changes from Apache',
|
287
|
+
"Current value: #{opt.apache_svn}",
|
288
|
+
lambda { |r| opt.apache_svn = r }],
|
289
|
+
['--apache-git REMOTE', 'The git remote used as town-hall repository.',
|
290
|
+
"Current value: #{opt.apache_git}",
|
291
|
+
lambda { |r| opt.apache_git = r }],
|
292
|
+
['--username SVN_USER',
|
293
|
+
'Specify the SVN username for dcommit',
|
294
|
+
"Defaults to: #{opt.svn_username}",
|
295
|
+
lambda { |b| opt.svn_username = b }],
|
296
|
+
['--svn-branch SVN_BRANCH',
|
297
|
+
'Specify the SVN branch to rebase changes from, and where to dcommit',
|
298
|
+
"Defaults to: #{opt.svn_branch}",
|
299
|
+
lambda { |b| opt.svn_branch = b }],
|
300
|
+
['--git-branch REMOTE_BRANCH',
|
301
|
+
'Specify the remote town-hall branch (on apache.git) to update',
|
302
|
+
"Defaults to: #{opt.git_branch}",
|
303
|
+
lambda { |b| opt.git_branch = b }],
|
304
|
+
['--branch BRANCH', 'Specify the local branch to take changes from',
|
305
|
+
"Current branch: #{opt.branch}",
|
306
|
+
lambda { |b| opt.branch = b }]
|
307
|
+
]
|
308
|
+
end
|
309
|
+
|
310
|
+
def execute(opt, argv)
|
311
|
+
# obtain the svn url
|
312
|
+
url = git('config', '--get', "svn-remote.#{opt.apache_svn}.url").chomp
|
313
|
+
# obtain the path for project
|
314
|
+
path = git('config', '--get', "svn-remote.#{opt.apache_svn}.branches").
|
315
|
+
chomp.split('/branches').first
|
316
|
+
commit_url = "#{url}/#{path}/#{opt.svn_branch}"
|
317
|
+
|
318
|
+
# obtain latest changes from svn
|
319
|
+
git('svn', 'fetch', '--svn-remote', opt.apache_svn)
|
320
|
+
# obtain latest changes from git
|
321
|
+
git('fetch', opt.apache_git,
|
322
|
+
"#{opt.git_branch}:refs/remotes/#{opt.apache_git}/#{opt.git_branch}")
|
323
|
+
|
324
|
+
# rebase svn changes in the desired branch
|
325
|
+
git('rebase', "#{opt.apache_svn}/#{opt.svn_branch}", opt.branch)
|
326
|
+
git('rebase', "#{opt.apache_git}/#{opt.git_branch}", opt.branch)
|
327
|
+
|
328
|
+
# dcommit to the specific svn branch
|
329
|
+
['svn', 'dcommit',
|
330
|
+
'--svn-remote', opt.apache_svn, '--commit-url', commit_url].tap do |cmd|
|
331
|
+
if opt.svn_username
|
332
|
+
cmd << '--username' << opt.svn_username
|
333
|
+
end
|
334
|
+
git(*cmd)
|
335
|
+
end
|
336
|
+
|
337
|
+
# update townhall remote ref
|
338
|
+
git('update-ref',
|
339
|
+
"refs/remotes/#{opt.apache_git}/#{opt.git_branch}",
|
340
|
+
"refs/remotes/#{opt.apache_svn}/#{opt.svn_branch}")
|
341
|
+
|
342
|
+
# forward the remote townhall/master to apache/trunk
|
343
|
+
git('push', opt.apache_git,
|
344
|
+
"refs/remotes/#{opt.apache_git}/#{opt.git_branch}:#{opt.git_branch}")
|
345
|
+
|
346
|
+
# get back to the original branch
|
347
|
+
git('checkout', opt.current)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
|
352
|
+
# This one is displayed when the user executes this script using
|
353
|
+
# open-uri -e
|
354
|
+
HEADER = <<HEADER
|
58
355
|
|
59
356
|
Buildr official commit channel is Apache's svn repository, however some
|
60
357
|
developers may prefer to use git while working on several features and
|
61
358
|
merging other's changes.
|
62
359
|
|
63
|
-
This script will configure a
|
360
|
+
This script will configure a gitflow copy on so you can commit to svn.
|
64
361
|
|
65
362
|
Enter <-h> to see options, <-H> to see notes about configured aliases
|
66
363
|
and recommended workflow, or any other option.
|
67
364
|
|
68
365
|
Ctrl+D or an invalid option to abort
|
69
366
|
HEADER
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
367
|
+
|
368
|
+
# When fork is completed, we display the following notice on a
|
369
|
+
# pager, giving the user a brief overview of git aliases used
|
370
|
+
# to keep the mirror in sync.
|
371
|
+
NOTICE = <<NOTICE
|
74
372
|
ALIASES:
|
75
373
|
|
76
374
|
Some git aliases have been created for developer convenience:
|
77
375
|
|
78
|
-
git apache
|
376
|
+
git apache fetch # get changes from apache/trunk without merging them
|
79
377
|
# you can inspect what's happening on trunk without
|
80
378
|
# having to worry about merging conflicts.
|
81
379
|
# Inspect the remote branch with `git log apache/trunk`
|
82
380
|
# Or if you have a git-ui like `tig` you can use that.
|
83
381
|
|
84
|
-
git apache
|
382
|
+
git apache merge # Merge already fetched changes on the current branch
|
85
383
|
# Use this command to get up to date with trunk changes
|
86
384
|
# you can always cherry-pick from the apache/trunk
|
87
385
|
# branch.
|
88
386
|
|
89
|
-
git apache
|
387
|
+
git apache pull # get apache-fetch && git apache-merge
|
90
388
|
|
91
|
-
git apache
|
389
|
+
git apache push # Push to Apache's SVN. Only staged changes (those
|
92
390
|
# recorded using `git commit`) will be sent to SVN.
|
93
391
|
# You need not to be on the master branch.
|
94
392
|
# Actually you can work on a tiny-feature branch and
|
@@ -108,24 +406,30 @@ ALIASES:
|
|
108
406
|
|
109
407
|
THE GITHUB MIRROR:
|
110
408
|
|
111
|
-
Buildr has an unofficial git mirror on github, maintained by
|
409
|
+
Buildr has an unofficial git mirror on github, maintained by Apache committers:
|
112
410
|
|
113
|
-
http://github.com/
|
411
|
+
http://github.com/buildr/buildr
|
114
412
|
|
115
|
-
|
116
|
-
|
413
|
+
This mirror DOES NOT replace Apache's SVN repository. We really care about
|
414
|
+
using Apache infrastructure and following Apache project guidelines for
|
415
|
+
contributions. This git mirror is provided only for developers convenience,
|
416
|
+
allowing them to easily create experimental branches or review code from
|
417
|
+
other committers.
|
117
418
|
|
118
|
-
|
419
|
+
All code that wants to make it to the official Apache Buildr repository needs
|
420
|
+
to be committed to the Apache SVN repository by using the command:
|
119
421
|
|
120
|
-
|
422
|
+
git synchronize
|
121
423
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
424
|
+
This command will synchronize both ways svn<->git to keep trunk upto date.
|
425
|
+
You need to be an Apache committer and have permissions on the SVN repo.
|
426
|
+
|
427
|
+
It's VERY IMPORTANT for Buildr committers to remember that contributions from
|
428
|
+
external entities wanting to be accepted will require them to sign the Apache ICLA.
|
429
|
+
We provide the git mirror to make it easier for people to experiment and
|
430
|
+
contribute back to Buildr, before merging their code in, please remember they
|
431
|
+
have to create create a JIRA issue granting ASF permission to include their code,
|
432
|
+
just like any other contribution following Apache's guidelines.
|
129
433
|
|
130
434
|
So, it's very important - if you care about meritocracy - to follow or at
|
131
435
|
least that you get an idea of the recommended workflow.
|
@@ -139,7 +443,7 @@ RECOMMENDED WORKFLOW:
|
|
139
443
|
As all things git, you can always follow your own workflow and even create
|
140
444
|
aliases on you .git/config file to avoid typing much. So, here they are:
|
141
445
|
|
142
|
-
1) get your
|
446
|
+
1) get your gitflow configured
|
143
447
|
(you have already do so, this was the most difficult part)
|
144
448
|
|
145
449
|
2) create a topic branch to work on, say.. you want to add cool-feature:
|
@@ -175,15 +479,15 @@ RECOMMENDED WORKFLOW:
|
|
175
479
|
license to include your code:
|
176
480
|
|
177
481
|
https://issues.apache.org/jira/browse/BUILDR
|
178
|
-
|
482
|
+
dev@buildr.apache.org
|
179
483
|
|
180
484
|
7.b) Now you have everyhing on staging area and merged important changes
|
181
485
|
from apache/trunk, it's time to commit them to Apache's SVN.
|
182
486
|
|
183
487
|
git apache-push
|
184
488
|
|
185
|
-
8) Optional. If you
|
186
|
-
|
489
|
+
8) Optional. If you are a buildr committer you may want to synchronize
|
490
|
+
the github mirror for helping others to get changes without having to
|
187
491
|
wait on Victor's cronjob to run every hour (useful for urgent changes).
|
188
492
|
|
189
493
|
git synchronize
|
@@ -194,219 +498,15 @@ RECOMMENDED WORKFLOW:
|
|
194
498
|
git rebase --onto origin/master master master
|
195
499
|
|
196
500
|
10) Unconditionally, Go to step 2 ;)
|
197
|
-
Share your
|
501
|
+
Share your gitflow workflow, git tips, etc.
|
198
502
|
|
199
503
|
RESOURCES:
|
200
504
|
|
201
|
-
http://github.com/
|
505
|
+
http://github.com/buildr/buildr/tree/master
|
202
506
|
http://git.or.cz/gitwiki/GitCheatSheet
|
203
507
|
http://groups.google.com/group/git-users/web/git-references
|
204
508
|
|
205
509
|
NOTICE
|
206
|
-
|
207
|
-
|
208
|
-
def optparse(options = OpenStruct.new, argv = ARGV)
|
209
|
-
opt = OptionParser.new do |opt|
|
210
|
-
|
211
|
-
if `git status 2>/dev/null`.chomp.empty?
|
212
|
-
options.local = File.expand_path('buildr', Dir.pwd)
|
213
|
-
else
|
214
|
-
puts "Current directory is a git repo: #{Dir.pwd}"
|
215
|
-
options.local = Dir.pwd
|
216
|
-
end
|
217
|
-
|
218
|
-
options.svn_branch = "apache/trunk"
|
219
|
-
options.origin = "git://github.com/vic/buildr.git"
|
220
|
-
options.member = false
|
221
|
-
|
222
|
-
opt.banner = "Usage: buildr-git.rb [options]"
|
223
|
-
opt.separator ""
|
224
|
-
opt.separator "OPTIONS:"
|
225
|
-
|
226
|
-
opt.on('-a', "--anon", "Use git://github.com/vic/buildr.git as origin") do
|
227
|
-
options.origin = "git://github.com/vic/buildr.git"
|
228
|
-
end
|
229
|
-
opt.on('-A', "--auth", "Use git@github.com:vic/buildr.git as origin") do
|
230
|
-
options.origin = "git@github.com:vic/buildr.git"
|
231
|
-
end
|
232
|
-
opt.on("-o", "--origin GIT_URL", "Clone from GIT_URL origin") do |value|
|
233
|
-
options.origin = value
|
234
|
-
end
|
235
|
-
opt.on('-l', "--local DIRECTORY", "Create local git clone on DIRECTORY") do |value|
|
236
|
-
options.local = value
|
237
|
-
end
|
238
|
-
opt.on('-b', "--branch GIT_SVN_BRANCH",
|
239
|
-
"Set the name for svn branch instead of apache/trunk") do |value|
|
240
|
-
options.svn_branch = value
|
241
|
-
end
|
242
|
-
opt.on('-e', "--email EMAIL",
|
243
|
-
"Configure git to use EMAIL for commits") do |value|
|
244
|
-
options.email = value
|
245
|
-
end
|
246
|
-
opt.on('-n', "--name USER_NAME",
|
247
|
-
"Configure your USER_NAME for git commits") do |value|
|
248
|
-
options.user_name = value
|
249
|
-
end
|
250
|
-
opt.on('-h', "--help", "Show buildr-git help") do
|
251
|
-
puts opt
|
252
|
-
throw :exit
|
253
|
-
end
|
254
|
-
opt.on('-H', "--notice", "Show notice about aliases and git workflow") do
|
255
|
-
run_pager
|
256
|
-
puts notice
|
257
|
-
throw :exit
|
258
|
-
end
|
259
|
-
end
|
260
|
-
opt.parse!(argv)
|
261
|
-
options
|
262
|
-
end # optparse method
|
263
|
-
|
264
|
-
|
265
|
-
def main
|
266
|
-
catch :exit do
|
267
|
-
options = optparse
|
268
|
-
puts header
|
269
|
-
puts
|
270
|
-
print '> '
|
271
|
-
if input = gets
|
272
|
-
options = optparse(options, input.split)
|
273
|
-
end
|
274
|
-
if input.nil? || (input != "\n" && input.empty?)
|
275
|
-
puts "Aborting."
|
276
|
-
return
|
277
|
-
end
|
278
|
-
perform(options)
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
def perform(options)
|
283
|
-
origin = options.origin
|
284
|
-
member = origin =~ /@/
|
285
|
-
local = options.local
|
286
|
-
svn_branch = options.svn_branch
|
287
|
-
user_email = options.email
|
288
|
-
user_name = options.user_name
|
289
|
-
|
290
|
-
`git clone #{origin} #{local} 1>&2` unless File.directory?(File.join('.git', origin))
|
510
|
+
#' for emacs
|
291
511
|
|
292
|
-
|
293
|
-
puts "Entering #{local} directory"
|
294
|
-
puts
|
295
|
-
Dir.chdir(local) do
|
296
|
-
|
297
|
-
# Load the list of git-svn committers
|
298
|
-
svn_authors_file = File.expand_path('etc/git-svn-authors', Dir.pwd)
|
299
|
-
svn_authors = File.read(svn_authors_file)
|
300
|
-
svn_authors.gsub!(/\s+=\s+/, ': ')
|
301
|
-
svn_authors = YAML.load(svn_authors)
|
302
|
-
|
303
|
-
# set the git-svn-authors file
|
304
|
-
`git config svn.authorsfile "#{svn_authors_file}"`
|
305
|
-
|
306
|
-
# Check that git is configured for the developer
|
307
|
-
user_email ||= `git config --get user.email`.chomp
|
308
|
-
if user_email.empty?
|
309
|
-
if member
|
310
|
-
puts "Enter your email as listed on #{svn_authors_file}"
|
311
|
-
print "> "
|
312
|
-
user_email = gets.chomp
|
313
|
-
else
|
314
|
-
puts "Provide an email address for git usage:"
|
315
|
-
user_email = gets.chomp
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
# Check user is listed
|
320
|
-
unless user_email.empty?
|
321
|
-
svn_user, git_contact = *svn_authors.find { |entry| /#{user_email}/ === entry.join(' ') }
|
322
|
-
end
|
323
|
-
|
324
|
-
if member
|
325
|
-
if git_contact.nil? # if using the authenticated git, he must be listed
|
326
|
-
puts <<-NOTICE
|
327
|
-
You need to be a buildr commmitter listed on #{svn_authors_file}.
|
328
|
-
Perhaps you need to add yourself to it, commit it using SVN, and
|
329
|
-
and run this script again.
|
330
|
-
Also checks your git global values for user.email and user.name
|
331
|
-
NOTICE
|
332
|
-
return
|
333
|
-
elsif /\s*(.*?)\s+\<(.+)\>\s*/ === git_contact
|
334
|
-
user_name, user_email = $1, $2
|
335
|
-
else
|
336
|
-
puts "Invalid contact string for #{svn_user}: #{git_contact.inspect}"
|
337
|
-
return
|
338
|
-
end
|
339
|
-
elsif user_email =~ /^\s*$/
|
340
|
-
puts "User email shall not include spaces: #{user_email.inspect}"
|
341
|
-
return
|
342
|
-
end
|
343
|
-
|
344
|
-
user_name ||= `git config --get user.name`.chomp
|
345
|
-
if git_contact.nil? && user_name.empty?
|
346
|
-
puts "Provide a developer name for git usage:"
|
347
|
-
user_name = gets.chomp
|
348
|
-
end
|
349
|
-
|
350
|
-
# Start the pager
|
351
|
-
run_pager
|
352
|
-
puts
|
353
|
-
|
354
|
-
|
355
|
-
old_origin = `git config --get remote.origin.url`.chomp
|
356
|
-
if member && old_origin !~ /@/
|
357
|
-
puts "Switching to authenticated origin #{origin}", ""
|
358
|
-
`git config remote.origin.url "#{origin}"`
|
359
|
-
elsif !member && old_origin =~ /@/
|
360
|
-
puts "Switching to anonymous origin #{origin}", ""
|
361
|
-
`git config remote.origin.url "#{origin}"`
|
362
|
-
end
|
363
|
-
|
364
|
-
# Configure user name and email for git sake (and github's gravatar)
|
365
|
-
puts "You claim to be #{user_name.inspect} <#{user_email}> "
|
366
|
-
puts "with apache-svn user: #{svn_user}" if svn_user
|
367
|
-
puts
|
368
|
-
`git config user.name "#{user_name}"`
|
369
|
-
`git config user.email "#{user_email}"`
|
370
|
-
|
371
|
-
# Ok, now obtain the last svn commit from history
|
372
|
-
last_svn_log = `git log -n 10 | grep git-svn-id | head -n 1`
|
373
|
-
fail "No svn metadata on last 10 commits" unless last_svn_log =~ /git-svn-id/
|
374
|
-
svn_repo, svn_prev = last_svn_log.split[1].split("@")
|
375
|
-
|
376
|
-
# Tell git where the svn repository is.
|
377
|
-
`git config svn-remote.#{svn_branch}.url #{svn_repo}`
|
378
|
-
`git config svn-remote.#{svn_branch}.fetch :refs/remotes/#{svn_branch}`
|
379
|
-
|
380
|
-
# Create the svn branch, do this instead of pulling the full svn history
|
381
|
-
`git push --force . refs/remotes/origin/master:refs/remotes/#{svn_branch}`
|
382
|
-
|
383
|
-
# Create apache aliases for developers git-workflow.
|
384
|
-
`git config alias.apache-fetch "!git-svn fetch #{svn_branch}"`
|
385
|
-
`git config alias.apache-merge "!git merge #{svn_branch}"`
|
386
|
-
`git config alias.apache-pull "!git apache-fetch && git apache-merge"`
|
387
|
-
if svn_user
|
388
|
-
`git config alias.apache-push "!git-svn dcommit --username #{svn_user}"`
|
389
|
-
else
|
390
|
-
`git config alias.apache-push "!git-svn dcommit"`
|
391
|
-
end
|
392
|
-
|
393
|
-
# Create github origin aliases
|
394
|
-
`git config alias.get "!git apache-fetch && git fetch origin"`
|
395
|
-
`git config alias.mrg "!git apache-merge && git merge origin"`
|
396
|
-
`git config alias.rbs "!git rebase --onto #{svn_branch} origin/master master"`
|
397
|
-
`git config alias.put "!git apache-push && git push origin"`
|
398
|
-
|
399
|
-
# This is Victor's cronjob
|
400
|
-
`git config alias.synchronize "!git get && git rbs && git put"`
|
401
|
-
|
402
|
-
# Final notices.
|
403
|
-
puts <<-NOTICE + notice
|
404
|
-
|
405
|
-
Your git repo #{local} has been configured, please review the
|
406
|
-
#{File.join(local, '.git/config')} file.
|
407
|
-
|
408
|
-
NOTICE
|
409
|
-
end
|
410
|
-
end # perform method
|
411
|
-
|
412
|
-
main
|
512
|
+
end
|