solaris-patch 1.0.2 → 1.0.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.
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
-