hallettj-cloudrcs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-04-25
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/License.txt ADDED
@@ -0,0 +1,14 @@
1
+ Copyright (c) 2008 Jesse Hallett
2
+
3
+ This program is free software: you can redistribute it and/or modify
4
+ it under the terms of the GNU General Public License as published by
5
+ the Free Software Foundation, either version 3 of the License, or (at
6
+ your option) any later version.
7
+
8
+ This program is distributed in the hope that it will be useful, but
9
+ WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ General Public License for more details.
12
+
13
+ You should have received a copy of the GNU General Public License
14
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
data/Manifest.txt ADDED
@@ -0,0 +1,35 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ PostInstall.txt
5
+ README.txt
6
+ Rakefile
7
+ config/hoe.rb
8
+ config/requirements.rb
9
+ lib/active_record/acts/list.rb
10
+ lib/acts_as_list.rb
11
+ lib/cloud_rcs.rb
12
+ lib/cloudrcs.rb
13
+ lib/cloud_rcs/patch.rb
14
+ lib/cloud_rcs/primitive_patch.rb
15
+ lib/cloud_rcs/patch_types/addfile.rb
16
+ lib/cloud_rcs/patch_types/binary.rb
17
+ lib/cloud_rcs/patch_types/hunk.rb
18
+ lib/cloud_rcs/patch_types/move.rb
19
+ lib/cloud_rcs/patch_types/rmfile.rb
20
+ lib/cloudrcs/version.rb
21
+ script/console
22
+ script/destroy
23
+ script/generate
24
+ script/txt2html
25
+ setup.rb
26
+ tasks/deployment.rake
27
+ tasks/environment.rake
28
+ tasks/website.rake
29
+ test/test_cloudrcs.rb
30
+ test/test_helper.rb
31
+ website/index.html
32
+ website/index.txt
33
+ website/javascripts/rounded_corners_lite.inc.js
34
+ website/stylesheets/screen.css
35
+ website/template.html.erb
data/PostInstall.txt ADDED
@@ -0,0 +1,2 @@
1
+
2
+ For more information on cloudrcs, see http://github.com/hallettj/cloudrcs/tree/master
data/README.txt ADDED
@@ -0,0 +1,293 @@
1
+ = cloudrcs
2
+
3
+ Get the code at:
4
+ http://github.com/hallettj/cloudrcs/tree/master
5
+
6
+ File bugs at:
7
+ http://hallettj.lighthouseapp.com/projects/11392/home
8
+
9
+
10
+ == DESCRIPTION:
11
+
12
+ CloudRCS is a revision control system implemented in pure Ruby and
13
+ based on darcs. It can be used as plugin for Ruby on Rails; or it can
14
+ be used without Rails, provided ActiveRecord is available.
15
+
16
+
17
+ == FEATURES/PROBLEMS:
18
+
19
+ CloudRCS is based on darcs; thus employing the same powerful theory of
20
+ patches that darcs does. It aims for darcs interoperability wherever
21
+ possible. However, I plan to implement features that are not available
22
+ with darcs, such as the ability to check out a subdirectory of a
23
+ repository, and the ability to provide partial access to a repository
24
+ according to a permissions system.
25
+
26
+ CloudRCS can be easily extended with new patch types. To introduce a
27
+ new patch type, it is only necessary to define a subclass of
28
+ CloudRCS::PrimitivePatch that implements the methods of PrmitivePatch
29
+ that indicate that they should be overridden.
30
+
31
+ CloudRCS is not yet complete. Patch types for manipulating directories
32
+ have not been implemented; so currently CloudRCS is limited flat
33
+ repositories. However, binary patches have recently been implemented;
34
+ and patch types for directories should follow shortly.
35
+
36
+ In addition, the merge algorithm is implemented and working - but it
37
+ is not quite finished. It will fail in certain cases where multiple
38
+ pushes are performed without any intervening pulls.
39
+
40
+ Finally, there is no intelligent support for resolving conflicts
41
+ yet. If a conflict is encountered, CloudRCS will raise an exception.
42
+
43
+
44
+ == SYNOPSIS:
45
+
46
+ CloudRCS includes a number of ActiveRecord models that represent named
47
+ and primitive patches. Add the line `require 'cloudrcs'` to the
48
+ environment.rb file of a Rails application, and those models will be
49
+ made available in the application automatically.
50
+
51
+ To generate a patch representing the changes made to any file, call
52
+ CloudRCS::Patch.generate(orig_file, changed_file) - where changed_file
53
+ is the file object in question, and orig_file is an unchanged version
54
+ of the same file. The generate method will return an unsaved instance
55
+ of CloudRCS::Patch.
56
+
57
+ To output a patch in darcs-compatible format, call
58
+ patch.gzipped_contents. That will yield the contents of a patch file
59
+ as a string compressed using gzip. The darcs format also specifies the
60
+ filename for any patch file. The appropriate file name can be
61
+ generated by calling patch.file_name. This gzipped format is handy for
62
+ sending the patch along to any other repository.
63
+
64
+ When receiving a patch file, the file can be translated into CloudRCS
65
+ objects by calling CloudRCS::Patch.parse(contents) - where contents
66
+ should be the contents of a patch file. The contents may be gzipped,
67
+ or in clear text. The parse method will return an unsaved
68
+ CloudRCS::Patch instance.
69
+
70
+ To apply any patch to your repository, call patch.apply! Any changes
71
+ represented by the patch will be applied and saved to the database. If
72
+ you want to apply the patch to a particular file without saving the
73
+ changes, then call patch.apply_to(file) - which will return a file
74
+ object with the unsaved changes.
75
+
76
+ The CloudRCS models are namespaced. So instead of making calls to
77
+ Patch, you will have to make calls to CloudRCS::Patch. If you want to
78
+ bypass the namespacing, you can create a model in your Rails
79
+ application called patch.rb that contains this line:
80
+
81
+ Patch = CloudRCS::Patch
82
+
83
+ You can use a name other than Patch if you want to, as long as the
84
+ name of the file and the constant name match.
85
+
86
+ Defining such a model in your application also allows you to extend
87
+ CloudRCS. For example, if your application will be handling multiple
88
+ repositories and you want to differentiate the repositories by user,
89
+ then define a Patch model that looks something like this:
90
+
91
+ Patch = CloudRCS::Patch
92
+ class Patch
93
+ belongs_to :user
94
+ validates_presence_of :user_id
95
+ end
96
+
97
+ class CloudRCS::PrimitivePatch
98
+ def locate_file(path)
99
+ MyAppFileClass.locate(path, :owner => patch.owner)
100
+ end
101
+ def self.file_class
102
+ MyAppFileClass
103
+ end
104
+ end
105
+
106
+ The extension to CloudRCS::PrimitivePatch informs CloudRCS of how to
107
+ locate files in your application. It also informs CloudRCS what class
108
+ you are using to represent files.
109
+
110
+ CloudRCS is currently not capable of accessing files using Ruby's File
111
+ class. It expects whatever file_class you use to implement the
112
+ following methods:
113
+
114
+ path : Return the path of the file relative to the repository root
115
+ path=(new_path) : Moves the file to new_path
116
+ contents : Returns the contents of the file as a string
117
+ contents=(c) : Sets the file's contents to c
118
+
119
+ = Writing new patch types
120
+
121
+ CloudRCS uses darcs' notion of named and primitive patches. A named
122
+ patch contains a header with the author of the patch, the date it was
123
+ created, and a description of the changes it describes. Named patches
124
+ can contain multiple changes affecting any number of files. They are
125
+ represented in CloudRCS by the class, CloudRCS::Patch.
126
+
127
+ A primitive patch represents a single change to a single file. The
128
+ could be the creation, movement, or deletion of a file. It could also
129
+ be a single changed hunk of a text file. CloudRCS represents primitive
130
+ patches with the class, CloudRCS::PrimitivePatch.
131
+
132
+ New patch types come in the form of new primitive patches types. To
133
+ define a primitive patch type, create a subclass of
134
+ CloudRCS::PrimitivePatch. The new class must override the following
135
+ methods:
136
+
137
+ apply_to(file) : Given a file object, applies the changes described by
138
+ the patch and returns the modified file. If file is
139
+ an instance of an ActiveRecord model, the changes
140
+ should not be saved by apply_to. Saving changes to
141
+ the database will be handled by the apply! method.
142
+
143
+ inverse : Returns the inverse of the patch. And inverse patch
144
+ completely undoes the effects of the original patch. So for
145
+ example, the inverse of a move from foo to bar is a move
146
+ from bar to foo.
147
+
148
+ Primitive patches have an attribute, `inverted`, that must
149
+ be set to true when a patch is generated as an inverse.
150
+
151
+ commute(patch) : Given another prmitive patch, generates the commuted
152
+ versions of the two patches. This is critical to
153
+ applying the theory of patches. Commuted patches
154
+ perform the same changes as the the originals, but
155
+ are applied in the reversed order. The commute method
156
+ assumes that the receiver is applied before the given
157
+ patch. So it returns [patch_prime, self_prime], where
158
+ patch_prime is the commuted version of the other
159
+ patch, and self_prime is the commuted version of the
160
+ receiver.
161
+
162
+ The commuted patches must be modified from the
163
+ originals so that they apply cleanly after being
164
+ reordered. For example, hunk patches operate on a
165
+ given line number within a file by removing lines
166
+ from that position, and then adding lines to the same
167
+ position. If two hunk patches that affect the same
168
+ file are commuted, the line numbers must be updated
169
+ in the commuted versions. If patch removes two lines
170
+ starting at line 3, and self adds to lines starting
171
+ at line 10, then when they are commuted those line
172
+ numbers will no longer be appropriate. Since
173
+ patch_prime will be aplied first, the position was
174
+ previously indicated as line 10 gets shifted up by
175
+ two lines and becomes line 8. So self_prime has to
176
+ operate on line 8 instead of line 10.
177
+
178
+ to_s : Returns a representation of the patch as a string for outptting
179
+ to a patch file. The string representation must begin with a
180
+ token representing the type of the patch, which is the
181
+ lowercase of the class name. So the token representing
182
+ CloudRCS::Hunk is 'hunk'.
183
+
184
+ The string representation must contain any patch type tokens at
185
+ the beginning of any line after the first. Beginning lines with
186
+ a non-alphanumeric character like '+', '-', or a space is a
187
+ good way to ensure that this restriction is respected.
188
+
189
+ In addition to the above instance methods, the patch type must also
190
+ override these class methods:
191
+
192
+ generate(orig_file, changed_file) :
193
+
194
+ Given a changed file and an unchanged version of the same file,
195
+ this method returns a patch that represents one change between the
196
+ two files, or an array of patches that represent one change
197
+ each. It is not necessary for the patches returned to represent
198
+ all of the changes between the two files - only the changes that
199
+ are well described by this patch type.
200
+
201
+ If there is no change between the two files that is well described
202
+ by this patch type, then this method should return nil or an empty
203
+ array.
204
+
205
+ Note that either orig_file or changed_file may be nil. If
206
+ orig_file is nil, then that represents the creation of a new
207
+ file. And when changed_file is nil, that represents a deletion.
208
+
209
+ After one or more patches have been generated, they should be
210
+ applied to orig_file using apply_to. This will prevent some other
211
+ patch type that is called later from generating another patch that
212
+ describes the same changes.
213
+
214
+ When CloudRCS::Patch.generate is invoked, it will call the
215
+ generate method for each primitive patch class in turn. After
216
+ that, the generated patches applied to orig_file should match
217
+ changed_file exactly.
218
+
219
+ parse(contents) :
220
+
221
+ Given a string representation of this patch type, parse returns a
222
+ new instance of this class with the same information contained in
223
+ the string representation. parse must be able to parse any string
224
+ representation outputted by the to_s method, and any output
225
+ generated by to_s must be parsable by parse.
226
+
227
+ You can also optionally define a class method called priority. This
228
+ method should return an integer. When CloudRCS::Patch.generate is
229
+ called, it will call the generate method of each patch type in turn,
230
+ ordered by the values returned by the priority method of each patch
231
+ type. So if your patch type is likely to conflict with other patch
232
+ types if is applied early in the process, then set its priority method
233
+ to a high value. Alternately, if it is important that the patch type
234
+ be processed early, then assign it a low priority.
235
+
236
+ To provide an example, addfile patches should always be generated
237
+ before hunks, which should be generated before rmfile. So addfile has
238
+ a low priority of 10, hunk has the default priority of 50, and rmfile
239
+ has a high priority of 90.
240
+
241
+ Finally, to inform CloudRCS of the existence of the new patch type,
242
+ this line must be executed:
243
+
244
+ CloudRCS::PATCH_TYPES << NewPatchType
245
+
246
+ where NewPatchType should be replaced with the new class.
247
+
248
+ In the CloudRCS gem, patch types are kept under
249
+ lib/cloud_rcs/patch_types/.
250
+
251
+
252
+ == REQUIREMENTS:
253
+
254
+ * activerecord
255
+ * diff-lcs
256
+
257
+
258
+ == ADDITIONAL BUILD-TIME REQUIREMENTS:
259
+
260
+ * hoe
261
+ * newgem
262
+ * trowel
263
+
264
+
265
+ == INSTALL FROM SOURCE:
266
+
267
+ sudo rake install_gem
268
+
269
+
270
+ == LICENSE:
271
+
272
+ (The MIT License)
273
+
274
+ Copyright (c) 2008 Jesse Hallett <hallettj@gmail.com>
275
+
276
+ Permission is hereby granted, free of charge, to any person obtaining
277
+ a copy of this software and associated documentation files (the
278
+ 'Software'), to deal in the Software without restriction, including
279
+ without limitation the rights to use, copy, modify, merge, publish,
280
+ distribute, sublicense, and/or sell copies of the Software, and to
281
+ permit persons to whom the Software is furnished to do so, subject to
282
+ the following conditions:
283
+
284
+ The above copyright notice and this permission notice shall be
285
+ included in all copies or substantial portions of the Software.
286
+
287
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
288
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
289
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
290
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
291
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
292
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
293
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
data/config/hoe.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'cloudrcs/version'
2
+
3
+ AUTHOR = 'Jesse Hallett' # can also be an array of Authors
4
+ EMAIL = "hallettj@gmail.com"
5
+ DESCRIPTION = "A Ruby clone of darcs that uses ActiveRecord for storing patches."
6
+ GEM_NAME = 'cloudrcs' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'cloudrcs' # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+ EXTRA_DEPENDENCIES = [
11
+ ['activerecord', '>= 2.0'],
12
+ ['diff-lcs', '>= 1.1']
13
+ # ['activesupport', '>= 1.3.1']
14
+ ] # An array of rubygem dependencies [name, version]
15
+
16
+ @config_file = "~/.rubyforge/user-config.yml"
17
+ @config = nil
18
+ RUBYFORGE_USERNAME = "unknown"
19
+ def rubyforge_username
20
+ unless @config
21
+ begin
22
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
23
+ rescue
24
+ puts <<-EOS
25
+ ERROR: No rubyforge config file found: #{@config_file}
26
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
27
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
28
+ EOS
29
+ exit
30
+ end
31
+ end
32
+ RUBYFORGE_USERNAME.replace @config["username"]
33
+ end
34
+
35
+
36
+ REV = nil
37
+ # UNCOMMENT IF REQUIRED:
38
+ # REV = YAML.load(`svn info`)['Revision']
39
+ VERS = Cloudrcs::VERSION::STRING + (REV ? ".#{REV}" : "")
40
+ RDOC_OPTS = ['--quiet', '--title', 'cloudrcs documentation',
41
+ "--opname", "index.html",
42
+ "--line-numbers",
43
+ "--main", "README",
44
+ "--inline-source"]
45
+
46
+ class Hoe
47
+ def extra_deps
48
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
49
+ @extra_deps
50
+ end
51
+ end
52
+
53
+ # Generate all the Rake tasks
54
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
55
+ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
56
+ p.developer(AUTHOR, EMAIL)
57
+ p.description = DESCRIPTION
58
+ p.summary = DESCRIPTION
59
+ p.url = HOMEPATH
60
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
61
+ p.test_globs = ["test/**/test_*.rb"]
62
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
63
+
64
+ # == Optional
65
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
66
+ #p.extra_deps = EXTRA_DEPENDENCIES
67
+
68
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
69
+ end
70
+
71
+ CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
72
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
73
+ $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
74
+ $hoe.rsync_args = '-av --delete --ignore-errors'
75
+ $hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
@@ -0,0 +1,15 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))