diff options
author | Adam Harrison <adamdharrison@gmail.com> | 2023-06-06 18:43:51 -0400 |
---|---|---|
committer | Adam Harrison <adamdharrison@gmail.com> | 2023-06-13 10:05:46 -0400 |
commit | 1c6bdc93b78981276534126ec91cabefaf88b9d1 (patch) | |
tree | bae8ecfdfe767c6c0e193fd6dd0b941ee08c3492 | |
parent | a08efc6ccd234b69022127e8245b905f734ca5f1 (diff) | |
download | lite-xl-plugin-manager-1c6bdc93b78981276534126ec91cabefaf88b9d1.tar.gz lite-xl-plugin-manager-1c6bdc93b78981276534126ec91cabefaf88b9d1.zip |
Continuing the thing.add-in-orphan-dependency-clean
-rw-r--r-- | src/lpm.lua | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/lpm.lua b/src/lpm.lua index cfcf0eb..9863595 100644 --- a/src/lpm.lua +++ b/src/lpm.lua @@ -366,7 +366,7 @@ function common.each(l, p) for i, v in ipairs(l) do p(v) end end function common.flat_map(l, p) local t = {} for i, v in ipairs(l) do local r = p(v) for k, w in ipairs(r) do table.insert(t, w) end end return t end function common.concat(t1, t2) local t = {} for i, v in ipairs(t1) do table.insert(t, v) end for i, v in ipairs(t2) do table.insert(t, v) end return t end function common.grep(l, p) local t = {} for i, v in ipairs(l) do if p(v) then table.insert(t, v) end end return t end -function common.first(l, p) for i, v in ipairs(l) do if p(v) then return v end end end +function common.first(l, p) for i, v in ipairs(l) do if (type(p) == 'function' and p(v)) or p == v then return v end end end function common.slice(t, i, l) local n = {} for j = i, l ~= nil and (i - l) or #t do table.insert(n, t[j]) end return n end function common.join(j, l) local s = "" for i, v in ipairs(l) do if i > 1 then s = s .. j .. v else s = v end end return s end function common.sort(t, f) table.sort(t, f) return t end @@ -871,13 +871,17 @@ function Addon:depends_on(addon) end +function Addon:is_explicitly_installed(bottle) + return common.first(settings.installed, function(id) return self.id == id end) +end + function Addon:get_orphaned_dependencies(bottle) local t = {} local installed_addons = system_bottle:installed_addons() for id, options in pairs(self.dependencies) do local dependency = bottle:get_addon(id, options.version) - if dependency and dependency:is_installed(bottle) and not common.first(settings.installed, function(id) return dependency.id == id end) and #common.grep(installed_addons, function(addon) return addon ~= self and addon:depends_on(dependency) end) == 0 then + if dependency and dependency:is_installed(bottle) and not dependency:is_explicitly_installed(bottle) and #common.grep(installed_addons, function(addon) return addon ~= self and addon:depends_on(dependency) end) == 0 then table.insert(t, dependency) end end @@ -888,7 +892,7 @@ end function Addon:uninstall(bottle, uninstalling) local install_path = self:get_install_path(bottle) if self:is_core(bottle) then error("can't uninstall " .. self.id .. "; is a core addon") end - local orphans = common.sort(self:get_orphaned_dependencies(bottle), function(a, b) return a.id < b.id end) + local orphans = common.sort(common.grep(self:get_orphaned_dependencies(bottle), function(e) return not uninstalling or not uninstalling[e.id] end), function(a, b) return a.id < b.id end) -- debate about this being a full abort, vs. just not uninstalling the orphans; settled in favour of full abort. can be revisited. if #orphans > 0 and not uninstalling and not prompt("Uninstalling " .. self.id .. " will uninstall the following orphans: " .. common.join(", ", common.map(orphans, function(e) return e.id end)).. ". Do you want to continue?") then return false @@ -896,9 +900,17 @@ function Addon:uninstall(bottle, uninstalling) common.each(orphans, function(e) e:uninstall(bottle, common.merge(uninstalling or {}, { [self.id] = true })) end) log_action("Uninstalling " .. self.type .. " located at " .. install_path) local incompatible_addons = common.grep(bottle:installed_addons(), function(p) return p:depends_on(self) and (not uninstalling or not uninstalling[p.id]) end) - if #incompatible_addons == 0 or (installing or prompt(self.id .. " is depended upon by " .. common.join(", ", common.map(incompatible_addons, function(p) return p.id end)) .. ". Remove as well?")) then + local should_uninstall = #incompatible_addons == 0 or uninstalling + if not should_uninstall then + should_uninstall = prompt(self.id .. " is depended upon by " .. common.join(", ", common.map(incompatible_addons, function(p) return p.id end)) .. ". Remove as well?") + if not should_uninstall and self:is_explicitly_installed(bottle) and prompt(self.id .. " is explicitly installed. Mark as non-explicit?") then + settings.installed = common.grep(settings.installed, function(e) return e ~= self.id end) + return false + end + end + if should_uninstall then for i,addon in ipairs(incompatible_addons) do - if not addon:uninstall(bottle, uninstalling) then return false end + if not addon:uninstall(bottle, common.merge(uninstalling or {}, { [self.id] = true })) then return false end end common.rmrf(install_path) return true @@ -1611,6 +1623,7 @@ end local function lpm_install(type, ...) + local to_install = {} for i, identifier in ipairs({ ... }) do local s = identifier:find(":") local id, version = (s and identifier:sub(1, s-1) or identifier), (s and identifier:sub(s+1) or nil) @@ -1623,15 +1636,17 @@ local function lpm_install(type, ...) if #addons == 0 and #potential_addons == 0 then error("can't find " .. (type or "addon") .. " " .. id .. " mod-version: " .. (system_bottle.lite_xl.mod_version or 'any')) end if #addons == 0 then log_warning((potential_addons[1].type or "addon") .. " " .. id .. " already installed") + if not common.first(settings.installed, id) then table.insert(settings.installed, id) end else for j,v in ipairs(addons) do - table.insert(settings.installed, v.id) - v:install(system_bottle) + if not common.first(settings.installed, v.id) then table.insert(settings.installed, v.id) end + table.insert(to_install, v) end end end end lpm_settings_save() + common.each(to_install, function(e) e:install(system_bottle) end) end @@ -1642,7 +1657,6 @@ local function lpm_addon_uninstall(type, ...) local installed_addons = common.grep(addons, function(e) return e:is_installed(system_bottle) end) if #installed_addons == 0 then error("addon " .. id .. " not installed") end for i, addon in ipairs(installed_addons) do - settings.installed = common.grep(settings.installed, function(e) return e ~= addon.id end) addon:uninstall(system_bottle) end end |