Skip to content

Instantly share code, notes, and snippets.

@line-o
Last active September 8, 2022 14:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save line-o/8bab558790a532939432da5cd3ad8ef7 to your computer and use it in GitHub Desktop.
Save line-o/8bab558790a532939432da5cd3ad8ef7 to your computer and use it in GitHub Desktop.
Update all packages were newer versions are available in the package repository
xquery version "3.1";
import module namespace semver = "http://exist-db.org/xquery/semver";
declare namespace http="http://expath.org/ns/http-client";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "json";
declare option output:media-type "application/json";
declare variable $package-repo := "https://exist-db.org/exist/apps/public-repo";
declare variable $local-cache := "remote-packages.xml";
declare variable $cache-collection := "/db";
declare variable $cache-path := $cache-collection || "/" || $local-cache;
declare variable $exist-version := (
util:system-property("product-semver"),
util:system-property("product-version")
)[1];
declare variable $list-packages-url :=
$package-repo || "/public/apps.xml" ||
"?version=" || $exist-version ||
"&source=" || util:system-property("product-source")
;
declare
function local:read-packages-from-repo() as document-node() {
let $data := http:send-request(
<http:request method="get" timeout="100" href="{$list-packages-url}" />)
return
if ($data[1]/@status ne '200')
then
error(xs:QName("repo-read-error"), $data[1], $data[2])
else
let $store := xmldb:store($cache-collection, $local-cache, $data[2])
return $data[2]
};
declare
function local:available-packages($force as xs:boolean?) as map(xs:string, xs:string) {
let $raw :=
if (
not(doc-available($cache-path)) or $force
(: or last-modified older than $threshhold :)
)
then local:read-packages-from-repo()//app
else doc($cache-path)//app
return map:merge(
$raw ! map { name/string(): version/string() })
};
declare function local:map-package ($packageURI as xs:string) as map(*) {
let $pkgInfo := $packageURI
=> repo:get-resource("expath-pkg.xml")
=> util:binary-to-string()
=> parse-xml()
let $version := $pkgInfo/node()/@version/string()
return map { "uri": $packageURI, "version" : $version }
};
declare function local:list-local-packages() {
for-each(repo:list(), local:map-package#1)
};
let $local-packages := local:list-local-packages()
let $remotes := local:available-packages(false())
return array {
for $package in $local-packages
let $uri := $package?uri
let $installed := $package?version
let $available := $remotes?($uri)
let $updated :=
if (semver:gt($available, $installed))
then
let $undeploy := repo:undeploy($uri)
let $remove := repo:remove($uri)
return
repo:install-and-deploy($uri, $available,
xs:anyURI($package-repo || "/find"))
else
false()
return map {
"uri": $uri,
"installed": $installed,
"available": $available,
"updated": $updated
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment