From 43e58d72a8f08097dbdc14f05f61a278b213c053 Mon Sep 17 00:00:00 2001 From: AR2000 Date: Sat, 22 Mar 2025 21:32:13 +0100 Subject: [PATCH] [pm-get] 1.5.0 fix upgrade --- packages/manifest | 2 +- packages/pm_get.tar | Bin 30720 -> 30720 bytes pm_get/bin/pm-get.lua | 225 ++++++++++++++++++++++++++--------------- pm_get/pm_get.manifest | 2 +- programs.cfg | 2 +- 5 files changed, 145 insertions(+), 86 deletions(-) diff --git a/packages/manifest b/packages/manifest index ca2e9a9..d5481b7 100644 --- a/packages/manifest +++ b/packages/manifest @@ -22,7 +22,7 @@ ["pm_get"] = { ["manifestVersion"] = "1.0", ["package"] = "pm_get", - ["version"] = "1.4.5", + ["version"] = "1.5.0", ["name"] = "pm get", ["repo"] = "tree/master/pm_get", ["description"] = "Download and install package for pm", diff --git a/packages/pm_get.tar b/packages/pm_get.tar index b2c5521dc88728558b2d68265a069537f84adf6e..a2bbc0b99fa015e1e4c71e1652e8be30a41002d3 100644 GIT binary patch delta 3483 zcmbtXU2GIp6lVEt%5O^xZMTri+Jza|S-Pd5QnqwyMgGH2OZY2vx^s7#ba!T$nOz`& z#YZ2E#uHx+3E_*pgE7W)?w#44ZZRP`$!2Ho`Muxy z&bfDQ{~o*jd+fu*ix=%o_t%as9$XXOxnsv*W(eEEl)FVfVVPGHU&l8;#XP&>=DFI+@G04Oy~Hej^|cZ&bIbQwmfg4|L3T|F$P8O3%&|v1->vYv0Ik;v^N77n03M_|mQ`6c%c@m)(6_DyqoZ{}huozO zcz-$pT3^eoSzrnZROVmi785&3o0i92pO(XHF+G)W%MfA1@A-*GEL6;XuDcMHz!Q0C zEx}j&SJfWJ-GxO>(?&1z{0zg4Fc;>`6j_zKo@ram^jO|5JGyTo(Cn(|UuFh(TG3?0 z(OtbvznJH{rd5nAl84Bm%l(RL!P~pLX7dzij60{Le+A7`6j0VmNONvc$)w0}ifxfz zwls+cgiW)U0Ht&g_k`^@hdr- z%uD1Ulrg53QB}4l%lc(8N*)hFHhIemZ?iAr4RZ~=g(Y@f+f@om;*?$H{$<3KT}9Ti ztFBG2K>@PKD@?ZxLJnUO0a}Ek+A7Oy=i$%zirU1+)h+9EpHC4Mx?wPvJGN)~wtKyH zbMu!AyKf5OMQZ1A&n{KD0ms!o^p(HPN~Y(h;Zt>JG5v(URdrXOG{&8AmvhC@^D}yp zr_j4Jmh~cZ{Oe9#4jYH!d#U~E`m#>9>I6p%%l7MTWNU;@MdQM~t+_?#Gn4Ri>s@$v z+kvz7{zkEusdp!}F13j{r@up2)FX3LNuAQIqHAIVQUtDy$Ct^@HQ~+4PHfzE&?Y+I zSaL;Ms4wIc7`4}DnqawsUI>#b71QNLz^YqOl;GR(j*%vwggKr^-;?JDCg*vWOGg}s z7&_5xg=jPdhFr26CWqTvLRC0&G7j&YX@NCk%j%1@PqgorZqbfl&E+tVrS4^z z;|ZPa^G77Wz+MhJrHE1JW|u-o+!DPVKVIqudz9T znS@mCo|S`TcyCJPax)lLl1+t*mG^1<6)@0I83(zpP=g8DNVOmXln81@BzDC&u$O$ISxw{JjyApeK&%mJkUEG7806miJa)ef?cr;oGv1&m@5=fZa!oYZjoj{ij}>h zAf1>1!D<6BYOaZBZwDGpyCID7I&zP^X_i^4Z$};?43|VGu`W`AXCqy!o3eo^r4#h* zc6f4OIlMK{4IgEDUqRRfv@{ASljod8qTNEhbZ`iQGu{PHMwhjV*bxjXrT2!r_6p7= zCH0h~r^;!Jb3{yK;Supe5GAl-f$QE!l0DRxYa48mhM7qfHeKw2zfQKnvw>dRLf62H zrYugif{t{c;V??58m3;fY|l6I%rHH=H)$5X=4&O>;=8f2J$$9Bl13D*qfYgvrwp?L zFD)`~D&C&%9HC+of+14>0ny%nM>O|85mj4Z(?lPfKewvA(S{+WFp|vlMxlDp8v3YxN~KSuE{|Z#IUbpR`fv delta 1789 zcmZuyO>7%Q6pr)bnglzE61Vwh;?#H@ysk}L5=z{p;G_*n>=YcN(gbcdXRF5g|d*azP*=E=Y(2w468~wHL$%loKZo%{@C93Fe_t#)>#;uq~~XR2>BHJg}8v?WfSwnTC!mAcr55|H#rwkPi^DJ>dSOc(>te7b zydy?$@6=^Q$`E~x#t?K|tl~0>F_2gTHQJ5nBbSh>Sq?glqB<{WbZ`q1RdNns(vGwEwFXTsZ z_PdLByGFS_8oB2ULYg9h!t(S=tXUUkYc@(~^>Eu2<^4Ks;Z0*bdw==HcvGBCm3W0H zCnhD7wx7BBtOp*Bb@sGCz(#&>qOpELa%{tC%1jHOrLCx@g%#zb@;s8IZR%wMON1NX z;p)&CH#&spGhXsGg)?DyehxmW4nrZ*3BRxP%)EkC)|yhiRHB-s4m2C07WdI56gH6% zHlra&|Flc||M_jWol8L_(*IPG3*1dlofXA=E|a5v#R@4_(H_?!?aZ+K)ymHv_$%du zkI6KAy?UdsdA80ugSH-ok+oQm7=~sDq0Q{d`o`MQ`cgK(lnKH8t+S9_|HF4>M>8Z@ zE!&r~qNllnz_lUxFqifu?4NS)bxn#QXFzAvonRBGgh;5a)0>96!=1U&kwi;TnV2lH z!N;A|XaE8+Z@%S(%!^K>#vxi|y%sMM%WVgd1g;-81A4Wb#WljlfKS1RJ1kxugyXph z_;cPrS;Xqg#BG~I5l^q5LrGRW__yGLH#d?0l-2%V^Ebbrvl6gTHly8eSd0W~*r=}4 z>kun~d-E`PCW@1`U;3pz)Fkph{P`_lKPdg<8E!U+rsCXm4M%ts8GwD|>GN)$F;v5< zTq0ECPi9LeKRD8`$6ZCRfeLB5UJJqX{P>g*TGr~SgxF3)G>CzRcjHugG=3C5Uziwd z>YML5y>V`g?YFu?d|?K{k-h=mNSZ%qgefk3KYPx95|e&rAU`YgKh7!&kLHKq_(CUq bx8U!6EEs$enS{T?gLX##HeeqsKl=UyecV?H diff --git a/pm_get/bin/pm-get.lua b/pm_get/bin/pm-get.lua index e8c1b52..82b628b 100644 --- a/pm_get/bin/pm-get.lua +++ b/pm_get/bin/pm-get.lua @@ -37,6 +37,21 @@ local reposRuntimeCache local f = string.format +local function tableMergeUniq(target, source) + local newElements = {} + for _, v in pairs(source) do + local new = true + for _, vv in pairs(target) do + if v == vv then + new = false + break + end + end + if (new) then table.insert(newElements, v) end + end + for _, v in pairs(newElements) do table.insert(target, v) end +end + local function printf(...) print(f(...)) end @@ -62,6 +77,22 @@ local function compareVersion(a, b) end end +---Check if the pkg version is compatible with dep +---@param dep string +---@param pkg string +---@return boolean +local function checkDepVersion(dep, pkg) + checkArg(1, dep, 'string') + checkArg(2, pkg, 'string') + if (dep == "oppm" or dep == "") then return true end + if (dep:sub(1, 1) == ">") then + return compareVersion(pkg, dep:sub(2, -1)) <= 0 + elseif (dep:sub(1, 1) == "=") then + return compareVersion(pkg, dep:sub(2, -1)) == 0 + end + error(f("Something went wrong with dep=%q and pkg=%q", dep, pkg)) +end + local function confirm(prompt, default) if (opts["y"]) then return true end while true do @@ -120,7 +151,7 @@ end local function getCachedPackageList() if (not reposRuntimeCache) then if (not filesystem.exists(REPO_MANIFEST_CACHE)) then - printferr("No data. Run `pm-get upddate` or add repositorys") + printferr("No data. Run `pm-get update` or add repository") return {} end local cache = assert(io.open(REPO_MANIFEST_CACHE)) @@ -145,39 +176,33 @@ local function getCachedPackageManifest(name, targetRepo) return nil, nil end ----@param package string ----@param dep? table Current dependance list. ----@param cleanup? boolean cleanup the dep list. Default `true` ----@return table? dep ordered list of dependances +---@param package string|table +---@param resolved? table Current dependency list. +---@return table? dep ordered list of dependency ---@return string? error -local function buildDepList(package, dep, cleanup) - if not dep then dep = {} end - assert(dep) - if cleanup == nil then cleanup = true end - local packageManifest = getCachedPackageManifest(package) +local function resolveDepTree(package, resolved) + if (type(package) == "string") then package = {package, "oppm"} end + if not resolved then resolved = {} end + local packageManifest = getCachedPackageManifest(package[1]) if (not packageManifest) then return nil, string.format("Package %q cannot be found", package) end if (packageManifest.dependencies) then - for dependance, requiredVersion in pairs(packageManifest.dependencies) do - table.insert(dep, {dependance, requiredVersion}) - buildDepList(dependance, dep, false) - end - end - - if (cleanup) then - local hash = {} - local rm = {} - for k, v in ipairs(dep) do - if not hash[v[1]] then - table.insert(hash, v[1]) - else - table.insert(rm, 1, k) + for dep, requiredVersion in pairs(packageManifest.dependencies) do + local new = -1 + for i, v in pairs(resolved) do + if (v[1] == dep) then + new = i + break + end end - end - for _, v in ipairs(rm) do - table.remove(dep, v) + if (new == -1) then + resolveDepTree({dep, requiredVersion}, resolved) + elseif (compareVersion(resolved[new][2], requiredVersion:sub(2, -1)) < 0) then + resolved[new][2] = requiredVersion + end + table.insert(resolved, package) end end - return dep + return resolved end ---Download from url and return it @@ -236,6 +261,59 @@ local function needUpgrade(pkg) return false end +---List the packages than can be upgraded +---@return table +local function listNeedUpgrade() + local canBeUpgraded = {} + for pkgName in pairs(pm.getInstalled()) do + if (needUpgrade(pkgName)) then table.insert(canBeUpgraded, pkgName) end + end + return canBeUpgraded +end + +---Find missing dependencies for the package +---@param pkg string +---@return table?, table|string +local function findMissingDep(pkg) + local missingDep = {} + local outdatedDep = {} + ---@type manifest? + local packageManifest + if pm.isInstalled(pkg) then + packageManifest = pm.getManifestFromInstalled(pkg) + else + packageManifest = getCachedPackageManifest(pkg) + end + if (not packageManifest) then return nil, f("Cannot find dependencies for %s. Package not found", pkg) end + + local resolvedDepTree, msg = resolveDepTree(pkg) + if (not resolvedDepTree) then + ---@cast msg -nil + return nil, msg + end + + for _, dep in pairs(resolvedDepTree) do + if (not pm.isInstalled(dep[1])) then + local manifest = getCachedPackageManifest(dep[1]) + if (not manifest or not checkDepVersion(dep[2], manifest.version)) then + return nil, f("Cannot fulfil dependency : %s (%s) for %s for (%s)", dep[1], dep[2], pkg, packageManifest.version) + end + table.insert(missingDep, dep[1]) + else + local manifest = pm.getManifestFromInstalled(dep[1]) + if (checkDepVersion(dep[2], manifest.version) == false) then + ---@diagnostic disable-next-line: cast-local-type + manifest = getCachedPackageManifest(dep[2]) + if (not manifest or not checkDepVersion(dep[2], manifest.version)) then + return nil, f("Cannot fulfil dependency : %s (%s) for %s for (%s)", dep[1], dep[2], pkg, packageManifest.version) + end + table.insert(outdatedDep, dep[1]) + end + end + end + return missingDep, outdatedDep +end + --============================================================================= ---Install a package @@ -278,12 +356,12 @@ end ---@param packages table|string ---@param markAuto? boolean ----@param buildDepTree? boolean -local function install(packages, markAuto, buildDepTree) - if (buildDepTree == nil) then buildDepTree = true end +---@return number 1=ok,0=nothing done, -1=error +---@return string? error +local function install(packages, markAuto) if (type(packages) == "string") then packages = {packages} end - ---get the dependance list - local depList = {} + ---get the dependency list + local depList, toInstall, toUpgrade = {}, {}, {} for _, package in pairs(packages) do local targetManifest, repoName = getCachedPackageManifest(package) --check that the packet exists @@ -291,45 +369,42 @@ local function install(packages, markAuto, buildDepTree) printferr("Package %s not found", package) os.exit(1) end - if (buildDepTree) then - buildDepList(package, depList) + local newInstall, newUpgrade = findMissingDep(package) + if (not newInstall) then + ---@cast newUpgrade -table + return -1, newUpgrade end + assert(type(newInstall) == "table") + assert(type(newUpgrade) == "table") + tableMergeUniq(toInstall, newInstall) + tableMergeUniq(toUpgrade, newUpgrade) end - local toInstall = {} - local toUpgrade = {} - for _, dep in pairs(depList) do - if (not pm.isInstalled(dep[1])) then - local exists = getCachedPackageManifest(dep[1]) - if (not exists) then - printferr("Cannot fuffil dependency : %s (%s)", dep[1], dep[2]) - return -1 - end - table.insert(toInstall, dep[1]) - else - --TODO : check version - end - end + local display = {} for _, v in pairs(toInstall) do table.insert(display, v) end for _, v in pairs(packages) do table.insert(display, v) end if (#display > 0) then printf("Will be installed :\n %s", table.concat(display, ', ')) end if (#toUpgrade > 0) then printf("Will be updated :\n %s", table.concat(toUpgrade, ', ')) end printf("%d upgraded, %d newly installed", #toUpgrade, #display) - if (#display == 0 and #toUpgrade == 0) then return end - if not confirm("Proceed") then return end + if (#display == 0 and #toUpgrade == 0) then return 0 end + if not confirm("Proceed") then return 0 end if (not opts['dry-run']) then for _, dep in pairs(toUpgrade) do - --TODO : upgrade printf("Updating dependency : %s", dep) - error("UNIMPLEMENTED") + printf("Installing dependency : %s", dep) + local code, errorReason = doInstall(dep, true) + if (errorReason) then + printferr("Failed to install %q. Giving up.", dep) + return -1 + end end for _, dep in pairs(toInstall) do printf("Installing dependency : %s", dep) local code, errorReason = doInstall(dep, true) if (errorReason) then - printferr("Failed to install %q. Abording", dep) + printferr("Failed to install %q. Giving up.", dep) return -1 end end @@ -337,12 +412,12 @@ local function install(packages, markAuto, buildDepTree) printf("Installing : %s", package) local code, errorReason = doInstall(package, false) if (errorReason) then - printferr("Failed to install %q. Abording", package) + printferr("Failed to install %q. Giving up.", package) return -1 end end end - return 0 + return 1 end local function uninstall(packages) @@ -388,16 +463,7 @@ local function update() end io.open(REPO_MANIFEST_CACHE, "w"):write(serialization.serialize(manifests)):close() - --check if packages need updating - local canBeUpgraded = 0 - local remotePackages = getCachedPackageList() - local installedPackages = pm.getInstalled() - for pkgName in pairs(installedPackages) do - if (needUpgrade(pkgName)) then - canBeUpgraded = canBeUpgraded + 1 - end - end - printf("%s package(s) can be upgraded", canBeUpgraded) + printf("%s package(s) can be upgraded", #listNeedUpgrade()) end local function printHelp() @@ -499,11 +565,14 @@ elseif (mode == "info") then printf("Repo : %s", repoName) os.exit(0) elseif (mode == "install") then - install(args) - for _, p in pairs(args) do - markManual(p) + if (install(args)) then + for _, p in pairs(args) do + markManual(p) + end + os.exit(0) + else + os.exit(1) end - os.exit(0) elseif (mode == "uninstall") then uninstall(args) elseif (mode == "autoremove") then @@ -525,7 +594,6 @@ elseif (mode == "autoremove") then end markManual(args[1]) elseif (mode == "upgrade") then - local installed = pm.getInstalled(false) local toUpgrade = {} if (args[1]) then if (pm.isInstalled(args[1])) then @@ -539,20 +607,11 @@ elseif (mode == "upgrade") then end end else - --TODO : pkg not installed + printf("Package %s is not installed") + os.exit(1) end else - for pkg, manifest in pairs(installed) do - if (manifest.version == "oppm") then - printf("Found oppm version for %q.", pkg) - table.insert(toUpgrade, pkg) - else - local remoteManifest = getCachedPackageManifest(pkg) - if (remoteManifest and (remoteManifest.version == "oppm" or compareVersion(remoteManifest.version, manifest.version))) then - table.insert(toUpgrade, pkg) - end - end - end + toUpgrade = listNeedUpgrade() end install(toUpgrade, false) elseif (mode == "sources") then diff --git a/pm_get/pm_get.manifest b/pm_get/pm_get.manifest index 413fe44..7c314c8 100644 --- a/pm_get/pm_get.manifest +++ b/pm_get/pm_get.manifest @@ -1,7 +1,7 @@ { ["manifestVersion"] = "1.0", ["package"] = "pm_get", - ["version"] = "1.4.5", + ["version"] = "1.5.0", ["name"] = "pm get", ["repo"] = "tree/master/pm_get", ["description"] = "Download and install package for pm", diff --git a/programs.cfg b/programs.cfg index cf1d4ff..4b5bdf2 100644 --- a/programs.cfg +++ b/programs.cfg @@ -21,7 +21,7 @@ } }, ["pm_get"] = { - version = "1.4.5", + version = "1.5.0", name = "pm get", repo = "tree/master/pm_get", description = "Download and install package for pm",