fact 0.1.1.a → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1 +1,3 @@
1
1
  *~
2
+ .*.swp
3
+ ruby.vim
data/README.md CHANGED
@@ -2,7 +2,7 @@ Purpose and features
2
2
  ====================
3
3
 
4
4
  FireAphisClearerTool (FACT) is a small project intended to make a life
5
- with ClearCase a little bit happier. The project tries to achieve the
5
+ with ClearCase UCM a little bit happier. The project tries to achieve the
6
6
  goal in two ways:
7
7
 
8
8
  1. Create an intuitive front end for IBM Rational ClearCase SCM.
@@ -26,6 +26,7 @@ This tool allows to perform the most common tasks in minimal amount of
26
26
  clicks and supplies only the necessary information in the most readable
27
27
  format, I could think of. Hope you will enjoy it too.
28
28
 
29
+ The tool is intended for the UCM version of ClearCase.
29
30
 
30
31
  CLI
31
32
  ---
@@ -37,13 +38,28 @@ key presses and without the need to remember numerous commands.
37
38
  Here's the current menus hierarchy of the CLI mode:
38
39
 
39
40
  ```
40
- Undelivered activities
41
+ |
42
+ +-- Create and set an activity
43
+ |
44
+ +-- Browse undelivered activities
45
+ | |
46
+ | +-- Activity change set
47
+ | |
48
+ | +-- File information
49
+ | |
50
+ | +-- Change set predecessor diff
51
+ |
52
+ +-- Browse hijacked files
41
53
  |
42
- --- Activity change set
43
- |
44
- --- File information
45
- |
46
- --- Change set predecessor diff
54
+ +-- List of hijacked files
55
+ | |
56
+ | +-- VOB version diff
57
+ | |
58
+ | +-- Undo hijack of a single file
59
+ | |
60
+ | +-- Check out and keep the changes of a single hijacked file
61
+ |
62
+ +-- Check out and keep the changes of all the hijacked files
47
63
  ```
48
64
 
49
65
  Dependencies
data/bin/fact CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  # FireAphisClearerTool (FACT) is a small project intended to make a life
4
- # with ClearCase a little bit happier. The project tries to achieve the
4
+ # with ClearCase UCM a little bit happier. The project tries to achieve the
5
5
  # goal in two ways:
6
6
  #
7
7
  # 1. Create an intuitive front end for IBM Rational ClearCase SCM.
@@ -21,26 +21,24 @@ require "fact"
21
21
 
22
22
  cc = Fact::ClearCase.new
23
23
 
24
- activity = Fact::Cli.choose_undelivered_activity
25
-
26
- unless activity.nil?
27
- # Come back every time to showing the files in the activity
28
- loop do
29
- file_version = Fact::Cli.choose_file_from_activity(activity)
30
-
31
- say("Fetching the file description... ")
32
- version_info = cc.get_version_info(file_version)
33
- say("Done")
34
-
35
- puts ""
36
- Fact::Cli.show_version_info(version_info)
37
-
38
- puts ""
39
- if version_info[:checkout] != "" and version_info[:checkout] != cc.get_current_view
40
- say("The file is checked out in a different view. Check it in to diff.")
41
- elsif agree("Compare with the change set predecessor?")
42
- say("Graphical diff is being opened in an external application.")
43
- cc.diff_other_version(file_version[:file], file_version[:version], version_info[:changeset_predecessor])
44
- end
45
- end
24
+ stream_name = cc.get_current_stream
25
+ exit(true) if stream_name.empty?
26
+
27
+ curr_act = cc.get_current_activity
28
+
29
+ say("You are viewing ClearCase stream <%= color('#{stream_name}', BOLD) %>")
30
+
31
+ if curr_act.empty?
32
+ say("The active activity hasn't been set. Set an activity if you wish to checkout files.")
33
+ else
34
+ say("Current activity is <%= color('#{curr_act}', BOLD) %>")
35
+ end
36
+
37
+ puts ""
38
+ choose do |menu|
39
+ menu.select_by = :index
40
+ menu.choice("Create and set an activity") { cc.create_activity(ask("Enter activity name: ")) }
41
+ menu.choice("Browse activities") { Fact::Cli.browse_actifities }
42
+ menu.choice("Browse hijacked files") { Fact::Cli.browse_hijacked }
43
+ menu.choice("Exit") { exit(true) }
46
44
  end
@@ -11,6 +11,39 @@ module Fact
11
11
 
12
12
  class Cli
13
13
 
14
+ # Browse all the undelivered activities in the current stream.
15
+ #
16
+ def Cli.browse_actifities
17
+ cc = ClearCase.new
18
+
19
+ activity = Cli.choose_undelivered_activity
20
+
21
+ unless activity.nil?
22
+ # Come back every time to showing the files in the activity
23
+ loop do
24
+ file_version = Cli.choose_file_from_activity(activity)
25
+ break if file_version.nil? # The activity doesn't contain any files
26
+
27
+ say("Fetching the file description... ")
28
+ version_info = cc.get_version_info(file_version)
29
+ say("Done")
30
+
31
+ puts ""
32
+ Cli.show_version_info(version_info)
33
+
34
+ puts ""
35
+ if version_info[:checkout] != "" and version_info[:checkout] != cc.get_current_view
36
+ say("The file is checked out in a different view. Check it in to diff.")
37
+ elsif agree("Compare with the change set predecessor?")
38
+ say("Graphical diff is being opened in an external application.")
39
+ cc.diff_versions(file_version[:file], file_version[:version], version_info[:changeset_predecessor])
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+
14
47
  # Ask the user to choose from the list of all the undelivered activities
15
48
  # in the current stream.
16
49
  # Returns the name of the chosen activity.
@@ -23,7 +56,7 @@ class Cli
23
56
  return if stream==""
24
57
 
25
58
  puts ""
26
- say("The current stream is <%= color('#{stream}', BOLD) %>. Fetching the stream activities... ")
59
+ say("Fetching the stream activities... ")
27
60
  activities = cc.get_activities
28
61
  say("Done.")
29
62
 
@@ -4,7 +4,7 @@ module Fact
4
4
 
5
5
  class ClearTool
6
6
  def invoke(command_str)
7
- return `cleartool #{command_str}`
7
+ return `cleartool #{command_str}`
8
8
  end
9
9
  end
10
10
 
@@ -32,6 +32,12 @@ class ClearCase
32
32
  return @cleartool.invoke("desc -pred -s #{create_cc_version(file,version)}").rstrip
33
33
  end
34
34
 
35
+ # Returns the name of the current activity in the current view.
36
+ #
37
+ def get_current_activity
38
+ return @cleartool.invoke("lsact -cact -s").rstrip
39
+ end
40
+
35
41
  # Get all the non-obsolete activities in the current view.
36
42
  # Returns an array of hashes. Each hash represents an activity and contains
37
43
  # two keys: :name and :headline.
@@ -40,6 +46,11 @@ class ClearCase
40
46
  return parse_lsact_output(@cleartool.invoke('lsact -fmt "%[name]p,%[headline]p,"'))
41
47
  end
42
48
 
49
+ # Creates a new activity and sets it as the active activity.
50
+ def create_activity(act_name)
51
+ @cleartool.invoke("mkact -f -headline \"#{act_name}\"")
52
+ end
53
+
43
54
  # Get version information. The argument must be a hash with keys :file and :version.
44
55
  # Returns a version info hash.
45
56
  #
@@ -90,6 +101,58 @@ class ClearCase
90
101
  return change_set
91
102
  end
92
103
 
104
+ # Get a list of the hijacked files in the current directory and all the
105
+ # subdirectories. Return a list of hashes. Each hash having keys
106
+ # :file and :version.
107
+ #
108
+ def get_hijacked_files
109
+ # Get recursively all the files in the current and child directories
110
+ ls_out = @cleartool.invoke("ls -r")
111
+
112
+ files = []
113
+
114
+ ls_out.each_line do |ls_line|
115
+ # Find all the hijacks
116
+ if ls_line =~ /(.*) \[.*hijacked.*\]/
117
+ files.push(parse_cc_version($1))
118
+ end
119
+ end
120
+
121
+ return files
122
+ end
123
+
124
+ # Undo the hijack. Return to the VOB version; save the changes in .keep file.
125
+ # Receives a list of hijacked files as a parameter. If any of the files is not
126
+ # hijacked, the behavior is undefined.
127
+ #
128
+ def undo_hijack(file_names)
129
+ @cleartool.invoke("update -rename #{file_names.join(' ')}")
130
+ end
131
+
132
+ # Chekout the hijacked files, but keep the changes. Receives a list of hijacked files
133
+ # as a parameter. If any of the files is not hijacked, the behavior is undefined.
134
+ #
135
+ def checkout_hijacked(file_names)
136
+
137
+ # Rename the .keep files for all the files that will be checked out.
138
+ # Our checkout operation will create new keep files
139
+ file_names.each { |file| backup_file(file + '.keep') if File.exists?(file + '.keep') }
140
+
141
+ @cleartool.invoke("co -nq -nc #{file_names.join(' ')}")
142
+
143
+ # The checkout operation reverts the file to the VOB version and copies the
144
+ # hijacked version to .keep file
145
+ file_names.each do |file|
146
+ keep_file = file + '.keep'
147
+
148
+ raise "Cannot find file #{file}" unless File.exists?(file)
149
+ raise "Cannot find file #{keep_file}" unless File.exists?(keep_file)
150
+
151
+ File.delete(file)
152
+ File.rename(keep_file, file)
153
+ end
154
+ end
155
+
93
156
  # Launches the default diff tool comparing two versions of a file.
94
157
  # The first parameter is the name of an existing file. The second and the third
95
158
  # parameters are strings indicating versions of the same file.
@@ -97,12 +160,19 @@ class ClearCase
97
160
  # currently on the disc. Beware that if the file is checked out from a different
98
161
  # view, the diff will compare wrong files.
99
162
  #
100
- def diff_other_version(file, version1, version2)
163
+ def diff_versions(file, version1, version2)
101
164
  ver1 = checkout_version?(version1) ? file : create_cc_version(file,version1)
102
165
  ver2 = checkout_version?(version2) ? file : create_cc_version(file,version2)
103
- #diff_process = fork { exec "cleartool diff -gra #{ver1} #{ver2}" }
104
- #Process.detach(diff_process)
105
- `cleartool diff -gra #{ver1} #{ver2}`
166
+ @cleartool.invoke("diff -gra #{ver1} #{ver2}")
167
+ end
168
+
169
+ # Launches the default diff tool comparing the local, on-disk version of a file
170
+ # with the specified vob version. The version must be a qualified vob version;
171
+ # it won't work with checked out versions.
172
+ #
173
+ def diff_vob_version(file, version)
174
+ full_version = create_cc_version(file, version)
175
+ @cleartool.invoke("diff -gra #{full_version} #{file}")
106
176
  end
107
177
 
108
178
  # Parses a string representing ClearCase element version and converts it into a hash
@@ -154,10 +224,35 @@ class ClearCase
154
224
  return activities
155
225
  end
156
226
 
227
+ MAX_BACKUP_VERSIONS = 100
228
+
229
+ # Renames the specified file to <file_name>.N where N is the lowest natural number 0<N<=MAX_BACKUP_VERSION
230
+ # for which the file <file_name>.N doesn't yet exist. If there are already files for all the numbers or if
231
+ # the original file was not found, an exception will be thrown.
232
+ #
233
+ def backup_file(file_name)
234
+ if File.exists?(file_name)
235
+ # Find a new name for the file by addining a numerical suffix
236
+ for i in 1..MAX_BACKUP_VERSIONS+1
237
+ break if !File.exists?(file_name + ".#{i}")
238
+ end
239
+ if i==MAX_BACKUP_VERSIONS+1 then raise "Apparently you have at least one hundred backups for #{file_name}. Erase some and try again." end
240
+
241
+ File.rename(file_name, file_name + ".#{i}")
242
+ else
243
+ raise "Cannot find the backed up file #{file_name}"
244
+ end
245
+ end
246
+
247
+ # Returns true if the specified version string denotes a checked out version.
248
+ #
157
249
  def checkout_version?(version)
158
250
  return version =~ /CHECKEDOUT/
159
251
  end
160
252
 
253
+ # Defines how the object will access ClearTool.
254
+ # Used for dependency injection during unit testing.
255
+ #
161
256
  def cleartool=(new_ct)
162
257
  @cleartool = new_ct
163
258
  end
@@ -10,7 +10,67 @@ module Fact
10
10
 
11
11
  class Cli
12
12
 
13
- # Format and print to stdout the specified information.
13
+ # Shows a list of all the hijacked files and allows to perform various actions
14
+ # on the files.
15
+ #
16
+ def Cli.browse_hijacked
17
+ cc = Fact::ClearCase.new
18
+
19
+ puts ""
20
+ say("Scanning for hijacked files in <%= color('#{File.absolute_path('.')}', BOLD) %>... ")
21
+ files = cc.get_hijacked_files
22
+ say("Done")
23
+
24
+ if files.empty?
25
+ say("No hijacked files.")
26
+ else
27
+ say("The hijacked files in the directory and its subdirectories are:")
28
+
29
+ # Show the hijacked files list in a menu
30
+ chosen_hijack = choose do |menu|
31
+ menu.prompt = "Choose a file: "
32
+ menu.select_by = :index
33
+
34
+ files.each do |file|
35
+ menu.choice(file[:file]) { file }
36
+ end
37
+
38
+ # Undo hijack for all the files in one command
39
+ file_names = files.collect {|f| f[:file]}
40
+ menu.choice("Keep the changes and checkout all the files") { cc.checkout_hijacked(file_names); exit(true) }
41
+
42
+ # The last entry allows graceful exit
43
+ menu.choice("Exit") { exit(true) }
44
+ end
45
+
46
+ Cli.operate_hijacked_file(chosen_hijack[:file], chosen_hijack[:version])
47
+
48
+ end
49
+ end
50
+
51
+ # Presents a list of operations that can be performed on a single hijacked file.
52
+ #
53
+ def Cli.operate_hijacked_file(file_name, original_version)
54
+ cc = Fact::ClearCase.new
55
+
56
+ puts ""
57
+ say("Hijacked file <%= color('#{file_name}', BOLD) %>")
58
+ choose do |menu|
59
+ menu.prompt = "Enter command number: "
60
+ menu.select_by = :index
61
+
62
+ menu.choice("Compare with the latest version") do
63
+ puts ""
64
+ say("Graphical diff is being opened in an external application.")
65
+ cc.diff_vob_version(file_name, original_version)
66
+ end
67
+
68
+ menu.choice("Drop the changes and renounce the hijack") { cc.undo_hijack([file_name]) }
69
+ menu.choice("Keep the changes and checkout") { cc.checkout_hijacked([file_name]) }
70
+ menu.choice("Exit") { exit(true) }
71
+ end
72
+ end
73
+
14
74
  # The parameter must be a hash with the following keys:
15
75
  #
16
76
  # :version, :name, :activity, :date, :user,
@@ -26,7 +86,7 @@ class Cli
26
86
  last_ver_text = "#{info[:version]}"
27
87
  end
28
88
 
29
- # Spliting the path and the name so the name can be shown in bold
89
+ # Splitting the path and the name so the name can be shown in bold
30
90
  path = info[:name].scan(/.*\//)[0]
31
91
  file_name = info[:name].scan(/\/[^\/]+$/)[0]
32
92
  file_name.slice!(0) # Removing the leading slash
@@ -1,3 +1,3 @@
1
1
  module Fact
2
- VERSION = "0.1.1.a"
2
+ VERSION = "0.2"
3
3
  end
@@ -102,4 +102,120 @@ class ClearCaseWrapperTests < Test::Unit::TestCase
102
102
  assert_equal(expected, change_set)
103
103
  end
104
104
 
105
+ def test_get_hijacked_files
106
+ # Define the expected calls
107
+ ct = MockClearTool.new
108
+ ct.add_invocation('ls -r',
109
+ [ "Connect",
110
+ "a1.cpp.obsolete@@/main/fact_1.0_Integ/4 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
111
+ "a2.h.obsolete@@/main/fact_1.0_Integ/5 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
112
+ "a3.cpp.obsolete@@/main/fact_1.0_Integ/fireaphis_1.0_2/1 Rule: .../fireaphis_1.0_2/LATEST",
113
+ "a4.h.obsolete@@/main/fact_1.0_Integ/fireaphis_1.0_2/2 Rule: .../fireaphis_1.0_2/LATEST",
114
+ "a5.h.obsolete@@/main/fact_1.0_Integ/2 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
115
+ "a6.cpp.obsolete@@/main/fact_1.0_Integ/fireaphis_1.0_2/4 Rule: .../fireaphis_1.0_2/LATEST",
116
+ "a7.h.obsolete@@/main/fact_1.0_Integ/fireaphis_1.0_2/3 Rule: .../fireaphis_1.0_2/LATEST",
117
+ "a8.h.obsolete@@/main/fact_1.0_Integ/3 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
118
+ "a9.cpp.keep",
119
+ "a10.cpp.keep.1",
120
+ "a11.cpp.keep.2",
121
+ "a12.h@@/main/fireaphis_1.0_2/4 Rule: .../fireaphis_1.0_2/LATEST",
122
+ "a13.h@@/main/fact_1.0_Integ/2 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
123
+ "a14.h@@/main/fact_1.0_Integ/1 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
124
+ "a15.cpp@@/main/fact_1.0_Integ/4 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
125
+ "a16.h@@/main/fact_1.0_Integ/fireaphis_1.0_2/2 [hijacked] Rule: .../fireaphis_1.0_2/LATEST",
126
+ "a17.h@@/main/fact_1.0_Integ/1 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
127
+ "test@@/main/fact_1.0_Integ/fireaphis_1.0_2/3 Rule: .../fireaphis_1.0_2/LATEST",
128
+ "./test/a18.h.obsolete@@/main/fact_1.0_Integ/3 [hijacked] Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
129
+ "./test/a19.cpp.obsolete@@/main/fact_1.0_Integ/9 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
130
+ "./test/a20.cpp@@/main/fact_1.0_Integ/3 [hijacked] Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
131
+ "./test/a21.h@@/main/fact_1.0_Integ/fireaphis_1.0_2/2 Rule: .../fireaphis_1.0_2/LATEST",
132
+ "./test/a22.cpp.obsolete@@/main/fact_1.0_Integ/3 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2",
133
+ "./test/a23.h.obsolete@@/main/fact_1.0_Integ/2 Rule: fact_1.0_1.0.0.0-663_31-MAY-2011_02.22.291 -mkbranch fireaphis_1.0_2"
134
+ ].join("\n"))
135
+
136
+ cc = Fact::ClearCase.new
137
+ cc.cleartool = ct
138
+
139
+ hijacked = []
140
+
141
+ err = catch(:wrongInvocation) { hijacked = cc.get_hijacked_files }
142
+ assert(ct.succeeded, err)
143
+
144
+ expected = [{:file=>"a16.h", :version=>"/main/fact_1.0_Integ/fireaphis_1.0_2/2"},
145
+ {:file=>"./test/a18.h.obsolete", :version=>"/main/fact_1.0_Integ/3" },
146
+ {:file=>"./test/a20.cpp", :version=>"/main/fact_1.0_Integ/3" }]
147
+ assert_equal(expected, hijacked)
148
+ end
149
+
150
+ end
151
+
152
+
153
+ class FileBackupTests < Test::Unit::TestCase
154
+
155
+ def setup
156
+ @dir = "test_backup_file"
157
+ @file = "#{@dir}/test.cpp.keep"
158
+ Dir.mkdir(@dir)
159
+ end
160
+
161
+ def teardown
162
+ system("rm -r #{@dir}")
163
+ end
164
+
165
+ def test_no_file
166
+ # Create existing backup files
167
+ (1 .. Fact::ClearCase::MAX_BACKUP_VERSIONS).each do |ver|
168
+ File.open("#{@file}.#{ver}", "w") { |f| f.write("booga") }
169
+ end
170
+ # Ensure that the correct number of files was created
171
+ assert_equal(Fact::ClearCase::MAX_BACKUP_VERSIONS+2, Dir.entries(@dir).size)
172
+
173
+ cc = Fact::ClearCase.new
174
+ # The method should raise because the backed up file doesn't exist
175
+ assert_raise(RuntimeError) { cc.backup_file(@file) }
176
+ # Ensure that no new files were added
177
+ assert_equal(Fact::ClearCase::MAX_BACKUP_VERSIONS+2, Dir.entries(@dir).size)
178
+ end
179
+
180
+ def test_99_files
181
+ # Create the file that will be backed up
182
+ File.open(@file, "w") {|f| f.write("booga")}
183
+
184
+ # Create existing backup files
185
+ (1 .. Fact::ClearCase::MAX_BACKUP_VERSIONS-1).each do |ver|
186
+ File.open("#{@file}.#{ver}", "w") { |f| f.write("booga") }
187
+ end
188
+ # Ensure that the correct number of files was created
189
+ assert_equal(Fact::ClearCase::MAX_BACKUP_VERSIONS+2, Dir.entries(@dir).size)
190
+ # Ensure that the back-up file that will be created doesn't exist yet
191
+ assert(!File.exists?("#{@file}.#{Fact::ClearCase::MAX_BACKUP_VERSIONS}"))
192
+
193
+ cc = Fact::ClearCase.new
194
+ assert_nothing_raised { cc.backup_file(@file) }
195
+ # Ensure that the backup was created
196
+ assert(File.exists?("#{@file}.#{Fact::ClearCase::MAX_BACKUP_VERSIONS}"))
197
+ # The orginal file should not exist now
198
+ assert(!File.exists?(@file))
199
+ end
200
+
201
+ def test_100_files
202
+ # Create the file that will be backed up
203
+ File.open(@file, "w") {|f| f.write("booga")}
204
+
205
+ # Create existing backup files
206
+ (1 .. Fact::ClearCase::MAX_BACKUP_VERSIONS).each do |ver|
207
+ File.open("#{@file}.#{ver}", "w") { |f| f.write("booga") }
208
+ end
209
+ # Ensure that the correct number of files was created
210
+ assert_equal(Fact::ClearCase::MAX_BACKUP_VERSIONS+3, Dir.entries(@dir).size)
211
+
212
+ cc = Fact::ClearCase.new
213
+ # The method should raise because there are too many back up files
214
+ assert_raise(RuntimeError) { cc.backup_file(@file) }
215
+ # Ensure that no new files were added
216
+ assert_equal(Fact::ClearCase::MAX_BACKUP_VERSIONS+3, Dir.entries(@dir).size)
217
+ # The orginal file should still exist
218
+ assert(File.exists?(@file))
219
+ end
220
+
105
221
  end
metadata CHANGED
@@ -1,20 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fact
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1.a
5
- prerelease: 6
4
+ version: '0.2'
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - FireAphis
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-05-31 00:00:00.000000000 +03:00
12
+ date: 2011-07-22 00:00:00.000000000 +03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: highline
17
- requirement: &83707590 !ruby/object:Gem::Requirement
17
+ requirement: &77118360 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,7 +22,7 @@ dependencies:
22
22
  version: 1.6.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *83707590
25
+ version_requirements: *77118360
26
26
  description: A small project intended to make a life with ClearCase a little bit happier.
27
27
  It supplies an intuitive and interactive ClearCase CLI and ClearCase wrapper API.
28
28
  email:
@@ -66,9 +66,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
66
  required_rubygems_version: !ruby/object:Gem::Requirement
67
67
  none: false
68
68
  requirements:
69
- - - ! '>'
69
+ - - ! '>='
70
70
  - !ruby/object:Gem::Version
71
- version: 1.3.1
71
+ version: '0'
72
72
  requirements:
73
73
  - ClearCase ClearTool
74
74
  rubyforge_project: fact