81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
+
+
+
+
+
+
+
+
+
|
# that Fossil committed a set of files.
#
variable fossilCommitPattern; # DEFAULT: {^New_Version: ([0-9a-f]{40})$}
if {![info exists fossilCommitPattern]} then {
set fossilCommitPattern {^New_Version: ([0-9a-f]{40})$}
}
#
# NOTE: Emit diagnostic messages when a new package is submitted?
#
variable verboseMetadataSubmit; # DEFAULT: false
if {![info exists verboseMetadataSubmit]} then {
set verboseMetadataSubmit false
}
}
#
# NOTE: This procedure returns a string value, formatted for use within a
# script block being processed by the [string map] command. The
# value argument is the string value to format. No return value is
# reserved to indicate an error. This procedure may not raise any
|
308
309
310
311
312
313
314
315
316
317
318
319
320
321
|
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
%ns%::downloadFiles %language% %version% %platform% $fileNames $options
%ns%::logoutAndResetCookie
}]
}]]
}
#
# NOTE: This procedure creates textual data that conforms to the content
# type "multipart/form-data", per RFC 2388. The boundary argument
# is a boundary value, as specified in section 4.1 of the RFC. The
# request argument is the dictionary of name/value pairs to include
# in the form body. This procedure may not raise script errors.
#
proc createMultipartFormData { boundary request } {
set result ""
foreach {name value} $request {
append result -- $boundary \r\n
append result "Content-Disposition: form-data; name=\""
append result $name \"\r\n\r\n
append result $value \r\n
}
if {[string length $result] > 0} then {
append result -- $boundary --\r\n
}
if {[isEagle]} then {
return [object create -alias String $result]
} else {
return $result
}
}
#
# NOTE: This procedure returns the full URI to use when submitting a new
# package to the package repository server. There are no arguments.
# This procedure may raise script errors.
#
proc getSubmitUri {} {
#
# NOTE: Fetch the base URI for the package repository server. If it
# is not available for some reason, just return an empty string
# to the caller (i.e. as we cannot do anything productive).
#
set baseUri [::PackageRepository::getLookupBaseUri]
if {[string length $baseUri] == 0} then {
return ""
}
#
# NOTE: Build the HTTP request URI and include the standard query
# parameters (with constant values) for this request type.
#
if {[isEagle]} then {
return [appendArgs \
$baseUri ?raw=1&method=submit]
} else {
package require http 2.0
return [appendArgs \
$baseUri ? [::http::formatQuery raw 1 method submit]]
}
}
#
# NOTE: This procedure attempts to submit the metadata for a new package to
# the package repository server. Upon success, an empty string will
# be returned. Upon failure, a script error will be raised. The
# apiKey argument is the list of API keys to use. The package argument
# is the name of the package. The patchLevel argument is the specific
# patch level being submitted. The language argument must be an empty
# string, "Tcl", or "Eagle". If it is an empty string, the current
# language will be assumed. The script argument is the script to be
# evaluated when the package needs to be provided. The certificate
# argument is the certificate associated with the script, which may be
# an OpenPGP signature or a Harpy script certificate.
#
# <public>
proc submitPackageMetadata {
apiKey package patchLevel language script certificate } {
variable verboseMetadataSubmit
#
# NOTE: Fetch the submission URI for the package repository server. If
# it is not available for some reason, raise a script error.
#
set uri [getSubmitUri]
if {[string length $uri] == 0} then {
error ""
}
if {[string length $language] == 0} then {
set language [expr {[isEagle] ? "Eagle" : "Tcl"}]
}
if {[isEagle]} then {
set boundary [string map \
[list + "" / "" = ""] [base64 encode [expr {randstr(50)}]]]
} else {
set boundary [::PackageRepository::getUniqueSuffix]
}
set contentType [appendArgs \
"multipart/form-data; boundary=" $boundary]
set formData [createMultipartFormData $boundary \
[list apiKey $apiKey package $package patchLevel \
$patchLevel language $language script $script \
certificate $certificate]]
if {[isEagle]} then {
if {![object invoke Eagle._Tests.Default \
TestHasScriptNewWebClientCallback ""]} then {
set error null
set code [object invoke Eagle._Tests.Default \
TestSetScriptNewWebClientCallback "" true true error]
if {$code ne "Ok"} then {
error [getStringFromObjectHandle $error]
}
}
set script [object create String {
if {[methodName ToString] eq "GetWebRequest"} then {
webRequest ContentType $contentType
}
}]
return [uri upload \
-inline -raw -encoding identity -webclientdata \
$script -data $formData $uri]
} else {
set options [list \
-binary true -type $contentType -query $formData]
return [eval ::PackageRepository::getFileViaHttp \
[list $uri] [list 20] [list stdout] [list \
[expr {!$verboseMetadataSubmit}]] $options]
}
}
#
# NOTE: This procedure attempts to stage the specified package files using
# Fossil. The fileNames argument is a list of (fully?) qualified
# local file names to stage.
#
# <public>
proc stagePackageFiles { language version platform fileNames } {
|
425
426
427
428
429
430
431
432
433
434
435
436
437
438
|
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
|
+
+
+
|
# package and then forcibly adjust various settings to the values
# necessary for this tool. In the future, this section may need to
# be tweaked to account for changes to the Package Repository Client
# package.
#
namespace eval ::PackageRepository {
variable verboseUriDownload true
variable autoRequireGaruda false
variable autoLoadTcl false
variable autoHook false
}
#
# NOTE: This package requires both the package repository and downloader
# client packages.
#
package require Eagle.Package.Downloader
|