cvs-wrapper 0.7.3

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cvs.rb +275 -0
  3. metadata +85 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cf936586217065cc4fee3222a42f6a765ee03cf9
4
+ data.tar.gz: 5d0c68da301692411ba216bdcbc19bd8c1a4f2e4
5
+ SHA512:
6
+ metadata.gz: ed68440560a1d9a220322e3220fa114b0b71ede57e39e77995942e9996c52f07a2b7d45c6ae9ad3a120fd398421d5dce6b2721e22432b1e07cbb21cf2ad45d2e
7
+ data.tar.gz: 86590674d08510c4b6e554519b8008dd1d9cfa96ad05104d027a992d09a554cb50dd958bae272fd6e0c56e60f008b6d48f5c5311c4c208faebeb59155e804d56
@@ -0,0 +1,275 @@
1
+ require 'logger'
2
+ require 'tempfile'
3
+ require 'childprocess'
4
+ require 'pathname'
5
+
6
+ class CVSOperationError < StandardError; end
7
+
8
+ class CVS
9
+
10
+ HEAD = 'HEAD'
11
+
12
+ def initialize(log=nil)
13
+ @logger = log || Logger.new(STDOUT)
14
+ @settings = {
15
+ :basedir => '.',
16
+ :root => '',
17
+ :executable => '/usr/bin/cvs',
18
+ :default_branch => 'HEAD',
19
+ :timeout => 300
20
+ }
21
+
22
+ end
23
+
24
+ # wrapper around cvs common tasks
25
+ def root
26
+ settings[:basedir]
27
+ end
28
+
29
+ def settings
30
+ return @settings
31
+ end
32
+
33
+ def add(filename)
34
+ check_file filename
35
+ parts = filename.split('/')
36
+ parent = parts.shift
37
+ file = parts.join '/'
38
+ file = '' if file.nil?
39
+ cmd = [cvs, '-d',cvsroot,'add', file]
40
+ return execute_command cmd, File.join(root, parent)
41
+ end
42
+
43
+ def remove(filename)
44
+ check_file filename
45
+ parts = filename.split('/')
46
+ parent = parts.shift
47
+ file = parts.join '/'
48
+ file_path = File.join(root, filename)
49
+ File.delete(file_path) if File.exists?(file_path)
50
+ cmd = [cvs,'-d',cvsroot,'remove',file]
51
+ return execute_command cmd, File.join(root, parent)
52
+ end
53
+
54
+ def co(file_name, branch = '')
55
+ @logger.debug('The method co is deprecated. Please change to the "checkout" method!')
56
+ check_CVSROOT()
57
+ cmd = [cvs,'-d',cvsroot, 'co']
58
+ cmd += ['-r', branch] unless ['', HEAD].include?(branch)
59
+ cmd.push file_name
60
+ return execute_command cmd
61
+ end
62
+
63
+ def checkout(file_name, options={})
64
+ check_CVSROOT()
65
+ cmd = [cvs,'-d',cvsroot, 'co']
66
+ cmd += ['-D', options[:timestamp] ] if options[:timestamp]
67
+ cmd += ['-r',options[:branch] ] if options[:branch] and not ['', HEAD].include?(options[:branch])
68
+ cmd.push file_name
69
+ execute_command(cmd, options[:basedir])
70
+ end
71
+
72
+ def rtag(file_name, tag_name, options={})
73
+ check_CVSROOT()
74
+ cmd = [cvs,'-d', cvsroot, 'rtag']
75
+ cmd += ['-b'] if options[:branch]
76
+ cmd.push tag_name
77
+ cmd.push file_name
78
+ execute_command(cmd, options[:basedir])
79
+ end
80
+
81
+ def commit(file_name, comment)
82
+ check_CVSROOT()
83
+ check_file(file_name) unless file_name.nil?
84
+ cmd = [cvs, '-d', cvsroot, 'commit', '-m', comment]
85
+ cmd.push(file_name) unless file_name.nil?
86
+ execute_command cmd
87
+ end
88
+
89
+ def config
90
+ yield @settings, @logger if block_given?
91
+ self
92
+ end
93
+
94
+ def reset_settings
95
+ @settings = {
96
+ :basedir => '.',
97
+ :root => '',
98
+ :executable => '/usr/bin/cvs',
99
+ :default_branch => 'HEAD',
100
+ :timeout => 300
101
+ }
102
+ end
103
+
104
+ def status(file_name)
105
+ check_CVSROOT()
106
+ check_file(file_name)
107
+ cmd = [cvs, '-d', cvsroot, 'status', file_name]
108
+ execute_command cmd
109
+ end
110
+
111
+ def current_branch(file_name)
112
+ check_file(file_name)
113
+ status = status(file_name).split("\n")
114
+ result = status.grep(/Tag/) do |line|
115
+ if line.include? 'none' then
116
+ rev = status.grep(/Repository revision/) { |repo_revision| repo_revision.split()[2]}[0]
117
+ return HEAD, rev
118
+ end
119
+ parts = line.split(':')
120
+ branch = parts[1].strip.scan(/(.*)\(branch/)[0][0].strip
121
+ branch_revision = parts[2].strip.scan(/(.*)\)/)[0][0].strip
122
+ return branch, branch_revision
123
+ end
124
+ return result
125
+ end
126
+
127
+ def current_revision(file_name)
128
+ check_file(file_name)
129
+ status(file_name).split("\n").grep(/Repository revision/) {|repo_revision| repo_revision.split()[2]}[0]
130
+ end
131
+
132
+ def previous_revision(file_name)
133
+ check_file(file_name)
134
+ calculate_previous_revision(current_revision(file_name))
135
+ end
136
+
137
+ def calculate_previous_revision(current_rev)
138
+ return '1.1' if current_rev.nil? or current_rev == 'NONE'
139
+ parts = current_rev.split('.')
140
+ last_index = parts.length-1
141
+ parts[last_index] = Integer(parts[last_index]) - 1
142
+ if parts[last_index] == 0 and last_index >= 3 then
143
+ #when it is a branch or a branch of a branch
144
+ parts.delete_at(last_index)
145
+ parts.delete_at(last_index-1)
146
+ end
147
+
148
+ #when you try to go to a previous version on head and there is no "go back" possible return 1.1
149
+ return '1.1' if parts[last_index] == 0 and last_index == 2
150
+ return parts.join('.')
151
+ end
152
+
153
+ def update(file_name, branch)
154
+ full_name = File.join(root(), file_name)
155
+ if File.exists? full_name then
156
+ File.delete full_name
157
+ end
158
+ co(file_name, branch)
159
+ end
160
+
161
+ def last_diff(file_name, base_rev=nil)
162
+ if base_rev.nil? or base_rev == 'NONE' then
163
+ rev = current_revision(file_name)
164
+ else
165
+ rev = base_rev
166
+ end
167
+ previous_rev = calculate_previous_revision(rev)
168
+ return diff(previous_rev, rev, file_name)
169
+ end
170
+
171
+ def diff(from_rev, to_rev, file_name)
172
+ check_CVSROOT()
173
+ cmd = [cvs, '-d', cvsroot, 'rdiff', '-u', '-r', from_rev, '-r', to_rev, file_name]
174
+ execute_command cmd
175
+ end
176
+
177
+ def apply_patch(file_name, patch_file)
178
+ cmd = ['patch', file_name, patch_file]
179
+ execute_command cmd
180
+ end
181
+
182
+ def apply_patch_to_root(patch_file)
183
+ cmd = ['patch', '<', patch_file]
184
+ execute_command cmd
185
+ end
186
+
187
+ def get_file_content(file_name, revision, basedir=nil)
188
+ cmd = [cvs, '-d', cvsroot, 'co', '-r', revision, file_name]
189
+ execute_command cmd , basedir
190
+ working_dir = basedir.nil? ? root : basedir
191
+ full_path = File.join(working_dir, file_name)
192
+ File.open(full_path, 'r').read
193
+ end
194
+
195
+ def get_file_content_as_binary(file_name, revision, basedir=nil)
196
+ cmd = [cvs, '-d', cvsroot, 'co', '-r', revision, file_name]
197
+ execute_command cmd , basedir
198
+ working_dir = basedir.nil? ? root : basedir
199
+ full_path = File.join(working_dir, file_name)
200
+ File.open(full_path, 'rb').read
201
+ end
202
+
203
+ def check_file(file_name)
204
+ target_file = File.join(root(), file_name)
205
+ unless File.exists?(target_file)
206
+ @logger.warn "Could not find #{target_file}. Are you sure you have set the correct CVS basedir?"
207
+ end
208
+ end
209
+
210
+ def check_CVSROOT
211
+ raise CVSOperationError, 'No CVSROOT specified!' if cvsroot.empty?
212
+ end
213
+
214
+ def cvsroot
215
+ @settings[:root]
216
+ end
217
+
218
+ def default_branch
219
+ return HEAD
220
+ end
221
+
222
+ def branch_module(sub_module, branch, basedir=nil)
223
+ cmd = [cvs, '-d', cvsroot, 'rtag', '-b', branch, sub_module]
224
+ execute_command cmd , basedir
225
+ end
226
+
227
+ def cvs
228
+ settings[:executable]
229
+ end
230
+
231
+ def execute_command(cmd, basedir = nil, timeout=nil)
232
+ basedir = basedir.nil? ? root : basedir
233
+ @logger.debug("Executing command #{cmd.join(' ')} | CWD: #{basedir}")
234
+ command_timeout = timeout || settings[:timeout]
235
+ out = Tempfile.new('cvs_cmd')
236
+ process = ChildProcess.build(*cmd)
237
+ process.cwd = basedir
238
+ process.io.stdout = process.io.stderr = out
239
+ process.start
240
+ process.poll_for_exit(command_timeout)
241
+ out.rewind
242
+ result = out.read
243
+ raise CVSOperationError, "Could not successfully execute command '#{cmd}'\n#{result}" if process.exit_code != 0
244
+ result
245
+ rescue ChildProcess::TimeoutError
246
+ raise CVSOperationError, "TIMEOUT[#{command_timeout}]! Could not successfully execute command '#{cmd}'"
247
+ ensure
248
+ out.close if out
249
+ out.unlink if out
250
+ end
251
+
252
+ def import(module_dir)
253
+ raise "Please specify the module_directory" unless Dir.exists?(module_dir)
254
+ absolute_path = File.absolute_path(module_dir)
255
+ module_name = Pathname.new(absolute_path).basename.to_s
256
+ cmd = [cvs,'-d', cvsroot, 'import', '-m', "Created module #{module_name}", module_name, "INITIAL", "start"]
257
+ execute_command cmd , absolute_path
258
+ end
259
+
260
+ end
261
+
262
+ def CVS.init(dir, cvs_exec="/usr/bin/cvs", logger=nil)
263
+ raise "Directory #{dir} does not exist! Please create it first!" unless Dir.exists?(dir)
264
+ raise "Could not find executable #{cvs_exec}! Do you have CVS installed!" unless File.exists?(cvs_exec)
265
+ cvs = CVS.new(logger).config do |settings|
266
+ settings[:basedir] = dir
267
+ settings[:root] = dir
268
+ settings[:executable] = cvs_exec
269
+ end
270
+ cmd = [cvs_exec, '-d', dir, "init"]
271
+ cvs.execute_command(cmd)
272
+ yield cvs if block_given?
273
+ cvs
274
+ end
275
+
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cvs-wrapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.3
5
+ platform: ruby
6
+ authors:
7
+ - Fabio Neves
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: childprocess
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.5.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.5.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: A simple wrapper around CVS command line tool
56
+ email: infrastructure@datalex.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - lib/cvs.rb
62
+ homepage: https://github.com/datalex-opensource/cvs-wrapper
63
+ licenses: []
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.2.2
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: a cvs command line wrapper
85
+ test_files: []