-
Notifications
You must be signed in to change notification settings - Fork 35
XIM: Xlings Installation Manager Module - Base #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I don't recommend the layout of package index by name_version_maintainer.
-- example of vscode
local general = {
homepage = "https://code.visualstudio.com",
name = "vscode",
version = "1.9.3",
description = "Visual Studio Code",
contributor = "https://github.com/microsoft/vscode/graphs/contributors",
license = "MIT",
repo = "https://github.com/microsoft/vscode",
docs = "https://code.visualstudio.com/docs"
categories = {"editor", "tools"},
keywords = {"vscode", "cross-platform"},
}
local factors_versions = {
["1.9.3"] = {
version = "1.9.3",
support = {
windows = true,
ubuntu = true,
arch = false, -- TODO: add arch support
},
pmanager = {
windows = {
xpm = {
url = "https://vscode.download.prss.microsoft.com/dbazure/download/stable/38c31bc77e0dd6ae88a4e9cc93428cc27a56ba40/code_1.93.1-1726079302_amd64.deb",
sha256 = nil,
},
},
ubuntu = {
xpm = {
url = "https://vscode.download.prss.microsoft.com/dbazure/download/stable/38c31bc77e0dd6ae88a4e9cc93428cc27a56ba40/VSCodeUserSetup-x64-1.93.1.exe",
sha256 = nil,
},
},
arch = {
-- TODO: add arch support
},
},
}
-- This design will keep files layout flat.
-- If possible, actually we could delete `supported`, and `pmanager`. Directly route the keyword, if not exsit, return false. I check the implementation of index manager. In this design, we could read the files, and retrieve things important for index route. |
I currently check the xmake docs, here contains: winos module could be used for windows env management. |
core/xim/pkgindex/pkgs/v/vscode.lua
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the dir management, add file management preferring flat layout.
-- pkg
-- rust.lua
-- vscode.lua
etc...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in future, pkgindex
will be a repository about package index. so, use dir-style is easy to manage for package file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine, just to reduce repetition as much as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
local base = {
homepage = "https://code.visualstudio.com",
name = "vscode",
version = "1.9.3",
description = "Visual Studio Code",
contributor = "https://github.com/microsoft/vscode/graphs/contributors",
license = "MIT",
repo = "https://github.com/microsoft/vscode",
docs = "https://code.visualstudio.com/docs"
categories = {"editor", "tools"},
keywords = {"vscode", "cross-platform"},
}
-- general pattern would be, if there's no "factorsKey", only retain "versions":
-- "factorsKey" = {
-- “versions" = {}
-- }
local siblings = {
"versions" = {
["1.9.3"] = {
"windows" = {}
"linux" = {} ...
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
major version use different file to describe, then minor/patch version can place to one file because major version may be exist some break-change, it need to implement different hooks function to manage it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if you want, you could separate hooks and storage abstracting commons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General search pattern in env for windows:
function search()
if os.host == "windows" then
local env_path,err = winos.registry_query("HKEY_CURRENT_USER\\Environment;Path")
if env_path then
local paths = env_path:split(";")
for _, path in ipairs(paths) do
if path:lower():find("pattern") then
if (-- deeper check for assurance) then
end
end
end
end
end
core/xim/index/IndexManager.lua
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A possible design based on pixi (a package manager for rust,python...)
-- global setting
local global = {
envs = {
[env_name] = {
deps = {} -- contains installed packages
exposed = {} -- contains executable_path(setting the path so it's executable)
}
}
}
Still dubious to the impl of index store.
-- No need for install
bool field, just store installed deps.
-- A possible lock hash for lazy evaluated.
-- A general parser for TOML (or others rather than raw Lua file.) enhancing readability.
-- possible design: index → lock → path env management.
filename-format: name_maintainer.lua XPackage Spec--- XPackage Spec
package = {
-- base info
homepage = "https://example.com",
name = "package-name",
version = "1.0.0", -- default version
description = "Package description",
author = "Author Name",
maintainer = "Maintainer Name",
contributor = "Contributor Name",
license = "MIT",
repo = "https://example.com/repo",
docs = "https://example.com/docs",
-- xim pkg info
status = "stable", -- dev, stable, deprecated
categories = {"category1", "category2"},
keywords = {"keyword1", "keyword2"},
date = "2020-01-01",
-- env info - todo (only label, impl in vm module)
xvm_type = "", -- unused
xvm_support = false, -- unused
deps = {
windows = { "xpkgname1", "xpkgname2" },
ubuntu = { "xpkgname3", "xpkgname2@1.0.1" },
arch = { "xpkgname4", "xpkgname2" },
},
pmanager = {
["1.0.0"] = {
windows = {
xpm = { url = "https://example.com/package-1.0.0.exe", sha256 = "xxxx" }
},
ubuntu = { apt = "apt-package-name" },
arch = { pacman = "pacman-package-name" },
},
["1.0.1"] = {
windows = {
xpm = { url = "https://example.com/package-1.0.1.exe", sha256 = "xxxx" }
},
ubuntu = { apt = "apt-package-name"},
arch = { pacman = "pacman-package-name"},
},
},
}
-- xim: hooks for package manager
inherit("xim.base.runtime")
-- step 1: support check - package attribute
-- step 2: installed check
function installed()
return true
end
-- step 2.5: download resources/package
-- step 3: process dependencies - package attribute
-- step 4: build package
function build()
return true
end
-- step 5: install package
function install()
return true
end
-- step 6: configure package
function config()
-- if exist different
if runtime.pkginfo.version == "1.0.1" then
.....
return true
end
-- step 7: uninstall package
function uninstall()
return true
end
|
I personally think that although using install_method like may be complicated, the description is accurate and can also be considered pmanager = {
pacman = { -- install method name
manager = "pacman",
version = "1.0.0",
deps = { "xpkgname1" },
package = "pacman-package-name"
},
exe = {
-- match if has manager, match deps and version(if not nil)
manager = "xpm-executor",
version = "1.0.0", -- Specify the default version by matching order
deps = { "windows", "x86_64", "xpkgname1", "xpkggname2" },
-- install options
default_path = "C:\\Program Files\\xxx", -- enable path choose
no_confirm = "--quite", -- If the user does not specify silent installation, then empty is passed below
installed = function() return true end, -- TODO Didn't figure out how to do it
xpm = {
url = "https://example.com/package-%version%.exe", -- %version% will be replaced
-- https://example.com/package-1.0.0.exe
sha256 = "xxx",
install = "%source% %no_confirm% --path \"%install_path%\"", -- package-1.0.0.exe --quite --path "C:\Program Files\xxx"
uninstall = "%install_path%\\uninstall.exe %no_confirm%" -- C:\Program Files\xxx\uninstall.exe --quite
}
},
exe_1_0_1 = {
inherit = "exe", -- inherit from other install method
-- modify
version = "1.0.1",
deps = { "windows", "x86_64", xpkgname1 = ">=2" }, -- This is the full coverage (delete xpkggname2)
xpm = { -- partially coverage
-- url = "https://example.com/package-%version%.exe", -- %version% will be replaced
-- https://example.com/package-1.0.1.exe
-- no need to change
sha256 = "abc" -- The url parameter does not change, but due to the change of %version%, the actual file and sha256 will also change
}
} I don't know if the installation status and version of pkg need to be stored. If so, the name of the installation method may be used instead of the version to store and query the content of 'uninstall' or call the corresponding 'manager' for uninstallation Or in this form exe = {
manager = "xpm-executor",
version = { "1.0.0", "1.0.1" },
deps = { "windows", "x86_64", "xpkgname1", "xpkggname2" },
-- install options
default_path = "C:\\Program Files\\xxx", -- enable path choose
no_confirm = "--quite", -- If the user does not specify silent installation, then empty is passed below
version_of = function() return "1.0.0" end, -- TODO Didn't figure out how to do it (nil for not installed...)
xpm = {
url = "https://example.com/package-%version%.exe",
sha256 = {
["1.0.0"] = "xxx",
["1.0.1"] = "abc"
}
}
} Then 'exe_1_0_1' can be deleted, but an additional 'version' information needs to be stored after installation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer the local project style.(rather virtual envs.)
Storing env metadata in project location (mimic to pixi
).
{
"manifest_path": "path to project env setting",
"environment_name": "...",
"xlings_version": "...",
"environment_lock_file_hash": "..."
}
use lock_file_hash to avoid entire copy with lazy evaluated(update when hash isn't equal).
-- local project locked file.
env = {
deps = {...} -- store packages.
}
-- local project setting file.
project = {
authors = "...",
description = "...",
name = "...",
...
}
-- further discuss the role of xlings in design.(in which extent of role should xlings take over?)
-- should we make local installation? (not recommend) prefer a local path modification.(open a new transient shell or `xlings run (certain cmd)` (for example: xlings run cargo run).)
-- prefer a general parser for toml.(or others rather than raw lua file.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in future, this feature will be implement in vm(version manager) module. now xim module focus on installation manager.
core/xim/index/IndexStore.lua
Outdated
|
||
name_maintainer[2] = name_maintainer[2] or "x" | ||
|
||
for version, _ in pairs(pkg.pmanager) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The expansion of pmanager may not version. (may a factorKey
, such as vendors... then versions
as sub-table.)
core/xim/index/IndexStore.lua
Outdated
local triple = string.split(name, "_") -- name_version_maintainer | ||
if triple[2] then | ||
name = triple[1] .. "@" .. string.gsub(triple[2], "-", ".") | ||
local name_maintainer = string.split(name, "_") -- name_version_maintainer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange impl.
Why not directly extract info from package info rather file name?
Prefer file content rather file name dispatch. (encode info in file name is bad.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maintainer is optional in filename. encode maintainer to filename is because we need to distinguish thenm in package index repository.
example:
- openjdk_oracle
- openjdk_zulu
- openjdk_microsoft
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we encode such info to "factorKey"🤔? We only encode the factors that could affect the independence of a package. Like I suggest:
'''lua
-- "factorsKey" = {
-- “versions" = {}
-- }
'''
core/platform.lua
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest a full integration of platform.lua
and the OS part of utils.lua
.
core/common.lua
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest an integration of commons
, platform
, utils
...
-- Common(or Utils)
-- -- cmd ops.
-- -- internal state ops.
-- -- platform info.
-- -- etc...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in future, xim module may be decouple from xlings, then xlings as a tools sets to include (xinstall/xim, xrun, xvm, ...) --- just possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this. Beside those main functionalities in xlings, there's still code overlapped.
core/xim/pm/XPkgManager.lua
Outdated
if ok then | ||
local extension = path.extension(filename) | ||
local compressed = false | ||
for _, ext in ipairs({".zip", ".tar", ".gz", ".bz2", ".xz", ".7z"}) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In utils.lua
:
function is_compressed(ext):
local exts = {
['.zip'] = true,
['.tar'] = true,
['.gz'] = true,
['.bz2'] = true,
['.xz'] = true,
['.7z'] = true
}
return exts[ext] or false
end
local download_dir = runtime.get_xim_data_dir() | ||
local ok, filename = utils.try_download_and_check(url, download_dir, sha256) | ||
|
||
if not ok then -- retry download |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A possible retry logic in utils.lua
-- try_download_and_check to download_verify
local function download_retry(url, dir, sha256, retrys)
retrys = retrys or 3
for retry = 1, retrys do
local ok, filename = utils.download_verify(url,dir,sha256)
if ok then
return ok,filename
else cprint("...",retry)
end
end
return false,nil
end
core/xim/CmdProcessor.lua
Outdated
if self.cmds.yes ~= true then | ||
cprint("[xlings:xim]: ${bright}install %s? (y/n)", self.target.name) | ||
local confirm = io.read() | ||
if confirm ~= "y" then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add prompt logic in utils.lua
local function prompt(message,cond,exit)
exit = exit or "exit"
cprint(message)
while true do
local input = io.read()
if input == nil then
cprint("\nInterrupted by user (Ctrl+C). Exiting...")
return nil,false
end
if input == exit then
cprint("Exiting...")
return nil,false
end
if cond(input) then
return input,true
else
cprint("Invalid input. Please try again.")
end
end
end
@MoYingJi use install method is because attribute description is hard to design a unified standard. example xpm = {
url = "https://example.com/package-%version%.exe", -- %version% will be replaced
-- https://example.com/package-1.0.0.exe
sha256 = "xxx",
install = "%source% %no_confirm% --path \"%install_path%\"", -- package-1.0.0.exe --quite --path "C:\Program Files\xxx"
uninstall = "%install_path%\\uninstall.exe %no_confirm%" -- C:\Program Files\xxx\uninstall.exe --quite
} on windows, maybe software's installer is format of 'xxx.exe', but many software's install procedure is combination of commands.
i think it should implement by package-file's writer for installation details, so hooks/function have most freedom. |
package = {
-- ...
xpm = {
windows = {
deps = {"dep1", "dep2"},
["1.0.1"] = {"url", "sha256"},
["1.0.0"] = {"url", "sha256"},
},
ubuntu = {
deps = {"dep3", "dep4"},
["1.0.1"] = {"url", "sha256"},
["1.0.0"] = {"url", "sha256"},
},
},
pm_wrapper = {
pacman = "xxxx", -- arch
},
} |
@@ -9,8 +9,8 @@ local os_info = utils.os_info() | |||
function new(pkg) | |||
local instance = {} | |||
debug.setmetatable(instance, XPackage) | |||
instance.pdata = pkg.data.package | |||
instance.version = pkg.version | |||
instance.version, instance.pdata = _dereference(pkg.version, pkg.data.package) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If version is a factor affecting independence, so for others. It's a coarse separation here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest an improvement of XPackage
:
Here, design an input list to restrict a sibling of a package. Rather directly segregate version and package body.
We could transport PMService
functionalities to XPackage
itself. There's no need of a factory pattern here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suppose args list as a restriction to find a sibling (we give the freedom of choosing version, vendors...etc for a package).
-- args is a predefined config.
function new(args,pkg)
args = args or default
-- same...
-- search loigc by args
ins.data = search_data
-- possible other thing.
-- caveat: we shouldn't bind accessory such as _map_pkgname etc... if it's happened, there must be a functionality separated from what it should contains.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Transport the logic of PMService
:
function XPackage:executor(...)
-- impl logic
end
core/xim/pm/XPackage.lua
Outdated
function XPackage:get_pm_wrapper() | ||
-- self.version is package manager name when use local package manager | ||
return self.version | ||
end | ||
|
||
function XPackage:get_map_pkgname() | ||
return self.pdata.pm_wrapper[self.version] | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not well-defined here. Either a design slip or a impl slip.
XPackage
should directly detect current OS local package manager, there's no need to do that in PMService
, after initiation of XPackage
, it should assign its own package manager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
XPackage is only a object for package file and provide some getter/setter. it is also a constraint (XPackage Spec)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
XPackage
is runtime object, so if you just do that, why we just read the file and extract essential thing🤔? The runtime initiation isn't necessary. And Service
itself just a middleware, there's no need to create an instance for doing that. The package file should be what you said in pkgindex
, XPackage
could be an initiation of a certain sibling, to maintain the independence.
core/xim/pm/XPackage.lua
Outdated
local pm = self.pdata.pmanager | ||
if pm[self.version][os_info.name] then | ||
return true | ||
function XPackage:xpm_enable() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A suggestion of designation: verb-noun(has_xpm) for consistency.
Other get_noun
can be designated as noun itself.
pacman wrapper impl
- #41 1. input params 2. cmd process 3. update pkg manager Signed-off-by: sunrisepeak <speakshen@163.com>
1. add input args -> cmd_args 2. adjust xinstall interface -> xim's interface 3. update install script 4. add readme for package index repo Signed-off-by: sunrisepeak <speakshen@163.com>
1.install test 2.xim test Signed-off-by: sunrisepeak <speakshen@163.com>
core/xim/index/IndexStore.lua
Outdated
if version == "latest" then | ||
print(name_maintainer) | ||
index[name_maintainer] = { | ||
ref = key | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if not pkg.xpm or not pkg.xpm[os_info.name] then
local local_pm = utils.local_package_manager()
if not pkg.pm_wrapper or not pkg.pm_wrapper[local_pm] then
cprint("[xlings:xim]: ${yellow}package file error: %s", file)
return
end
local index_key = string.format("%s@%s", name_maintainer, local_pm)
index[name_maintainer] = { ref = index_key }
index[index_key] = {
version = local_pm,
installed = false,
path = file
}
return
end
local os_key = pkg.xpm[os_info.name].ref or os_info.name
for version, _ in pairs(pkg.xpm[os_key]) do
if version == "deps" then continue end
local key = string.format("%s@%s", name_maintainer, version)
if pkg.xpm[os_key][version].ref then
index[key] = {
ref = name_maintainer .. "@" .. pkg.xpm[os_key][version].ref
}
else
index[key] = {
version = version,
installed = false,
path = file
}
end
if version == "latest" then
index[name_maintainer] = {
ref = key
}
end
end
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the separation of local package manager and xpm gradually reform the index store. The difficulty of manage package independence will be potent. Actually, the practical problem will occur in further development, I guess...messy.
@@ -42,8 +43,18 @@ end | |||
-- xmake l xim.lua vscode -i | |||
-- xmake l xim.lua -r vscode -y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not recommend a random order in params input, sometimes in nested structure, it has semantic vagueness.
core/xim/xim.lua
Outdated
function _input_params_process(target, ...) | ||
local args = {...} | ||
function _input_params_process(target, args) | ||
|
||
if target:sub(1, 1) == '-' then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function _input_params_process(target, ...)
local args = {...}
if target:sub(1, 1) == '-' then
local original_target = target
for i, arg in ipairs(args) do
if arg:sub(1, 1) ~= '-' then
target = arg
table.remove(args, i)
table.insert(args, 1, original_target)
break
end
end
end
return target, args
end
1.add repo manager 2.seprate pm-wrapper and xmp 3.create a package index repo 4.update command format repo: https://github.com/d2learn/xim-pkgindex Signed-off-by: sunrisepeak <speakshen@163.com>
core/xim/CmdProcessor.lua
Outdated
if self.target and self.target ~= "" then | ||
if self.cmds.search then | ||
cprint("[xlings:xim]: search for *${green}%s${clear}* ...\n", self._target) | ||
cprint("[xlings:xim]: search for *${green}%s${clear}* ...\n", self.target) | ||
self:search() | ||
else | ||
local pkg = index_manager:load_package(self._target) | ||
local pkg = index_manager:load_package(self.target) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if self.target and self.target ~= "" then
target_cmds()
else
non_target_cmds()
end
-- target_cmds
if self.cmds.search then
cprint("[xlings:xim]: search for *${green}%s${clear}* ...\n", self.target)
self:search()
return
end
if not pkg then
cprint("[xlings:xim]: ${red}package not found - %s${clear}\n", self.target)
cprint("\t${yellow}Did you mean one of these?\n")
self:search()
cprint("[xlings:xim]: ${yellow}please check the name and try again${clear}")
return
end
self.pm_executor = pm_service:create_pm_executor(pkg)
if self.cmds.remove then
self:remove()
elseif self.cmds.update then
self:update()
else
self:install()
_feedback()
end
-- non_target_cmds
if self.cmds.list then
self:list()
elseif self.cmds.detect then
cprint("[xlings:xim]: start detect local packages...")
self:detect()
else
self:help()
end
core/xim/CmdProcessor.lua
Outdated
if not disable_info then self._pm_executor:info(xpkg) end | ||
|
||
if is_installed then | ||
cprint("[xlings:xim]: already installed - ${green bright}%s${clear}", self.target.name) | ||
index_manager.status_changed_pkg[self._target] = {installed = true} | ||
cprint("[xlings:xim]: already installed - ${green bright}%s${clear}", self.target) | ||
index_manager.status_changed_pkg[self.target] = {installed = true} | ||
else | ||
-- please input y or n | ||
if self.cmds.yes ~= true then | ||
local msg = string.format("${bright}install %s? (y/n)", self.target.name) | ||
local msg = string.format("${bright}install %s? (y/n)", self.target) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if not self._pm_executor:support() then
cprint("[xlings:xim]: ${red}<%s>-platform not support${clear} - ${green}%s${clear}", os.host(), self.target)
return
end
local xpkg = self.target
local is_installed = self._pm_executor:installed(xpkg)
if not disabled_info then
...
end
if is_installed then
print(...)
end
if not (--prompt logic, your prompt design is bad, because you still need to check cond outside your function,that do nothing) then
return
end
-- deps logic
-- install-failure logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's same problem about remove
logic, you could refactor that.
1. xim-pkgindex -> pkgindex 2. add pkgindex mirror repo to RepoManager 3. add syscmds --update [index | self] mirror-repo: https://gitee.com/sunrisepeak/xim-pkgindex Signed-off-by: sunrisepeak <speakshen@163.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
base
Package Index
xim-pkgindex: https://github.com/d2learn/xim-pkgindex
Command