System.Data.SQLite
Check-in [e100045f84]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improvements to the master release archive verification tool.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e100045f84e37bdb97d8dbf41051bf3e856c7016
User & Date: mistachkin 2014-11-24 21:34:14
Context
2014-11-24
22:03
Check for missing Fossil tool in the master release archive verification tool. check-in: 59d9761e66 user: mistachkin tags: trunk
21:34
Improvements to the master release archive verification tool. check-in: e100045f84 user: mistachkin tags: trunk
2014-11-19
23:09
Update SQLite core library to the 3.8.7.2 release. check-in: 919cb869dc user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Setup/verify.eagle.

    10     10   package require Eagle
    11     11   
    12     12   proc usage { error } {
    13     13     if {[string length $error] > 0} then {puts stdout $error}
    14     14   
    15     15     puts stdout "usage:\
    16     16   [file tail [info nameofexecutable]]\
    17         -[file tail [info script]] <directory>"
           17  +[file tail [info script]] <directory> <withHashes>"
    18     18   
    19     19     #
    20     20     # NOTE: Indicate to the caller, if any, that we have failed.
    21     21     #
    22     22     exit 1
    23     23   }
           24  +
           25  +proc getSha1Hashes { varName } {
           26  +  variable fossil
           27  +
           28  +  upvar 1 $varName hashes
           29  +
           30  +  set data [exec -success Success -nocarriagereturns -- \
           31  +      $fossil artifact current]
           32  +
           33  +  set result 0
           34  +  set lines [split $data \n]
           35  +
           36  +  foreach line $lines {
           37  +    if {[string range $line 0 1] eq "F "} then {
           38  +      set fields [split $line " "]
           39  +
           40  +      if {[llength $fields] >= 3} then {
           41  +        set hashes([lindex $fields 1]) [lindex $fields 2]
           42  +        incr result
           43  +      }
           44  +    }
           45  +  }
           46  +
           47  +  return $result
           48  +}
           49  +
           50  +proc getSha1Sum { fileName } {
           51  +  variable fossil
           52  +
           53  +  return [string range [exec -success Success -nocarriagereturns \
           54  +      -trimall -- $fossil sha1sum $fileName] 0 39]
           55  +}
    24     56   
    25     57   set argc [llength $argv]
    26     58   
    27         -if {$argc == 1} then {
           59  +if {$argc == 2} then {
    28     60     set directory [lindex $argv 0]
    29     61   
    30         -  if {[string length $directory] > 0} then {
    31         -    set exitCode 0
    32         -
    33         -    set script [info script]
    34         -    set path [file dirname $script]
    35         -    set rootName [file rootname [file tail $script]]
    36         -
    37         -    if {![info exists innounp]} then {
    38         -      if {[info exists env(InnoUnpackTool)]} then {
    39         -        set innounp $env(InnoUnpackTool)
    40         -      }
    41         -
    42         -      if {![info exists innounp] || ![file exists $innounp]} then {
    43         -        set innounp [file join $path innounp.exe]
    44         -      }
           62  +  if {[string length $directory] == 0} then {
           63  +    usage "invalid directory specified"
           64  +  }
           65  +
           66  +  if {![file isdirectory $directory]} then {
           67  +    usage [appendArgs \
           68  +        "directory \"" $directory "\" does not exist"]
           69  +  }
           70  +
           71  +  set withHashes [lindex $argv 1]
           72  +
           73  +  if {[string length $withHashes] == 0} then {
           74  +    usage "invalid \"withHashes\" flag specified"
           75  +  }
           76  +
           77  +  if {![string is boolean -strict $withHashes]} then {
           78  +    usage "bad \"withHashes\" flag, not a boolean"
           79  +  }
           80  +
           81  +  set exitCode 0
           82  +
           83  +  set script [info script]
           84  +  set path [file dirname $script]
           85  +  set rootName [file rootname [file tail $script]]
           86  +
           87  +  if {![info exists fossil]} then {
           88  +    if {[info exists env(FossilTool)]} then {
           89  +      set fossil $env(FossilTool)
           90  +    }
           91  +
           92  +    if {![info exists fossil] || ![file exists $fossil]} then {
           93  +      set fossil [file join $path fossil.exe]
           94  +    }
           95  +  }
           96  +
           97  +  if {![info exists innounp]} then {
           98  +    if {[info exists env(InnoUnpackTool)]} then {
           99  +      set innounp $env(InnoUnpackTool)
          100  +    }
          101  +
          102  +    if {![info exists innounp] || ![file exists $innounp]} then {
          103  +      set innounp [file join $path innounp.exe]
          104  +    }
          105  +  }
          106  +
          107  +  if {![info exists rar]} then {
          108  +    if {[info exists env(UnRARTool)]} then {
          109  +      set rar $env(UnRARTool)
          110  +    }
          111  +
          112  +    if {![info exists rar] || ![file exists $rar]} then {
          113  +      set rar [file join $path UnRAR.exe]
          114  +    }
          115  +  }
          116  +
          117  +  if {![info exists zip]} then {
          118  +    if {[info exists env(UnZipTool)]} then {
          119  +      set zip $env(UnZipTool)
          120  +    }
          121  +
          122  +    if {![info exists zip] || ![file exists $zip]} then {
          123  +      set zip [file join $path UnZip.exe]
    45    124       }
    46         -
    47         -    if {![info exists rar]} then {
    48         -      if {[info exists env(UnRARTool)]} then {
    49         -        set rar $env(UnRARTool)
    50         -      }
    51         -
    52         -      if {![info exists rar] || ![file exists $rar]} then {
    53         -        set rar [file join $path UnRAR.exe]
    54         -      }
          125  +  }
          126  +
          127  +  source [file join $path data [appendArgs $rootName .lst]]
          128  +
          129  +  if {![array exists manifests]} then {
          130  +    usage "master archive manifest is missing"
          131  +  }
          132  +
          133  +  package require Eagle.Test; set extractDirectory [getTemporaryPath]
          134  +
          135  +  if {[string length $extractDirectory] == 0} then {
          136  +    usage "no extract directory is available"
          137  +  }
          138  +
          139  +  if {![file isdirectory $extractDirectory]} then {
          140  +    usage [appendArgs \
          141  +        "extract directory \"" $extractDirectory "\" does not exist"]
          142  +  }
          143  +
          144  +  if {[getSha1Hashes hashes] == 0} then {
          145  +    usage "no repository hashes are available"
          146  +  }
          147  +
          148  +  set archiveFileNames [list]
          149  +
          150  +  foreach extension [list exe rar zip] {
          151  +    eval lappend archiveFileNames [findFilesRecursive \
          152  +        [file join $directory [appendArgs *. $extension]]]
          153  +  }
          154  +
          155  +  foreach archiveFileName $archiveFileNames {
          156  +    set manifest [file tail $archiveFileName]
          157  +
          158  +    #
          159  +    # NOTE: Attempt to extract the version and/or date/time
          160  +    #       information from the manifest file name.
          161  +    #
          162  +    regexp -- {(\d+)\.(\d+)\.(\d+)\.(\d+)} $manifest dummy \
          163  +        major minor build revision
          164  +
          165  +    regexp -- {(\d{4})-(\d{2})-(\d{2})-(\d{2})} $manifest \
          166  +        dummy year month day sequence
          167  +
          168  +    #
          169  +    # HACK: Attempt to match and remove sub-strings from the
          170  +    #       manifest file name that look like the name of a
          171  +    #       build configuration (e.g. "debug" or "release").
          172  +    #
          173  +    regsub -- {-debug-|-release-} $manifest {-} manifest
          174  +
          175  +    #
          176  +    # HACK: Attempt to match and remove sub-strings from the
          177  +    #       manifest file name that look like a version number
          178  +    #       in the format "<major>.<minor>.<build>.<revision>"
          179  +    #       and/or a date/time string matching the format
          180  +    #       "YYYY-MM-DD-NN" (where the NN portion is a generic
          181  +    #       incrementing sequence number).
          182  +    #
          183  +    regsub -- {\d+\.\d+\.\d+\.\d+} $manifest {} manifest
          184  +    regsub -- {\d{4}-\d{2}-\d{2}-\d{2}} $manifest {} manifest
          185  +
          186  +    if {![info exists manifests($manifest)]} then {
          187  +      puts stdout [appendArgs \
          188  +          "WARNING: Cannot find master manifest \"" \
          189  +          $manifest "\" for archive \"" $archiveFileName \
          190  +          "\", skipped."]
          191  +
          192  +      continue
    55    193       }
    56    194   
    57         -    if {![info exists zip]} then {
    58         -      if {[info exists env(UnZipTool)]} then {
    59         -        set zip $env(UnZipTool)
          195  +    set manifestFileNames [list]
          196  +
          197  +    foreach list [lrange $manifests($manifest) 1 end] {
          198  +      set rawManifestFileNames [set [appendArgs \
          199  +          [appendArgs [lindex $manifests($manifest) 0] \
          200  +          _manifests] ( $list )]]
          201  +
          202  +      if {[info exists manifests($manifest,subst)]} then {
          203  +        set rawManifestFileNames [subst $rawManifestFileNames]
    60    204         }
    61    205   
    62         -      if {![info exists zip] || ![file exists $zip]} then {
    63         -        set zip [file join $path UnZip.exe]
          206  +      foreach manifestFileName $rawManifestFileNames {
          207  +        lappend manifestFileNames $manifestFileName
    64    208         }
    65    209       }
    66    210   
    67         -    source [file join $path data [appendArgs $rootName .lst]]
    68         -
    69         -    if {![array exists manifests]} then {
    70         -      usage "master archive manifest is missing"
    71         -    }
    72         -
    73         -    set archiveFileNames [list]
    74         -
    75         -    foreach extension [list exe rar zip] {
    76         -      eval lappend archiveFileNames [findFilesRecursive \
    77         -          [file join $directory [appendArgs *. $extension]]]
    78         -    }
    79         -
    80         -    foreach archiveFileName $archiveFileNames {
    81         -      set manifest [file tail $archiveFileName]
    82         -
    83         -      #
    84         -      # NOTE: Attempt to extract the version and/or date/time
    85         -      #       information from the manifest file name.
    86         -      #
    87         -      regexp -- {(\d+)\.(\d+)\.(\d+)\.(\d+)} $manifest dummy \
    88         -          major minor build revision
    89         -
    90         -      regexp -- {(\d{4})-(\d{2})-(\d{2})-(\d{2})} $manifest \
    91         -          dummy year month day sequence
    92         -
    93         -      #
    94         -      # HACK: Attempt to match and remove sub-strings from the
    95         -      #       manifest file name that look like the name of a
    96         -      #       build configuration (e.g. "debug" or "release").
    97         -      #
    98         -      regsub -- {-debug-|-release-} $manifest {-} manifest
    99         -
   100         -      #
   101         -      # HACK: Attempt to match and remove sub-strings from the
   102         -      #       manifest file name that look like a version number
   103         -      #       in the format "<major>.<minor>.<build>.<revision>"
   104         -      #       and/or a date/time string matching the format
   105         -      #       "YYYY-MM-DD-NN" (where the NN portion is a generic
   106         -      #       incrementing sequence number).
   107         -      #
   108         -      regsub -- {\d+\.\d+\.\d+\.\d+} $manifest {} manifest
   109         -      regsub -- {\d{4}-\d{2}-\d{2}-\d{2}} $manifest {} manifest
   110         -
   111         -      if {![info exists manifests($manifest)]} then {
   112         -        puts stdout [appendArgs \
   113         -            "WARNING: Cannot find master manifest \"" \
   114         -            $manifest "\" for archive \"" $archiveFileName \
   115         -            "\", skipped."]
   116         -
   117         -        continue
          211  +    set listCommand [list]
          212  +    lappend listCommand exec -success Success -nocarriagereturns --
          213  +
          214  +    set extractCommand [list]
          215  +    lappend extractCommand exec -success Success -nocarriagereturns --
          216  +
          217  +    if {[file extension $archiveFileName] eq ".zip"} then {
          218  +      if {![file exists $zip]} then {
          219  +        usage [appendArgs "tool \"" $zip "\" is missing"]
   118    220         }
   119    221   
   120         -      set manifestFileNames [list]
          222  +      lappend listCommand $zip -Z -1 $archiveFileName
   121    223   
   122         -      foreach list [lrange $manifests($manifest) 1 end] {
   123         -        set rawManifestFileNames [set [appendArgs \
   124         -            [appendArgs [lindex $manifests($manifest) 0] \
   125         -            _manifests] ( $list )]]
          224  +      lappend extractCommand $zip -j -o $archiveFileName \
          225  +          \"%fileName%\" -d \"%directory%\"
          226  +    } elseif {[file extension $archiveFileName] eq ".exe" && \
          227  +        [string match -nocase *Setup*.exe $manifest]} then {
          228  +      #
          229  +      # HACK: Assume this is an Inno Setup package and process
          230  +      #       it using the necessary external tool.
          231  +      #
          232  +      lappend listCommand $innounp -v $archiveFileName
   126    233   
   127         -        if {[info exists manifests($manifest,subst)]} then {
   128         -          set rawManifestFileNames [subst $rawManifestFileNames]
   129         -        }
   130         -
   131         -        foreach manifestFileName $rawManifestFileNames {
   132         -          lappend manifestFileNames $manifestFileName
   133         -        }
          234  +      lappend extractCommand $innounp -x -e -y \"-d%directory%\" \
          235  +          $archiveFileName \"%fileName%\"
          236  +    } else {
          237  +      if {![file exists $rar]} then {
          238  +        usage [appendArgs "tool \"" $rar "\" is missing"]
   134    239         }
   135    240   
   136         -      set listCommand [list]
   137         -      lappend listCommand exec -success Success -nocarriagereturns --
   138         -
   139         -      if {[file extension $archiveFileName] eq ".zip"} then {
   140         -        if {![file exists $zip]} then {
   141         -          usage [appendArgs "tool \"" $zip "\" is missing"]
   142         -        }
   143         -
   144         -        lappend listCommand $zip -Z -1 $archiveFileName
   145         -      } elseif {[file extension $archiveFileName] eq ".exe" && \
   146         -          [string match -nocase *Setup*.exe $manifest]} then {
   147         -        #
   148         -        # HACK: Assume this is an Inno Setup package and process
   149         -        #       it using the necessary external tool.
   150         -        #
   151         -        lappend listCommand $innounp -v $archiveFileName
   152         -      } else {
   153         -        if {![file exists $rar]} then {
   154         -          usage [appendArgs "tool \"" $rar "\" is missing"]
   155         -        }
   156         -
   157         -        lappend listCommand $rar vb -- $archiveFileName
   158         -      }
   159         -
   160         -      if {[catch {eval $listCommand} result] == 0} then {
   161         -        #
   162         -        # HACK: The Inno Setup unpacking tool requires some extra
   163         -        #       parsing logic to handle the output.
   164         -        #
   165         -        if {[string first [file tail $innounp] $listCommand] != -1} then {
   166         -          set containedFileNames [list]
   167         -
   168         -          foreach {dummy matchFileName} [regexp -line -all -inline -- \
   169         -              {^[ 0-9]{10}  \d{4}\.\d{2}\.\d{2} \d{2}:\d{2}  (.*)$} $result] {
   170         -            #
   171         -            # NOTE: Add the file name extracted from the output
   172         -            #       line to the list of file names contained in
   173         -            #       this archive.
   174         -            #
   175         -            lappend containedFileNames $matchFileName
   176         -          }
   177         -        } else {
   178         -          set containedFileNames [split [string map [list \\ /] \
   179         -              [string trim $result]] \n]
   180         -        }
   181         -
   182         -        foreach manifestFileName $manifestFileNames {
          241  +      lappend listCommand $rar vb -- $archiveFileName
          242  +
          243  +      lappend extractCommand $rar x -ep -y -- $archiveFileName \
          244  +          \"%fileName%\" \"%directory%\"
          245  +    }
          246  +
          247  +    if {[catch {eval $listCommand} result] == 0} then {
          248  +      #
          249  +      # HACK: The Inno Setup unpacking tool requires some extra
          250  +      #       parsing logic to handle the output.
          251  +      #
          252  +      if {[string first [file tail $innounp] $listCommand] != -1} then {
          253  +        set containedFileNames [list]
          254  +
          255  +        foreach {dummy matchFileName} [regexp -line -all -inline -- \
          256  +            {^[ 0-9]{10}  \d{4}\.\d{2}\.\d{2} \d{2}:\d{2}  (.*)$} $result] {
          257  +          #
          258  +          # NOTE: Add the file name extracted from the output
          259  +          #       line to the list of file names contained in
          260  +          #       this archive.
   183    261             #
   184         -          # TODO: Should we use -nocase here because Windows
   185         -          #       is the primary release platform?
   186         -          #
   187         -          if {[lsearch -exact -- $containedFileNames \
   188         -              $manifestFileName] == -1} then {
   189         -            puts stdout [appendArgs \
   190         -                "ERROR: Archive \"" $archiveFileName \
   191         -                "\" missing file \"" $manifestFileName \
   192         -                "\" from manifest \"" $manifest "\"."]
   193         -
   194         -            set exitCode 1
   195         -          }
   196         -        }
   197         -
   198         -        foreach containedFileName $containedFileNames {
   199         -          #
   200         -          # TODO: Should we use -nocase here because Windows
   201         -          #       is the primary release platform?
   202         -          #
   203         -          if {[lsearch -exact -- $manifestFileNames \
   204         -              $containedFileName] == -1} then {
   205         -            puts stdout [appendArgs \
   206         -                "ERROR: Archive \"" $archiveFileName \
   207         -                "\" contains file \"" $containedFileName \
   208         -                "\" not in manifest \"" $manifest "\"."]
   209         -
   210         -            set exitCode 1
   211         -          }
          262  +          lappend containedFileNames $matchFileName
   212    263           }
   213    264         } else {
   214         -        puts stdout [appendArgs \
   215         -            "ERROR: Failed to get list of files in archive \"" \
   216         -            $archiveFileName "\", error: " $result]
          265  +        set containedFileNames [split [string map [list \\ /] \
          266  +            [string trim $result]] \n]
          267  +      }
          268  +
          269  +      foreach manifestFileName $manifestFileNames {
          270  +        #
          271  +        # TODO: Should we use -nocase here because Windows
          272  +        #       is the primary release platform?
          273  +        #
          274  +        if {[lsearch -exact -- $containedFileNames \
          275  +            $manifestFileName] == -1} then {
          276  +          puts stdout [appendArgs \
          277  +              "ERROR: Archive \"" $archiveFileName \
          278  +              "\" missing file \"" $manifestFileName \
          279  +              "\" from manifest \"" $manifest "\"."]
          280  +
          281  +          set exitCode 1
          282  +        }
          283  +
          284  +        #
          285  +        # NOTE: Skip checking SHA1 hashes if it was not requested on the
          286  +        #       command line.
          287  +        #
          288  +        if {!$withHashes} then {
          289  +          continue
          290  +        }
          291  +
          292  +        #
          293  +        # HACK: For now, only verify SHA1 hashes for those files present
          294  +        #       in the repository.
          295  +        #
          296  +        if {![string match -nocase -- *Source* $archiveFileName]} then {
          297  +          continue
          298  +        }
          299  +
          300  +        set extractCommandMap [list \
          301  +            %fileName% [file nativename $manifestFileName] \
          302  +            %directory% [file nativename $extractDirectory]]
          303  +
          304  +        set extractFileName [file join \
          305  +            $extractDirectory [file tail $manifestFileName]]
          306  +
          307  +        catch {
          308  +          file attributes $extractFileName -readonly false
          309  +          file delete $extractFileName
          310  +        }
          311  +
          312  +        try {
          313  +          if {[catch {eval [string map \
          314  +              $extractCommandMap $extractCommand]} result] == 0} then {
          315  +            if {[info exists hashes($manifestFileName)]} then {
          316  +              set hash [getSha1Sum $extractFileName]
          317  +
          318  +              if {$hash ne $hashes($manifestFileName)} then {
          319  +                puts stdout [appendArgs \
          320  +                    "ERROR: Archive \"" $archiveFileName \
          321  +                    "\" file \"" $manifestFileName \
          322  +                    "\" repository hash mismatch, have \"" \
          323  +                    $hash "\", want \"" $hashes($manifestFileName) \
          324  +                    "\"."]
          325  +
          326  +                set exitCode 1
          327  +              }
          328  +            } else {
          329  +              puts stdout [appendArgs \
          330  +                  "ERROR: Archive \"" $archiveFileName \
          331  +                  "\" file \"" $manifestFileName \
          332  +                  "\" has no repository hash."]
          333  +
          334  +              set exitCode 1
          335  +            }
          336  +          }
          337  +        } finally {
          338  +          catch {
          339  +            file attributes $extractFileName -readonly false
          340  +            file delete $extractFileName
          341  +          }
          342  +        }
          343  +      }
          344  +
          345  +      foreach containedFileName $containedFileNames {
          346  +        #
          347  +        # TODO: Should we use -nocase here because Windows
          348  +        #       is the primary release platform?
          349  +        #
          350  +        if {[lsearch -exact -- $manifestFileNames \
          351  +            $containedFileName] == -1} then {
          352  +          puts stdout [appendArgs \
          353  +              "ERROR: Archive \"" $archiveFileName \
          354  +              "\" contains file \"" $containedFileName \
          355  +              "\" not in manifest \"" $manifest "\"."]
   217    356   
   218         -        set exitCode 1
          357  +          set exitCode 1
          358  +        }
   219    359         }
   220         -    }
          360  +    } else {
          361  +      puts stdout [appendArgs \
          362  +          "ERROR: Failed to get list of files in archive \"" \
          363  +          $archiveFileName "\", error: " $result]
   221    364   
   222         -    exit $exitCode
   223         -  } else {
   224         -    usage "invalid directory"
          365  +      set exitCode 1
          366  +    }
   225    367     }
          368  +
          369  +  exit $exitCode
   226    370   } else {
   227    371     usage ""
   228    372   }

Changes to www/release.wiki.

   318    318   
   319    319     <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>
   320    320   
   321    321     <li>
   322    322       Enter the following command to build all the source release packages:
   323    323       <br />
   324    324       <br />
   325         -    <b>..\Externals\Eagle\bin\EagleShell.exe -file verify.eagle Output</b>
          325  +    <b>..\Externals\Eagle\bin\EagleShell.exe -file verify.eagle Output true</b>
   326    326       <br />
   327    327       <br />
   328    328       <i>If errors are generated, the file
   329    329       &quot;&lt;root&gt;\Setup\data\verify.lst&quot; may need to be updated to
   330    330       account for the files that have been added and/or removed from the release
   331    331       archives since the previous release.</i>
   332    332     </li>