rscm 0.3.4 → 0.3.5
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/CHANGES +11 -1
- data/README +1 -1
- data/Rakefile +3 -2
- data/lib/rscm/base.rb +17 -4
- data/lib/rscm/better.rb +0 -4
- data/lib/rscm/historic_file.rb +22 -0
- data/lib/rscm/logging.rb +0 -11
- data/lib/rscm/revision_file.rb +7 -0
- data/lib/rscm/scm/cvs.rb +14 -4
- data/lib/rscm/scm/subversion.rb +36 -28
- data/lib/rscm.rb +1 -0
- data/test/rscm/generic_scm_tests.rb +15 -2
- metadata +3 -2
data/CHANGES
CHANGED
@@ -1,11 +1,21 @@
|
|
1
1
|
= RSCM Changelog
|
2
2
|
|
3
|
+
== Version 0.3.5
|
4
|
+
|
5
|
+
This release adds new API methods for accessing files and their revisions and contents.
|
6
|
+
|
7
|
+
* Added new scm.history_file method (returning RSCM::HistoryFile).
|
8
|
+
* Added RSCM::HistoryFile.revision_files methods to get all revisions of a file.
|
9
|
+
* Added RSCM::RevisionFile.open to get the contents of a specific revision of a file.
|
10
|
+
* Set defaults for Subversion username/password
|
11
|
+
* Removed logging code (may reintroduce later if I come up with a better way to configure it)
|
12
|
+
|
3
13
|
== Version 0.3.4
|
4
14
|
|
5
15
|
This release fixes some bugs on windows.
|
6
16
|
|
7
17
|
* Removed redirection to dev/null for CVS commands. 2>nul didn't seem to work on windows.
|
8
|
-
* Fixed
|
18
|
+
* Fixed the path to touch.exe (needed in tests)
|
9
19
|
|
10
20
|
== Version 0.3.3
|
11
21
|
|
data/README
CHANGED
data/Rakefile
CHANGED
@@ -10,7 +10,7 @@ require 'meta_project'
|
|
10
10
|
|
11
11
|
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
12
12
|
PKG_NAME = 'rscm'
|
13
|
-
PKG_VERSION = '0.3.
|
13
|
+
PKG_VERSION = '0.3.5' + PKG_BUILD
|
14
14
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
15
15
|
|
16
16
|
desc "Default Task"
|
@@ -134,7 +134,8 @@ task :release_files => [:gem] do
|
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
|
-
|
137
|
+
desc "Publish docs/website"
|
138
|
+
task :publish_doc do
|
138
139
|
publisher = Rake::RubyForgePublisher.new(PKG_NAME, ENV['RUBYFORGE_USER'])
|
139
140
|
publisher.upload
|
140
141
|
end
|
data/lib/rscm/base.rb
CHANGED
@@ -20,6 +20,7 @@ module RSCM
|
|
20
20
|
# * move
|
21
21
|
# * revisions
|
22
22
|
# * uptodate?
|
23
|
+
# * file
|
23
24
|
#
|
24
25
|
# In addition to operations related to working copies, the same instance should provide
|
25
26
|
# methods to administer the working copy's associated 'central' repository. These are:
|
@@ -77,8 +78,14 @@ module RSCM
|
|
77
78
|
|
78
79
|
public
|
79
80
|
|
80
|
-
|
81
|
+
def checkout_dir=(dir)
|
82
|
+
@checkout_dir = PathConverter.filepath_to_nativepath(dir, false)
|
83
|
+
end
|
81
84
|
|
85
|
+
def checkout_dir
|
86
|
+
@checkout_dir
|
87
|
+
end
|
88
|
+
|
82
89
|
def to_yaml_properties
|
83
90
|
props = instance_variables
|
84
91
|
props.delete("@checkout_dir")
|
@@ -144,7 +151,7 @@ module RSCM
|
|
144
151
|
# Commit (check in) modified files.
|
145
152
|
def commit(message)
|
146
153
|
end
|
147
|
-
|
154
|
+
|
148
155
|
# Checks out or updates contents from a central SCM to +checkout_dir+ - a local working copy.
|
149
156
|
# If this is a distributed SCM, this method should create a 'working copy' repository
|
150
157
|
# if one doesn't already exist. Then the contents of the central SCM should be pulled into
|
@@ -186,9 +193,10 @@ module RSCM
|
|
186
193
|
end
|
187
194
|
|
188
195
|
# Returns a Revisions object for the period specified by +from_identifier+ (exclusive, i.e. after)
|
189
|
-
# and +to_identifier+ (inclusive).
|
196
|
+
# and +to_identifier+ (inclusive). If +relative_path+ is specified, the result will only contain
|
197
|
+
# revisions pertaining to that path.
|
190
198
|
#
|
191
|
-
def revisions(from_identifier, to_identifier=Time.infinity)
|
199
|
+
def revisions(from_identifier, to_identifier=Time.infinity, relative_path=nil)
|
192
200
|
# Should be overridden by subclasses
|
193
201
|
revisions = Revisions.new
|
194
202
|
revisions.add(
|
@@ -206,6 +214,11 @@ module RSCM
|
|
206
214
|
)
|
207
215
|
revisions
|
208
216
|
end
|
217
|
+
|
218
|
+
# Returns a HistoricFile for +relative_path+
|
219
|
+
def file(relative_path)
|
220
|
+
HistoricFile.new(relative_path, self)
|
221
|
+
end
|
209
222
|
|
210
223
|
# Whether the working copy is in synch with the central
|
211
224
|
# repository's revision/time identified by +identifier+.
|
data/lib/rscm/better.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
module RSCM
|
2
|
+
# Represents the full history of a single file
|
3
|
+
class HistoricFile
|
4
|
+
def initialize(relative_path, scm)
|
5
|
+
@relative_path, @scm = relative_path, scm
|
6
|
+
end
|
7
|
+
|
8
|
+
# Returns an Array of RevisionFile - from Time.epoch until Time.infinity (now)
|
9
|
+
def revision_files
|
10
|
+
@scm.revisions(Time.epoch, Time.infinity, @relative_path).collect do |revision|
|
11
|
+
if revision.files.length != 1
|
12
|
+
files_s = revision.files.collect{|f| f.to_s}.join("\n")
|
13
|
+
raise "The file-specific revision didn't have exactly one file, but #{revision.files.length}:\n#{files_s}"
|
14
|
+
end
|
15
|
+
if(revision.files[0].path != @relative_path)
|
16
|
+
raise "The file-specific revision didn't have expected path #{@relative_path}, but #{revision.files[0].path}"
|
17
|
+
end
|
18
|
+
revision.files[0]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/rscm/logging.rb
CHANGED
@@ -6,14 +6,3 @@ if(WINDOWS)
|
|
6
6
|
else
|
7
7
|
HOMEDIR = ENV['HOME']
|
8
8
|
end
|
9
|
-
|
10
|
-
begin
|
11
|
-
RSCM_DEFAULT_LOGGER = Logger.new("#{HOMEDIR}/.rscm.log")
|
12
|
-
rescue StandardError
|
13
|
-
RSCM_DEFAULT_LOGGER = Logger.new(STDERR)
|
14
|
-
RSCM_DEFAULT_LOGGER.level = Logger::WARN
|
15
|
-
RSCM_DEFAULT_LOGGER.warn(
|
16
|
-
"RSCM Error: Unable to access log file. Please ensure that #{HOMEDIR}/.rscm.log exists and is chmod 0666. " +
|
17
|
-
"The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
|
18
|
-
)
|
19
|
-
end
|
data/lib/rscm/revision_file.rb
CHANGED
@@ -20,10 +20,17 @@ module RSCM
|
|
20
20
|
attr_accessor :message
|
21
21
|
# This is a UTC ruby time
|
22
22
|
attr_accessor :time
|
23
|
+
attr_accessor :scm
|
23
24
|
|
24
25
|
def initialize(path=nil, status=nil, developer=nil, message=nil, native_revision_identifier=nil, time=nil)
|
25
26
|
@path, @developer, @message, @native_revision_identifier, @time, @status = path, developer, message, native_revision_identifier, time, status
|
26
27
|
end
|
28
|
+
|
29
|
+
# Returns/yields an IO containing the contents of this file, using +scm+ this
|
30
|
+
# file lives in.
|
31
|
+
def open(scm, &block)
|
32
|
+
scm.open(self, &block)
|
33
|
+
end
|
27
34
|
|
28
35
|
def accept(visitor)
|
29
36
|
visitor.visit_file(self)
|
data/lib/rscm/scm/cvs.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'stringio'
|
1
2
|
require 'rscm/base'
|
2
3
|
require 'rscm/path_converter'
|
3
4
|
require 'rscm/line_editor'
|
@@ -91,9 +92,9 @@ module RSCM
|
|
91
92
|
files.empty?
|
92
93
|
end
|
93
94
|
|
94
|
-
def revisions(from_identifier, to_identifier=Time.infinity)
|
95
|
+
def revisions(from_identifier, to_identifier=Time.infinity, relative_path=nil)
|
95
96
|
checkout(to_identifier) unless uptodate?(to_identifier) # must checkout to get revisions
|
96
|
-
parse_log(changes_command(from_identifier, to_identifier))
|
97
|
+
parse_log(changes_command(from_identifier, to_identifier, relative_path))
|
97
98
|
end
|
98
99
|
|
99
100
|
def diff(change)
|
@@ -112,6 +113,15 @@ module RSCM
|
|
112
113
|
end
|
113
114
|
end
|
114
115
|
|
116
|
+
def open(revision_file, &block)
|
117
|
+
with_working_dir(@checkout_dir) do
|
118
|
+
diff_cmd = "cvs -Q update -p -r #{revision_file.native_revision_identifier} #{revision_file.path}"
|
119
|
+
Better.popen(diff_cmd) do |io|
|
120
|
+
block.call io
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
115
125
|
def apply_label(label)
|
116
126
|
cvs(@checkout_dir, "tag -c #{label}")
|
117
127
|
end
|
@@ -241,10 +251,10 @@ module RSCM
|
|
241
251
|
revisions
|
242
252
|
end
|
243
253
|
|
244
|
-
def changes_command(from_identifier, to_identifier)
|
254
|
+
def changes_command(from_identifier, to_identifier, relative_path)
|
245
255
|
# https://www.cvshome.org/docs/manual/cvs-1.11.17/cvs_16.html#SEC144
|
246
256
|
# -N => Suppress the header if no RevisionFiles are selected.
|
247
|
-
"log #{branch_option} -N #{period_option(from_identifier, to_identifier)}"
|
257
|
+
"log #{branch_option} -N #{period_option(from_identifier, to_identifier)} #{relative_path}"
|
248
258
|
end
|
249
259
|
|
250
260
|
def branch_specified?
|
data/lib/rscm/scm/subversion.rb
CHANGED
@@ -20,6 +20,10 @@ module RSCM
|
|
20
20
|
ann :tip => "If you use ssh, specify the URL as svn+ssh://username@server/path/to/repo"
|
21
21
|
attr_accessor :url
|
22
22
|
|
23
|
+
ann :description => "Path"
|
24
|
+
ann :tip => "You only need to specify this if you want to be able to automatically create the repository. This should be the relative path from the start of the repository <br>to the end of the URL. For example, if your URL is <br>svn://your.server/path/to/repository/path/within/repository <br>then this value should be path/within/repository."
|
25
|
+
attr_accessor :path
|
26
|
+
|
23
27
|
ann :description => "Username"
|
24
28
|
ann :tip => "This only applies to svn:// URLs."
|
25
29
|
attr_accessor :username
|
@@ -28,12 +32,14 @@ module RSCM
|
|
28
32
|
ann :tip => "This only applies to svn:// URLs."
|
29
33
|
attr_accessor :password
|
30
34
|
|
31
|
-
ann :description => "Path"
|
32
|
-
ann :tip => "You only need to specify this if you want to be able to automatically create the repository. This should be the relative path from the start of the repository <br>to the end of the URL. For example, if your URL is <br>svn://your.server/path/to/repository/path/within/repository <br>then this value should be path/within/repository."
|
33
|
-
attr_accessor :path
|
34
|
-
|
35
35
|
def initialize(url="", path="")
|
36
36
|
@url, @path = url, path
|
37
|
+
@username = ""
|
38
|
+
@password = ""
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_yaml_properties
|
42
|
+
["@url", "@password", "@username", "@password"]
|
37
43
|
end
|
38
44
|
|
39
45
|
def add(relative_filename)
|
@@ -70,10 +76,13 @@ module RSCM
|
|
70
76
|
absolute_path = PathConverter.nativepath_to_filepath(native_absolute_path)
|
71
77
|
if(File.exist?(absolute_path) && !File.directory?(absolute_path))
|
72
78
|
native_checkout_dir = PathConverter.filepath_to_nativepath(@checkout_dir, false)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
79
|
+
relative_path = nil
|
80
|
+
if WINDOWS
|
81
|
+
relative_path = native_absolute_path[native_checkout_dir.length+1..-1].chomp
|
82
|
+
relative_path = relative_path.gsub(/\\/, "/")
|
83
|
+
else
|
84
|
+
relative_path = absolute_path
|
85
|
+
end
|
77
86
|
checked_out_files << relative_path
|
78
87
|
yield relative_path if block_given?
|
79
88
|
end
|
@@ -83,14 +92,6 @@ module RSCM
|
|
83
92
|
checked_out_files
|
84
93
|
end
|
85
94
|
|
86
|
-
def checkout_commandline
|
87
|
-
"svn checkout #{revision_option(nil)}"
|
88
|
-
end
|
89
|
-
|
90
|
-
def update_commandline
|
91
|
-
"svn update #{url} #{checkout_dir}"
|
92
|
-
end
|
93
|
-
|
94
95
|
def uptodate?(identifier)
|
95
96
|
if(!checked_out?)
|
96
97
|
false
|
@@ -112,12 +113,18 @@ module RSCM
|
|
112
113
|
|
113
114
|
def diff(file, &block)
|
114
115
|
with_working_dir(@checkout_dir) do
|
115
|
-
cmd = "svn diff
|
116
|
+
cmd = "svn diff --revision #{file.previous_native_revision_identifier}:#{file.native_revision_identifier} \"#{url}/#{file.path}\""
|
116
117
|
Better.popen(cmd) do |io|
|
117
118
|
return(yield(io))
|
118
119
|
end
|
119
120
|
end
|
120
121
|
end
|
122
|
+
|
123
|
+
def open(revision_file, &block)
|
124
|
+
Better.popen("svn cat --revision #{revision_file.native_revision_identifier} #{url}/#{revision_file.path}") do |io|
|
125
|
+
return(yield(io))
|
126
|
+
end
|
127
|
+
end
|
121
128
|
|
122
129
|
def can_create_central?
|
123
130
|
local?
|
@@ -190,13 +197,13 @@ module RSCM
|
|
190
197
|
svn(dir, import_cmd)
|
191
198
|
end
|
192
199
|
|
193
|
-
def revisions(from_identifier, to_identifier=Time.infinity)
|
200
|
+
def revisions(from_identifier, to_identifier=Time.infinity, relative_path="")
|
194
201
|
# Return empty revision if the requested revision doesn't exist yet.
|
195
202
|
return Revisions.new if(from_identifier.is_a?(Integer) && head_revision_identifier <= from_identifier)
|
196
203
|
|
197
204
|
checkout_dir = PathConverter.filepath_to_nativepath(@checkout_dir, false)
|
198
205
|
revisions = nil
|
199
|
-
command = "svn #{changes_command(from_identifier, to_identifier)}"
|
206
|
+
command = "svn #{changes_command(from_identifier, to_identifier, relative_path)}"
|
200
207
|
|
201
208
|
with_working_dir(@checkout_dir) do
|
202
209
|
Better.popen(command) do |stdout|
|
@@ -300,28 +307,29 @@ module RSCM
|
|
300
307
|
end
|
301
308
|
|
302
309
|
def checkout_command(to_identifier)
|
303
|
-
|
304
|
-
"
|
310
|
+
cd = "\"#{checkout_dir}\""
|
311
|
+
raise "checkout_dir not set" if cd == ""
|
312
|
+
"checkout #{login_options} #{url} #{cd} #{revision_option(nil,to_identifier)}"
|
305
313
|
end
|
306
314
|
|
307
315
|
def update_command(to_identifier)
|
308
316
|
"update #{login_options} #{revision_option(nil,to_identifier)}"
|
309
317
|
end
|
310
318
|
|
311
|
-
def changes_command(from_identifier, to_identifier)
|
319
|
+
def changes_command(from_identifier, to_identifier, relative_path)
|
312
320
|
# http://svnbook.red-bean.com/svnbook-1.1/svn-book.html#svn-ch-3-sect-3.3
|
313
321
|
# file_list = files.join('\n')
|
314
|
-
|
315
|
-
cmd = "log --verbose #{login_options} #{revision_option(from_identifier, to_identifier)} #{
|
322
|
+
full_url = relative_path ? "#{url}/#{relative_path}" : ""
|
323
|
+
cmd = "log --verbose #{login_options} #{revision_option(from_identifier, to_identifier)} #{full_url}"
|
316
324
|
cmd
|
317
325
|
end
|
318
326
|
|
319
327
|
def login_options
|
320
328
|
result = ""
|
321
|
-
u = @username ? @username.strip :
|
322
|
-
p = @password ? @password.strip :
|
323
|
-
result << "--username #{u} "
|
324
|
-
result << "--password #{p} "
|
329
|
+
u = @username ? @username.strip : ""
|
330
|
+
p = @password ? @password.strip : "
|
331
|
+
result << "--username #{u} " unless u == ""
|
332
|
+
result << "--password #{p} " unless p == ""
|
325
333
|
result
|
326
334
|
end
|
327
335
|
|
data/lib/rscm.rb
CHANGED
@@ -10,7 +10,12 @@ module RSCM
|
|
10
10
|
|
11
11
|
def teardown
|
12
12
|
if @scm
|
13
|
-
|
13
|
+
begin
|
14
|
+
@scm.destroy_centra
|
15
|
+
rescue => e
|
16
|
+
# Fails on windows with TortoiseCVS' cvs because of resident cvslock.exe
|
17
|
+
STDERR.puts "Couldn't destroy central #{@scm.class.name}"
|
18
|
+
end
|
14
19
|
end
|
15
20
|
end
|
16
21
|
|
@@ -252,7 +257,7 @@ module RSCM
|
|
252
257
|
+five six
|
253
258
|
EOF
|
254
259
|
|
255
|
-
def
|
260
|
+
def test_diffs_and_historic_file
|
256
261
|
work_dir = RSCM.new_temp_dir("diff")
|
257
262
|
checkout_dir = "#{work_dir}/checkout"
|
258
263
|
repository_dir = "#{work_dir}/repository"
|
@@ -302,6 +307,14 @@ EOF
|
|
302
307
|
assert_match(/^\+five six/, diff_string)
|
303
308
|
end
|
304
309
|
assert(got_diff)
|
310
|
+
|
311
|
+
# TODO: make separate test. Make helper method for the cumbersome setup!
|
312
|
+
historic_afile = scm.file("afile.txt")
|
313
|
+
revision_files = historic_afile.revision_files
|
314
|
+
assert_equal(Array, revision_files.class)
|
315
|
+
assert(revision_files.length >= 2)
|
316
|
+
assert(revision_files.length <= 3)
|
317
|
+
assert_equal("one two three four\nfive six\n", revision_files[-1].open(scm){|io| io.read})
|
305
318
|
end
|
306
319
|
|
307
320
|
private
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rscm
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.3.
|
7
|
-
date: 2005-
|
6
|
+
version: 0.3.5
|
7
|
+
date: 2005-10-05 00:00:00 -04:00
|
8
8
|
summary: "RSCM - Ruby Source Control Management"
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -39,6 +39,7 @@ files:
|
|
39
39
|
- lib/rscm/base.rb
|
40
40
|
- lib/rscm/better.rb
|
41
41
|
- lib/rscm/difftool.rb
|
42
|
+
- lib/rscm/historic_file.rb
|
42
43
|
- lib/rscm/line_editor.rb
|
43
44
|
- lib/rscm/logging.rb
|
44
45
|
- lib/rscm/mockit.rb
|