hallettj-cloudrcs 0.0.1

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.
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]))