]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Update tclsolv, still work in progress
authorMichael Schroeder <mls@suse.de>
Tue, 25 Aug 2015 15:21:17 +0000 (17:21 +0200)
committerMichael Schroeder <mls@suse.de>
Tue, 25 Aug 2015 15:21:17 +0000 (17:21 +0200)
* use arrays instead of dics for the repos, so we can use the $foo(bar)
  syntax which makes the code a bit more readable
* implement susetags reading and cache writing

examples/tclsolv

index 21ed816bc88f643b73b6cb517f66f21322326cc1..4c6b4a5bd607cfe85ae045dd417ac403cda0b050 100755 (executable)
@@ -13,27 +13,29 @@ proc fileno {file} {
   error "file not open"
 }
 
-proc repo_calc_cookie_file {selfname filename} {
-  upvar $selfname self
+### generic repo handling (cache reading/writing)
+
+proc repo_calc_cookie_file {selfName filename} {
+  upvar $selfName self
   set chksum [solv::new_Chksum $solv::REPOKEY_TYPE_SHA256]
-  $chksum add 1.1
+  $chksum add "1.1"
   $chksum add_stat $filename
   return [$chksum raw]
 }
 
-proc repo_calc_cookie_fp {selfname fp} {
-  upvar $selfname self
+proc repo_calc_cookie_fp {selfName fp} {
+  upvar $selfName self
   set chksum [solv::new_Chksum $solv::REPOKEY_TYPE_SHA256]
   $chksum add 1.1
   $chksum add_fp $fp
   return [$chksum raw]
 }
 
-proc repo_calc_cookie_ext {selfname f cookie} {
-  upvar $selfname self
+proc repo_calc_cookie_ext {selfName f cookie} {
+  upvar $selfName self
   set chksum [solv::new_Chksum $solv::REPOKEY_TYPE_SHA256]
   $chksum add 1.1
-  $chksum add cookie
+  $chksum add $cookie
   $chksum add_fstat [$f fileno]
   set extcookie [$chksum raw]
   if {[string index $extcookie 0] eq "\000"} {
@@ -42,9 +44,9 @@ proc repo_calc_cookie_ext {selfname f cookie} {
   return $extcookie
 }
 
-proc repo_cachepath {selfname {ext "-"}} {
-  upvar $selfname self
-  regsub {^\.} [dict get $self name] _ path
+proc repo_cachepath {selfName {ext "-"}} {
+  upvar $selfName self
+  regsub {^\.} $self(name) _ path
   if {$ext ne "-"} {
     set path "${path}_$ext.solvx"
   } else {
@@ -54,48 +56,51 @@ proc repo_cachepath {selfname {ext "-"}} {
   return "/var/cache/solv/$path"
 }
 
-proc repo_generic_load {selfname pool} {
-  upvar $selfname self
-  set handle [ $pool add_repo [ dict get $self name ] ]
-  dict set self handle $handle
-  $handle configure -appdata $self -priority [expr 99 - [dict get $self priority]]
-  set dorefresh [dict get $self autorefresh]
-  set metadata_expire [dict get $self metadata_expire]
+proc repo_generic_load {selfName pool} {
+  upvar $selfName self
+  set handle [ $pool add_repo $self(name) ]
+  set self(handle) $handle
+  $handle configure -priority [expr 99 - $self(priority)]
+  upvar self "::repo_appdata_$handle"
+  set dorefresh $self(autorefresh)
+  set metadata_expire $self(metadata_expire)
   catch {
     if {$metadata_expire == -1 || [clock seconds] - [file mtime [repo_cachepath self]] < $metadata_expire} {
       set dorefresh 0
     }
   }
-  dict set self cookie {}
+  set self(cookie) {}
   if { !$dorefresh && [repo_usecachedrepo self] } {
-    puts "repo [dict get $self name]: cached"
+    puts "repo $self(name): cached"
     return 1 
   }
   return 0 
 }
 
-proc repo_free_handle {selfname} {
-  upvar $selfname self
-  set handle [ dict get $self handle ]
-  dict remove $self handle
+proc repo_free_handle {selfName} {
+  upvar $selfName self
+  set handle $self(handle)
+  set ::repo_appdata_gone 1
+  upvar ::repo_appdata_gone "::repo_appdata_$handle"
+  unset "::repo_appdata_$handle"
+  unset self(handle)
   $handle free 1
 }
 
-proc repo_usecachedrepo {selfname {ext "-"} {mark 0}} {
-  upvar $selfname self
-  return 0
+proc repo_usecachedrepo {selfName {ext "-"} {mark 0}} {
+  upvar $selfName self
   set repopath [repo_cachepath self]
   set code [catch {
     set f [open $repopath "rb"]
     seek $f -32 end
     set fcookie [read $f 32]
-    set cookie [dict get $self [expr { $ext eq "-" ? {cookie} : {extcookie}}]]
+    set cookie [expr {$ext eq "-" ? $self(cookie) : $self(extcookie)}]
     if {$cookie ne {} && $cookie ne $fcookie} {
       close $f
       return 0
     }
     set fextcookie {}
-    if {$ext eq "-" && [dict get $self type] ne "system"} {
+    if {$ext eq "-" && $self(type) ne "system"} {
       seek $f -64 end
       set fextcookie [read $f 32]
     }
@@ -109,14 +114,14 @@ proc repo_usecachedrepo {selfname {ext "-"} {mark 0}} {
        set flags [expr $flags | $solv::Repo_REPO_LOCALPOOL]
       }
     }
-    if {! [[dict get $self handle] add_solv $ff $flags]} {
+    if {! [$self(handle) add_solv $ff $flags]} {
       $ff close
       return 0
     }
     $ff close
-    if {[dict get $self type] ne "system" && $ext eq "-"} {
-      dict set self cookie $fcookie
-      dict set self extcookie $fextcookie
+    if {$self(type) ne "system" && $ext eq "-"} {
+      set self(cookie) $fcookie
+      set self(extcookie) $fextcookie
     }
     if {$mark} {
       catch {
@@ -128,17 +133,37 @@ proc repo_usecachedrepo {selfname {ext "-"} {mark 0}} {
   return [expr {$code == 2 ? $res : 0}]
 }
 
-proc repo_writecachedrepo {selfname {ext "-"}} {
-  upvar $selfname self
-  if [dict exists $self incomplete] {
+proc repo_writecachedrepo {selfName {ext "-"} {info "NULL"}} {
+  upvar $selfName self
+  if [info exists self(incomplete)] {
     return
   }
+  file mkdir "/var/cache/solv"
+  ::fileutil::tempdir "/var/cache/solv"
+  set tempfilename [::fileutil::tempfile ".newsolv-"]
+  ::fileutil::tempdirReset
+  set f [solv::xfopen $tempfilename "w+"]
+  file attributes $tempfilename -permissions 0444
+  if {$info eq {NULL}} {
+    $self(handle) write $f
+  } else {
+    $info write $f
+  }
+  $f flush
+  if {$self(type) ne "system" && $ext eq "-"} {
+    if {![info exists self(extcookie)]} {
+      set self(extcookie) [repo_calc_cookie_ext self $f $self(cookie)]
+    }
+    $f write $self(extcookie)
+  }
+  $f write [expr {$ext eq "-" ? $self(cookie) : $self(extcookie)}]
+  $f close
+  file rename -force -- $tempfilename [repo_cachepath self $ext]
 }
 
-proc repo_download {selfname file uncompress chksum {markincomplete 0}} {
-  upvar $selfname self
-  set url [dict get $self baseurl]
-  regsub {/$} $url {} url
+proc repo_download {selfName file uncompress chksum {markincomplete 0}} {
+  upvar $selfName self
+  regsub {/$} $self(baseurl) {} url
   set url "$url/$file"
   set tempfilename [::fileutil::tempfile]
   set f [open $tempfilename rb+]
@@ -151,7 +176,7 @@ proc repo_download {selfname file uncompress chksum {markincomplete 0}} {
       puts "$file: download error"
     }
     close $f
-    return 0
+    return {NULL}
   }
   seek $f 0 start
   if {$chksum ne "" && $chksum ne "NULL"} {
@@ -159,39 +184,36 @@ proc repo_download {selfname file uncompress chksum {markincomplete 0}} {
     if {$fchksum eq "" || $fchksum eq "NULL"} {
       puts "$file: unknown checksum type"
       if {$markincomplete} {
-       dict set self incomplete 1
+       set self(incomplete) 1
       }
       close $f
-      return 0
+      return {NULL}
     }
     $fchksum add_fd [fileno $f]
     if {[$fchksum hex] ne [$chksum hex]} {
       puts "$file: checksum mismatch"
       if {$markincomplete} {
-       dict set self incomplete 1
+       set self(incomplete) 1
       }
       close $f
-      return 0
+      return {NULL}
     }
   }
   set ff [solv::xfopen_fd [expr {$uncompress ? $file : ""}] [fileno $f]]
   close $f
-  if {$ff eq "NULL"} {
-    return 0
-  }
   return $ff
 }
 
-###
+### system
 
-proc repo_system_load {selfname pool} {
-  upvar $selfname self
-  set handle [ $pool add_repo [ dict get $self name ] ]
-  dict set self handle $handle
-  $handle configure -appdata $self
+proc repo_system_load {selfName pool} {
+  upvar $selfName self
+  set handle [ $pool add_repo $self(name) ]
+  set self(handle) $handle
+  upvar self "::repo_appdata_$handle"
   $pool configure -installed $handle
   puts -nonewline "rpm database: "
-  dict set self cookie [repo_calc_cookie_file self "/var/lib/rpm/Packages"]
+  set self(cookie) [repo_calc_cookie_file self "/var/lib/rpm/Packages"]
   if [repo_usecachedrepo self] {
     puts "cached"
     return 1
@@ -202,12 +224,11 @@ proc repo_system_load {selfname pool} {
   repo_writecachedrepo self
 }
 
-###
+### repomd
 
-proc repo_repomd_find {selfname what} {
-  upvar $selfname self
-  set handle [dict get $self handle]
-  set di [$handle Dataiterator_meta $solv::REPOSITORY_REPOMD_TYPE $what $solv::Dataiterator_SEARCH_STRING]
+proc repo_repomd_find {selfName what} {
+  upvar $selfName self
+  set di [$self(handle) Dataiterator_meta $solv::REPOSITORY_REPOMD_TYPE $what $solv::Dataiterator_SEARCH_STRING]
   $di prepend_keyname $solv::REPOSITORY_REPOMD
   solv::iter d $di {
     set dp [$d parentpos]
@@ -222,42 +243,42 @@ proc repo_repomd_find {selfname what} {
   return {}
 }
 
-proc repo_repomd_load {selfname pool} {
-  upvar $selfname self
+proc repo_repomd_load {selfName pool} {
+  upvar $selfName self
   if [repo_generic_load self $pool] {
     return 1
   }
-  puts -nonewline "rpmmd repo '[dict get $self name]': "
+  puts -nonewline "rpmmd repo '$self(name)': "
   set f [repo_download self {repodata/repomd.xml} 0 {}]
-  if {$f == 0} {
+  if {$f eq {NULL}} {
     puts "no repomd.xml file, skipped"
     repo_free_handle self
     return 0
   }
-  dict set self cookie [repo_calc_cookie_fp self $f]
+  set self(cookie) [repo_calc_cookie_fp self $f]
   if [repo_usecachedrepo self] {
     puts "cached"
     return 1
   }
-  set handle [dict get $self handle]
-  $handle add_repomdxml $f 0
+  set handle $self(handle)
+  $handle add_repomdxml $f
   puts "fetching"
   set primary [repo_repomd_find self primary]
-  if {$primary ne ""} {
+  if {$primary ne {}} {
     set f [repo_download self [lindex $primary 0] 1 [lindex $primary 1] 1]
-    if {$f != 0} {
-      $handle add_rpmmd $f "NULL" 0
+    if {$f ne {NULL}} {
+      $handle add_rpmmd $f {NULL}
       $f close
     }
-    if [dict exists $self incomplete] {
+    if [info exists self(incomplete)] {
       return 0
     }
   }
   set updateinfo [repo_repomd_find self primary]
-  if {$updateinfo ne ""} {
+  if {$updateinfo ne {}} {
     set f [repo_download self [lindex $updateinfo  0] 1 [lindex $updateinfo 1] 1]
-    if {$f != 0} {
-      $handle add_updateinfoxml $f 0
+    if {$f ne {NULL}} {
+      $handle add_updateinfoxml $f
       $f close
     }
   }
@@ -265,48 +286,105 @@ proc repo_repomd_load {selfname pool} {
   return 1
 }
 
-###
+### susetags
 
-proc repo_susetags_load {selfname pool} {
-  upvar $selfname self
+proc repo_susetags_find {selfName what} {
+  upvar $selfName self
+  set di [$self(handle) Dataiterator_meta $solv::SUSETAGS_FILE_NAME $what $solv::Dataiterator_SEARCH_STRING]
+  $di prepend_keyname $solv::SUSETAGS_FILE
+  solv::iter d $di {
+    set dp [$d parentpos]
+    set checksum [$dp lookup_checksum $solv::SUSETAGS_FILE_CHECKSUM]
+    return [list $what $checksum]
+  }
+  return {}
+}
+
+proc repo_susetags_load {selfName pool} {
+  upvar $selfName self
   if [repo_generic_load self $pool] {
     return 1
   }
-  puts -nonewline "susetags repo '[dict get $self name]': "
-  puts "skipped"
-  return 0
+  puts -nonewline "susetags repo '$self(name)': "
+  set f [repo_download self {content} 0 {}]
+  if {$f eq {NULL}} {
+    puts "no content file, skipped"
+    repo_free_handle self
+    return 0
+  }
+  set self(cookie) [repo_calc_cookie_fp self $f]
+  if [repo_usecachedrepo self] {
+    puts "cached"
+    return 1
+  }
+  set handle $self(handle)
+  $handle add_content $f
+  puts "fetching"
+  set defvendorid [[$handle cget -meta] lookup_id $solv::SUSETAGS_DEFAULTVENDOR]
+  set descrdir [[$handle cget -meta] lookup_str $solv::SUSETAGS_DESCRDIR]
+  if {$descrdir eq {NULL}} {
+    set descrdir "suse/setup/descr"
+  }
+  set packages [repo_susetags_find self "packages.gz"]
+  if {$packages eq {}} {
+    set packages [repo_susetags_find self "packages"]
+  }
+  if {$packages ne {}} {
+    set f [repo_download self "$descrdir/[lindex $packages 0]" 1 [lindex $packages 1] 1]
+    if {$f ne {NULL}} {
+      $handle add_susetags $f $defvendorid {} [expr $solv::Repo_REPO_NO_INTERNALIZE | $solv::Repo_SUSETAGS_RECORD_SHARES]
+      $f close
+      set packages [repo_susetags_find self "packages.en.gz"]
+      if {$packages eq {}} {
+       set packages [repo_susetags_find self "packages.en"]
+      }
+      if {$packages ne {}} {
+       set f [repo_download self "$descrdir/[lindex $packages 0]" 1 [lindex $packages 1] 1]
+       if {$f ne {NULL}} {
+          $handle add_susetags $f $defvendorid {} [expr $solv::Repo_REPO_NO_INTERNALIZE | $solv::Repo_REPO_REUSE_REPODATA | $solv::Repo_REPO_EXTEND_SOLVABLES ]
+         $f close
+       }
+      }
+      $handle internalize
+    }
+  }
+  repo_writecachedrepo self
+  return 1
 }
 
-###
+### unknown
 
-proc repo_unknown_load {selfname pool} {
-  upvar $selfname self
-  puts "unsupported repo '[dict get $self name]': skipped"
+proc repo_unknown_load {selfName pool} {
+  upvar $selfName self
+  puts "unsupported repo '$self(name)': skipped"
   return 0
 }
 
-###
+### poor man's OO
 
-proc repo_load {selfname pool} {
-  upvar $selfname self
-  "repo_[dict get $self type]_load" self $pool
+proc repo_load {selfName pool} {
+  upvar $selfName self
+  "repo_$self(type)_load" self $pool
 }
 
+###
 
-
-set repos {}
+set repoNames {}
 foreach reponame [lsort [glob -nocomplain -directory $reposdir *.repo]] {
   set ini [::ini::open $reponame r]
   foreach alias [::ini::sections $ini] {
-    set repoattr [dict create enabled 0 priority 99 autorefresh 1 type rpm-md metadata_expire 900]
-    set repoattr [dict replace $repoattr {*}[::ini::get $ini $alias]]
-    dict set repoattr name $alias
-    switch -exact -- [dict get $repoattr type] {
-      rpm-md  { dict set repoattr type repomd }
-      yast2   { dict set repoattr type susetags }
-      default { dict set repoattr type unknown }
+    set num [llength $repoNames]
+    array set "repos$num" {}
+    upvar 0 "repos$num" repoattr
+    array set repoattr {enabled 0 priority 99 autorefresh 1 type rpm-md metadata_expire 900}
+    array set repoattr [::ini::get $ini $alias]
+    set repoattr(name) $alias
+    switch -exact -- $repoattr(type) {
+      rpm-md  { set repoattr(type) repomd }
+      yast2   { set repoattr(type) susetags }
+      default { set repoattr(type) unknown }
     }
-    lappend repos $repoattr
+    lappend repoNames "repos$num" 
   }
   ::ini::close $ini
 }
@@ -314,11 +392,12 @@ foreach reponame [lsort [glob -nocomplain -directory $reposdir *.repo]] {
 set pool [solv::new_Pool]
 $pool setarch
 
-set sysrepo [dict create name {@System} type system]
+array set sysrepo [list name {@System} type system]
 repo_load sysrepo $pool
 
-foreach repo $repos {
-  if [dict get $repo enabled] {
+foreach repoName $repoNames {
+  upvar 0 $repoName repo
+  if {$repo(enabled)} {
     repo_load repo $pool
   }
 }