###############################################################################
#
# pkgd.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Package Downloader Client
#
# Copyright (c) 2007-2012 by Joe Mistachkin. All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################
#
# NOTE: Use our own namespace here because even though we do not directly
# support namespaces ourselves, we do not want to pollute the global
# namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::PackageDownloader {
proc setupDownloadVars {} {
#
# NOTE: Prevent progress messages from being displayed while downloading
# from the repository, etc? By default, this is enabled.
#
variable quiet; # DEFAULT: true
if {![info exists quiet]} then {
set quiet true
}
#
# NOTE: The base URI for the package distribution web site.
#
variable baseUri; # DEFAULT: https://urn.to/r/pkgr
if {![info exists baseUri]} then {
set baseUri https://urn.to/r/pkgr
}
#
# NOTE: The URI where a single package file may be found. This file will
# belong to a specific version of one package.
#
variable downloadUri; # DEFAULT: ${baseUri}?...&filename=${fileName}
if {![info exists downloadUri]} then {
set downloadUri {${baseUri}?download&ci=trunk&filename=${fileName}}
}
#
# NOTE: The root directory where any persistent packages will be saved.
#
variable persistentDirectory; # DEFAULT: [getPersistentRootDirectory]
if {![info exists persistentDirectory]} then {
set persistentDirectory [getPersistentRootDirectory]
}
}
proc getPersistentRootDirectory {} {
#
# NOTE: Return a directory parallel to the one containing the library
# directory.
#
return [file join [file dirname [info library]] pkgr]
}
proc addToAutoPath { language directory } {
#
# NOTE: Add the specified directory to the auto-path if not already
# present.
#
if {[string length $language] == 0 || $language eq "eagle"} then {
if {[isEagle]} then {
if {![info exists ::auto_path] || \
[lsearch -exact $::auto_path $directory] == -1} then {
lappend ::auto_path $directory
}
} else {
::PackageRepository::eagleMustBeReady
eagle [string map [list %directory% $directory] {
if {![info exists ::auto_path] || \
[lsearch -exact $::auto_path {%directory%}] == -1} then {
lappend ::auto_path {%directory%}
}
}]
}
} elseif {$language eq "tcl"} then {
if {[isEagle]} then {
tcl eval [tcl master] [string map [list %directory% $directory] {
if {![info exists ::auto_path] || \
[lsearch -exact $::auto_path {%directory%}] == -1} then {
lappend ::auto_path {%directory%}
}
}]
} else {
if {![info exists ::auto_path] || \
[lsearch -exact $::auto_path $directory] == -1} then {
lappend ::auto_path $directory
}
}
} else {
error "unsupported language, no idea how to modify auto-path"
}
}
proc downloadFiles { language version fileNames persistent } {
variable baseUri
variable downloadUri
variable persistentDirectory
variable quiet
if {$persistent} then {
set downloadRootDirectory [file join $persistentDirectory]
} elseif {[info exists ::env(PKGD_TEMP)]} then {
set downloadRootDirectory [file join $::env(PKGD_TEMP) pkgr]
} elseif {[info exists ::env(TEMP)]} then {
set downloadRootDirectory [file join $::env(TEMP) pkgr]
} elseif {[info exists ::env(TMP)]} then {
set downloadRootDirectory [file join $::env(TMP) pkgr]
} else {
error "please set PKGD_TEMP (via environment) to temporary directory"
}
set downloadDirectories [list]
foreach fileName $fileNames {
if {[string length $fileName] == 0 || \
[file pathtype $fileName] ne "relative"} then {
error [appendArgs \
"bad file name \"" $fileName "\", not relative"]
}
set directoryParts [file split [file dirname $fileName]]
if {[llength $directoryParts] == 0} then {
error [appendArgs \
"bad file name \"" $fileName "\", no directory parts"]
}
set downloadDirectory [eval file join \
[list $downloadRootDirectory] $directoryParts]
set downloadFileName [file join $downloadDirectory \
[file tail $fileName]]
if {!$persistent} then {
catch {file delete $downloadFileName}
}
file mkdir [file dirname $downloadFileName]
set fileName [file join $language $version $fileName]
set uri [subst $downloadUri]
if {[isEagle]} then {
writeFile $downloadFileName [interp readorgetscriptfile -- "" $uri]
} else {
writeFile $downloadFileName [::PackageRepository::getFileViaHttp \
$uri 10 stdout $quiet]
}
lappend downloadDirectories [file dirname $downloadDirectory]
}
set downloadDirectories [lsort -unique $downloadDirectories]
foreach downloadDirectory $downloadDirectories {
addToAutoPath $language $downloadDirectory
}
}
#
# NOTE: Setup the variables, within this namespace, used by this script.
#
setupDownloadVars
#
# NOTE: This package requires the package repository client package.
#
package require Eagle.Package.Repository
#
# NOTE: Provide the package to the interpreter.
#
package provide Eagle.Package.Downloader \
[expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}