solaris-patch 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b774165f33d7ac5ff6223d37e0931a4d585f8f22
4
+ data.tar.gz: 218a198a52c6a11cc1ba0c75bf77ae1dca6cfd0f
5
+ SHA512:
6
+ metadata.gz: 3d0e51b0fda8d09109d78bc7083d13160d6d1334816e112e79ac598f69eeecaf10c1669167ba87b132be63eed2f6dceae24bca0df1cd24fe2bf6f7b4ee76b1e2
7
+ data.tar.gz: cb174c16a0d537816bebddf78868a62ca7482dd1808aa3cda8f5193ce783c9ae31e879f0df629c9eeaefebfda5deb765e99059ed070c64ffe4992e498bd0db7f
data/README.rdoc CHANGED
@@ -7,7 +7,7 @@ Copyright:: Copyright (c) Martin Carpenter 2011
7
7
 
8
8
  == About
9
9
  The solaris-patch gem helps with the manipulation of SunOS and Solaris
10
- patches.
10
+ patches.
11
11
 
12
12
  * Read (or write!) patchdiag.xref files.
13
13
  * Find latest version of a patch.
@@ -20,30 +20,30 @@ patches.
20
20
  === Download a patch
21
21
 
22
22
  require 'solaris/patch'
23
- Solaris::Patch.download_patch!( '123456-78',
24
- :to_file => '/tmp/123456-78.zip' )
23
+ Solaris::Patch.download_patch!('123456-78',
24
+ :to_file => '/tmp/123456-78.zip')
25
25
 
26
26
  Alternatively:
27
27
 
28
- patch = Solaris::Patch.new( '123456-78' )
29
- patch.download_patch!( :to_dir => '/tmp' )
28
+ patch = Solaris::Patch.new('123456-78')
29
+ patch.download_patch!(:to_dir => '/tmp')
30
30
 
31
31
  === Download a readme
32
32
 
33
33
  require 'solaris/patch'
34
- Solaris::Patch.download_readme!( '123456-78',
35
- :to_file => '/tmp/123456-78.txt' )
34
+ Solaris::Patch.download_readme!('123456-78',
35
+ :to_file => '/tmp/123456-78.txt')
36
36
 
37
37
  === Get the latest version of a patch
38
38
 
39
39
  require 'solaris/patch'
40
- Solaris::Patchdiag.open( '/tmp/patchdiag.xref' ).latest( '123456-01' )
40
+ Solaris::Patchdiag.open('/tmp/patchdiag.xref').latest('123456-01')
41
41
  => "123456|12|..."
42
42
 
43
43
  === Get the latest non-obsolete version of a possibly obsoleted patch
44
44
 
45
45
  require 'solaris/patch'
46
- Solaris::Patchdiag.open( '/tmp/patchdiag.xref' ).successor( '123456-01' )
46
+ Solaris::Patchdiag.open('/tmp/patchdiag.xref').successor('123456-01')
47
47
  => "234567|12|..."
48
48
 
49
49
  === Interrogate patchdiag.xref
@@ -51,14 +51,14 @@ Alternatively:
51
51
  require 'solaris/patch'
52
52
 
53
53
  # slurp in patchdiag.xref
54
- patchdiag = Solaris::Patchdiag.new( '/tmp/patchdiag.xref' )
54
+ patchdiag = Solaris::Patchdiag.new('/tmp/patchdiag.xref')
55
55
 
56
56
  # all sparc patches
57
57
  patchdiag.select { |p| p.archs.include? 'sparc' }.inspect
58
- => [ "123456-78", ... ]
58
+ => ["123456-78", ...]
59
59
 
60
60
  # latest line added to patchdiag.xref
61
- most_recent = patchdiag.sort_by( &:date ).last
61
+ most_recent = patchdiag.sort_by(&:date).last
62
62
  most_recent
63
63
  => "123456|78|..."
64
64
 
@@ -74,4 +74,3 @@ Alternatively:
74
74
 
75
75
  Dates in patchdiag.xref are Mon/dd/yy format. This gem will break in
76
76
  2050 since it assumes year 50 and above is in the 20th century.
77
-
data/Rakefile CHANGED
@@ -7,12 +7,12 @@ require 'rubygems/package_task'
7
7
  desc 'Default task (package)'
8
8
  task :default => [:package]
9
9
 
10
- Rake::TestTask.new( 'test' )
10
+ Rake::TestTask.new('test')
11
11
 
12
12
  SPECFILE = 'solaris-patch.gemspec'
13
- if File.exist?( SPECFILE )
14
- spec = eval( File.read( SPECFILE ) )
15
- Gem::PackageTask.new( spec ).define
13
+ if File.exist?(SPECFILE)
14
+ spec = eval(File.read(SPECFILE))
15
+ Gem::PackageTask.new(spec).define
16
16
  end
17
17
 
18
18
  RDoc::Task.new do |rdoc|
@@ -20,8 +20,8 @@ RDoc::Task.new do |rdoc|
20
20
  rdoc.title = 'solaris-patch'
21
21
  rdoc.options << '--charset' << 'utf-8'
22
22
  rdoc.options << '--all'
23
- rdoc.rdoc_files.include( 'README.rdoc' )
24
- rdoc.rdoc_files.include( FileList[ 'lib/**/*' ] )
25
- rdoc.rdoc_files.include( FileList[ 'test/**/*' ] )
23
+ rdoc.rdoc_files.include('README.rdoc')
24
+ rdoc.rdoc_files.include(FileList['lib/**/*'])
25
+ rdoc.rdoc_files.include(FileList['test/**/*'])
26
26
  end
27
27
 
data/lib/solaris.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  # Namespace for child classes.
3
2
  module Solaris
4
3
 
@@ -7,4 +6,3 @@ module Solaris
7
6
  require 'solaris/patchdiag_entry'
8
7
 
9
8
  end # Solaris
10
-
@@ -1,4 +1,3 @@
1
-
2
1
  module Solaris
3
2
 
4
3
  class Patch
@@ -32,4 +31,3 @@ module Solaris
32
31
  end
33
32
 
34
33
  end # Solaris
35
-
data/lib/solaris/patch.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  module Solaris
3
2
 
4
3
  # Class to represent a patch number.
@@ -17,7 +16,7 @@ module Solaris
17
16
  :patch => 'https://getupdates.oracle.com/all_unsigned/%s.zip',
18
17
  :readme => 'https://getupdates.oracle.com/readme/README.%s'
19
18
  }
20
-
19
+
21
20
  # The major number of the patch (integer), the part before the dash.
22
21
  attr_accessor :major
23
22
 
@@ -45,7 +44,7 @@ module Solaris
45
44
  # TLDR: Patch.new('123456-78')
46
45
  def initialize(major=nil, minor=nil)
47
46
  if major
48
- patch_no = major.to_s + ( minor ? "-#{minor}" : '' )
47
+ patch_no = major.to_s + (minor ? "-#{minor}" : '')
49
48
  if patch_no =~ /^(\d+)(-(\d+))?$/
50
49
  @major = $1.to_i
51
50
  @minor = $3.to_i if $3
@@ -57,18 +56,18 @@ module Solaris
57
56
 
58
57
  # Download this patch. For the options hash see private method Patch#download!
59
58
  def download_patch!(opts={})
60
- download!( :patch, opts )
59
+ download!(:patch, opts)
61
60
  end
62
61
 
63
62
  # Download this README. For the options hash see private method Patch#download!
64
63
  def download_readme!(opts={})
65
- download!( :readme, opts )
64
+ download!(:readme, opts)
66
65
  end
67
66
 
68
67
  # Return a string representation of this patch. If the minor
69
68
  # number has not been set then just return the major number.
70
69
  def to_s
71
- minor ? "#{@major}-#{Patch.pad_minor( @minor )}" : "#{@major}"
70
+ minor ? "#{@major}-#{Patch.pad_minor(@minor)}" : "#{@major}"
72
71
  end
73
72
 
74
73
  # Compare patch versions. (Performs a string compare on the full patch numbers).
@@ -79,20 +78,20 @@ module Solaris
79
78
  # Download the given patch (this may be a Patch object or a string
80
79
  # like '123456-78'). For the options hash see Patch#download!.
81
80
  def Patch.download_patch!(patch, opts={})
82
- patch_to_dl = Patch.new( patch.to_s )
83
- patch_to_dl.download_patch!( opts )
81
+ patch_to_dl = Patch.new(patch.to_s)
82
+ patch_to_dl.download_patch!(opts)
84
83
  end
85
84
 
86
85
  # Download the given readme (this may be a Patch object or a string
87
86
  # like '123456-78'). For the options hash see Patch#download!.
88
87
  def Patch.download_readme!(patch, opts={})
89
- patch_to_dl = Patch.new( patch.to_s )
90
- patch_to_dl.download_readme!( opts )
88
+ patch_to_dl = Patch.new(patch.to_s)
89
+ patch_to_dl.download_readme!(opts)
91
90
  end
92
91
 
93
92
  # Left pad a minor version number with zeros as required.
94
93
  def Patch.pad_minor(minor)
95
- "#{minor.to_s.rjust( 2, '0' )}"
94
+ "#{minor.to_s.rjust(2, '0')}"
96
95
  end
97
96
 
98
97
  private
@@ -102,15 +101,14 @@ module Solaris
102
101
  def download!(type, opts={})
103
102
  raise ArgumentError, "Patch #{self.inspect} requires a major number to download" unless @major
104
103
  raise ArgumentError, "Patch #{self.inspect} requires a minor number to download" unless @minor
105
- raise ArgumentError, "Unknown type #{type.inspect}" unless URL[ type ]
106
- url = URL[ type ] % self.to_s
104
+ raise ArgumentError, "Unknown type #{type.inspect}" unless URL[type]
105
+ url = URL[type] % self.to_s
107
106
  opts = {
108
107
  :agent => 'Wget/1.10.2', # default user agent, required by Oracle
109
- }.merge( opts )
110
- Solaris::Util.download!( url, opts )
108
+ }.merge(opts)
109
+ Solaris::Util.download!(url, opts)
111
110
  end
112
-
111
+
113
112
  end # Patch
114
113
 
115
114
  end # Solaris
116
-
@@ -1,4 +1,3 @@
1
-
2
1
  module Solaris
3
2
 
4
3
  # Class to represent the Oracle patchdiag "database" (file).
@@ -20,17 +19,30 @@ module Solaris
20
19
  # URL of latest patchdiag.xref from Oracle.
21
20
  DEFAULT_XREF_URL = 'https://getupdates.oracle.com/reports/patchdiag.xref'
22
21
 
22
+ # The date of this patchdiag.xref, parsed from the header.
23
+ attr_writer :date
24
+
25
+ # The array of lines that comprise the header, sans trailing newline.
26
+ attr_accessor :header
27
+
28
+ # The array of lines that comprise the footer, sans trailing newline.
29
+ attr_accessor :footer
30
+
23
31
  # Create a new patchdiag database object by reading the given
24
32
  # xref file (this may be a filename (string) or a fileish object
25
33
  # (File, StringIO)). If no xref file is given then the default
26
34
  # is read (/var/tmp/patchdiag.xref); this is the cache file used
27
35
  # by Patch Check Advanced (pca).
28
36
  def initialize(xref_file=DEFAULT_XREF_FILE)
29
- xref_file = File.new( xref_file ) if xref_file.is_a?( String )
30
- @_entries = xref_file.
31
- readlines.
32
- reject { |line| line =~ /^#|^\s*$/ }. # discard comments, blanks
33
- map { |line| PatchdiagEntry.new( line ) }
37
+ xref_file = File.new(xref_file) if xref_file.is_a?(String)
38
+ @entries, @header, @footer = [], [], []
39
+ xref_file.each_line do |line|
40
+ if line =~ /^\d/
41
+ @entries << PatchdiagEntry.new(line)
42
+ else
43
+ (@entries.empty? ? @header : @footer) << line.chomp
44
+ end
45
+ end
34
46
  end
35
47
 
36
48
  # Download the patchdiag database and return it as a string.
@@ -38,14 +50,14 @@ module Solaris
38
50
  # to disk unless :to_file or :to_dir are given.
39
51
  # For the options hash argument see Solaris::Util.download!
40
52
  def Patchdiag.download!(opts={})
41
- url = opts.delete( :url ) || DEFAULT_XREF_URL
42
- Util.download!( url, opts )
53
+ url = opts.delete(:url) || DEFAULT_XREF_URL
54
+ Util.download!(url, opts)
43
55
  end
44
56
 
45
57
  # Open the given optional patchdiag xref file and yield to the
46
58
  # optional block.
47
59
  def Patchdiag.open(xref_file=DEFAULT_XREF_FILE, &blk)
48
- patchdiag = Patchdiag.new( xref_file )
60
+ patchdiag = Patchdiag.new(xref_file)
49
61
  if block_given?
50
62
  yield patchdiag
51
63
  else
@@ -55,13 +67,20 @@ module Solaris
55
67
 
56
68
  # Create and return a deep copy of this object.
57
69
  def clone
58
- Marshal.load( Marshal.dump( self ) )
70
+ Marshal.load(Marshal.dump(self))
71
+ end
72
+
73
+ # Return the date parsed from the patchdiag.xref comment lines.
74
+ def date
75
+ ## PATCHDIAG TOOL CROSS-REFERENCE FILE AS OF Jan/23/14 ##
76
+ @date ||= @header.find { |line| line =~ /\s(\w\w\w\/\d\d\/\d\d)\s/ } &&
77
+ Date.parse($1)
59
78
  end
60
79
 
61
80
  # For Enumerator module: yields each Solaris::PatchdiagEntry in
62
81
  # turn.
63
82
  def each(&blk)
64
- @_entries.each( &blk )
83
+ @entries.each(&blk)
65
84
  end
66
85
 
67
86
  # Returns an array of Solaris::PatchdiagEntry from the
@@ -73,16 +92,16 @@ module Solaris
73
92
  # major number are returned. Returns an empty array if no such
74
93
  # patches can be found. This method overrides Enumerable#find.
75
94
  def find(patch)
76
- patch = Patch.new( patch.to_s )
95
+ patch = Patch.new(patch.to_s)
77
96
  property = patch.minor ? :to_s : :major
78
- comparator = patch.send( property )
79
- entries.select { |pde| pde.patch.send( property ) == comparator }
97
+ comparator = patch.send(property)
98
+ @entries.select { |pde| pde.patch.send(property) == comparator }
80
99
  end
81
100
 
82
101
  # Strangely Enumerable module does not define Enumerable#last (although
83
102
  # it does define Enumerable#first) so we define last here.
84
103
  def last
85
- entries.last
104
+ @entries.last
86
105
  end
87
106
 
88
107
  # Return the Solaris::PatchdiagEntry of the latest version of the
@@ -90,24 +109,24 @@ module Solaris
90
109
  # Solaris::Patch). Throws Solaris::Patch::NotFound if the patch
91
110
  # cannot be found in patchdiag.xref.
92
111
  def latest(patch)
93
- major = Patch.new( patch.to_s ).major
94
- find( major ).max ||
95
- raise( Solaris::Patch::NotFound,
96
- "Cannot find patch #{patch} in patchdiag.xref" )
112
+ major = Patch.new(patch.to_s).major
113
+ find(major).max ||
114
+ raise(Solaris::Patch::NotFound,
115
+ "Cannot find patch #{patch} in patchdiag.xref")
97
116
  end
98
117
 
99
118
  # Returns a (deep) copy of +self+ with the entries sorted, takes an
100
119
  # optional block. This method overrides Enumerable#sort. See also
101
120
  # Solaris::Patchdiag#sort!.
102
121
  def sort(&blk)
103
- clone.sort!( &blk )
122
+ clone.sort!(&blk)
104
123
  end
105
124
 
106
125
  # Returns +self+ with the entries sorted in place, takes an optional
107
126
  # block. See also Solaris::Patchdiag#sort.
108
127
  def sort!(&blk)
109
- # use @_entries since #entries returns a copy
110
- @_entries.sort!( &blk )
128
+ # use @entries since #entries returns a copy
129
+ @entries.sort!(&blk)
111
130
  self
112
131
  end
113
132
 
@@ -125,21 +144,21 @@ module Solaris
125
144
  # The ancestors parameter is a recursion accumulator and should not
126
145
  # normally be assigned to by callers.
127
146
  def successors(patch, ancestors=[])
128
- patch = Patch.new( patch.to_s )
147
+ patch = Patch.new(patch.to_s)
129
148
  raise Solaris::Patch::SuccessorLoop,
130
- "Loop detected for patch #{patch} with ancestors #{ancestors.inspect}" if ancestors.include?( patch )
149
+ "Loop detected for patch #{patch} with ancestors #{ancestors.inspect}" if ancestors.include?(patch)
131
150
  ancestors << patch
132
151
  if ! patch.minor # patch has no minor number
133
- successors( latest( patch ).patch, ancestors )
134
- elsif ! entry = find( patch ).last # explicit patch not found
135
- latest_patch = latest( patch ).patch
152
+ successors(latest(patch).patch, ancestors)
153
+ elsif ! entry = find(patch).last # explicit patch not found
154
+ latest_patch = latest(patch).patch
136
155
  raise Solaris::Patch::NotFound,
137
156
  "Patch #{patch} not found and has no later version" if latest_patch.minor <= patch.minor
138
- successors( latest_patch, ancestors )
157
+ successors(latest_patch, ancestors)
139
158
  else
140
159
  if entry.obsolete?
141
160
  succ = entry.successor
142
- successors( succ, ancestors )
161
+ successors(succ, ancestors)
143
162
  elsif entry.bad?
144
163
  raise BadSuccessor, "Terminal successor #{patch} is bad/withdrawn"
145
164
  else
@@ -151,17 +170,16 @@ module Solaris
151
170
  # Return the Solaris::PatchdiagEntry of the latest non-obsolete successor
152
171
  # of this patch. This is a convenience method for #successors.last.
153
172
  def successor(patch)
154
- latest( successors( patch ).last )
173
+ latest(successors(patch).last)
155
174
  end
156
175
 
157
176
  # Returns a string representation of the patchdiag.xref. All comments
158
177
  # and blank lines are elided.
159
178
  def to_s
160
- entries.join("\n")
179
+ (@header + @entries + @footer).join("\n") << "\n"
161
180
  end
162
181
  alias to_str to_s
163
182
 
164
183
  end # Patchdiag
165
184
 
166
185
  end # Solaris
167
-
@@ -1,4 +1,3 @@
1
-
2
1
  module Solaris
3
2
 
4
3
  # Class to represent a line from Sun's patchdiag.xref patch "database".
@@ -56,23 +55,27 @@ module Solaris
56
55
  # patchdiag.xref).
57
56
  attr_accessor :y2k
58
57
 
58
+ # Number of pipe-delimited fields in a patchdiag line.
59
+ FIELDS = 11
60
+
59
61
  def initialize(patchdiag_line)
60
- fields = patchdiag_line.split( '|', 11 )
62
+ fields = patchdiag_line.split('|', FIELDS)
63
+ raise ArgumentError, "Not enough fields in line: #{patchdiag_line}" unless fields.size == FIELDS
61
64
  major, minor, date, @recommended, @security, @obsolete, bad, @os, archs, pkgs, @synopsis = *fields
62
- @archs = archs.split( ';' )
65
+ @archs = archs.split(';')
63
66
  if date == ''
64
67
  year, month, day = 1970, 1, 1
65
68
  else
66
- month_s, day_s, year_s = *date.split( '/' )
67
- year = ( year_s.to_i > 50 ? "19#{year_s}" : "20#{year_s}" ).to_i
68
- month = Date::ABBR_MONTHNAMES.index( month_s )
69
+ month_s, day_s, year_s = *date.split('/')
70
+ year = (year_s.to_i > 50 ? "19#{year_s}" : "20#{year_s}").to_i
71
+ month = Date::ABBR_MONTHNAMES.index(month_s)
69
72
  day = day_s.to_i
70
73
  end
71
74
  @bad = bad =~ /B/ ? 'B' : ' '
72
75
  @y2k = bad =~ /Y/ ? 'Y' : ' '
73
- @date = Date.new( year, month, day )
74
- @patch = Patch.new( major, minor )
75
- @pkgs = pkgs.split( ';' )
76
+ @date = Date.new(year, month, day)
77
+ @patch = Patch.new(major, minor)
78
+ @pkgs = pkgs.split(';')
76
79
  @synopsis.chomp!
77
80
  end
78
81
 
@@ -82,12 +85,12 @@ module Solaris
82
85
 
83
86
  # Download this patch. For options hash see Patch#download!.
84
87
  def download_patch!(opts={}) ;
85
- @patch.download_patch!( opts )
88
+ @patch.download_patch!(opts)
86
89
  end
87
90
 
88
91
  # Download the README for this patch. For options hash see Patch#download!.
89
92
  def download_readme!(opts={})
90
- @patch.download_readme!( opts )
93
+ @patch.download_readme!(opts)
91
94
  end
92
95
 
93
96
  # Returns this entries major patch number as an integer.
@@ -141,7 +144,7 @@ module Solaris
141
144
 
142
145
  # See if we can find a successor
143
146
  if synopsis =~ /obsolete(d?) by\s*(:?)\s*(\d+(-\d+)?)/i
144
- Patch.new( $3 )
147
+ Patch.new($3)
145
148
  else
146
149
  raise Solaris::Patch::InvalidSuccessor,
147
150
  "Failed to parse successor to obsolete patchdiag entry for patch #{patch.inspect}"
@@ -151,16 +154,17 @@ module Solaris
151
154
  # Output this patchdiag xref entry as a string, in format of Oracle's
152
155
  # database.
153
156
  def to_s
154
- [ patch.major,
155
- Patch.pad_minor( patch.minor ),
157
+ [
158
+ patch.major,
159
+ Patch.pad_minor(patch.minor),
156
160
  date_s,
157
161
  @recommended,
158
162
  @security,
159
163
  @obsolete,
160
- @bad + @y2k,
164
+ @y2k + @bad,
161
165
  @os,
162
- join_semis( @archs ),
163
- join_semis( @pkgs ),
166
+ join_semis(@archs),
167
+ join_semis(@pkgs),
164
168
  @synopsis
165
169
  ].join('|')
166
170
  end
@@ -179,9 +183,10 @@ module Solaris
179
183
 
180
184
  # Convert the Date object to a date string as found in patchdiag.xref.
181
185
  def date_s
182
- [ Date::ABBR_MONTHNAMES[ @date.mon ], # month eg Jan
186
+ [
187
+ Date::ABBR_MONTHNAMES[@date.mon], # month eg Jan
183
188
  @date.mday.to_s.rjust(2, '0'), # day of month
184
- @date.year % 100 # 2 digit year
189
+ (@date.year % 100).to_s.rjust(2, '0') # 2 digit year
185
190
  ].join('/')
186
191
  end
187
192
 
@@ -195,4 +200,3 @@ module Solaris
195
200
  end # PatchdiagEntry
196
201
 
197
202
  end # Solaris
198
-