summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--notes.txt141
-rw-r--r--src/__main__.py3
-rw-r--r--src/options.py95
-rw-r--r--src/xi.py117
4 files changed, 271 insertions, 85 deletions
diff --git a/notes.txt b/notes.txt
new file mode 100644
index 0000000..962ba2b
--- /dev/null
+++ b/notes.txt
@@ -0,0 +1,141 @@
+/etc/xi/xipkg.conf
+ for xipkg config
+
+in config define repo sources like this:
+ <source name>: <url or filepath>
+
+eg:
+ davidovski: https://xi.davidovski.xyz/repo/
+
+
+then specify repos that should be loaded:
+ repos: core extra other
+
+/var/lib/xipkg
+ to contain all working files:
+
+/var/lib/xipkg/packages
+ "working dir" to keep xipkg files and xipkg.info
+ will look something like this:
+ packages/
+ core/
+ extra/
+
+
+/var/lib/xipkg/keychain
+place to store publickeys for sources.
+
+/var/lib/xipkg/installed/<pkg name>
+ /info - info about the package that has been installed to the system
+ /files - text file with all the files that it installed to the sysetm (for later removal purposes)
+
+
+sync
+-------
+download all xipkg.info and keys from repos, done before all other commands
+
+just go to each source
+and each repo
+one by one take each xipkg.info
+temporarily save each xipkg.info somewhere, per source
+
+find the latest xipkg.info and get the VER_HASH for that build
+find all of the xipkg.info with that VER_HASH and compare their checksums
+the most common CHECKSUM will win, so place that xipkg.info in the correct place
+
+? maybe make a warning about any sources that have outdated / different CHECKSUMS for that version hash (possibly malicious?)
+
+A database should be made:
+
+Packages:
+ [name (String), repo (String)]
+
+Sources:
+ [name (String)], url (String)
+
+PackageSources:
+ package (String), repo (String), source (String)
+
+This database should solve the problem of of which package infos come from which sources
+
+
+???
+File:
+ path (String), package (String), repo (String)
+???
+
+install
+-------
+
+if a xipkg file is specified and there is a corresponding .info as well, it will install it directly
+if its a url, then download the xipkg file and its .info
+
+if its a package name:
+ check if it exists,
+ if that package name exists in multiple repos, then prompt to ask which repo to take from
+
+to check a package is already installed, search for its name in /var/lib/xipkg/installed
+
+to install package need to:
+ - find the package in a place in /var/lib/xipkg/packages
+ - find all dependencies and subdependecies in a tree, and repeat install for any that are missing
+
+ - aquire .xipkg from correct source (look for the xipkg.info.source)
+
+ - verify that the hash of xipkg is right
+
+ - check against every publickey in /var/lib/xipkg/keychain (maybe better ideas?)
+
+ - untar the xipkg
+ - list all package's files in xipkg into /var/lib/xipkg/installed/<pkg name>/files
+ - copy the pkginfo to /var/lib/xipkg/installed/<pkg name>
+ ( do not use a symlink since later syncs can make the information inacurate)
+ - copy all the files into their place on the system
+ (actually install the package)
+
+ - make an install reciept that contains:
+ * the source that the package was downloaded from
+ * the key that was used to validate the package
+ * the date the package was installed
+ * the user that installed the package
+ * if the package was installed as a dependency
+ * other info?
+
+ - ?? run some post install scripts??
+ - ?? clean up??
+
+remove
+------
+
+find the package's installed files in /var/lib/xipkg/installed/<pkg name>/files and remove them from the system
+(? maybe check if other packages need them, and dont remove then?)
+
+remove all the info from /var/lib/xipkg/installed/<pkg name>
+
+(? check )
+
+upgrade
+-------
+do a sync
+if a package is specified, only upgrade that one package
+
+create a dependency tree and try upgrade core packages first (shouldnt matter really, since upgrading shouldnt have any dependencies other than xipkg and its subdependencies)
+
+to upgrade a package find that package in the repo and compare its pkginfo with the installed's package info
+
+if the VERSION_HASH is different then upgrade (guessing newer)
+if the CHECKSUM is different AND the date is newer then upgrade (a different checksum with an older date could be a mistake)
+
+(cant rely only on version hash, because the way that the package was built can be changed)
+
+
+force-upgrade
+------------
+(! needs a better name)
+
+just removes the package and then installs it again
+
+file
+------
+searches for a file to install
+(!!! REQUIRES SOME KIND OF FILE DATABASE)
diff --git a/src/__main__.py b/src/__main__.py
index d1abc56..43d8cb7 100644
--- a/src/__main__.py
+++ b/src/__main__.py
@@ -1,6 +1,5 @@
import xi
if __name__ == "__main__":
- pass
-
+ xi.main()
diff --git a/src/options.py b/src/options.py
new file mode 100644
index 0000000..9064369
--- /dev/null
+++ b/src/options.py
@@ -0,0 +1,95 @@
+import sys
+
+options = {
+ "h": {
+ "name": "help",
+ "flag" : True,
+ "desc" : "prints the command usage and exists the program",
+ }
+ "y" : {
+ "name" : "no-confirm",
+ "flag" : True,
+ "desc": "will not prompt the user"
+ },
+ "r" : {
+ "name" : "root",
+ "flag" : False,
+ "desc" : "specify the directory to use as the system root",
+ "default" : "/"
+ },
+ "l": {
+ "name" : "no-sync",
+ "flag" : True,
+ "desc" : "skip syncing with repo sources (not recommended)"
+ }
+ }
+
+def parse_args():
+
+ # re-organise the options by name rather than by single letter
+ # a dict with "name": option_leter
+ names = { v["name"] if v["name"] else k : k for k,v in options.items()}
+
+ args = sys.argv
+ index = 1
+
+ # save all of the options into a "parsed" dictionary
+ parsed = {"args" : []}
+
+ while index < len(args):
+ arg = args[index]
+
+ if len(arg) > 1 and arg[0] == "-":
+ option = None
+
+ # is a named argument with a --
+ if arg[1] == "-" and len(arg) > 2 and arg[2:].split("=")[0] in names:
+ option = names[arg[2:].split("=")[0]]
+ # is a single letter argument with a -
+ elif arg[1] in options:
+ option = arg[1]
+ else:
+ parsed["args"].append(arg)
+
+ # add the option and any values ot the parsed dict
+ if option is not None:
+ if options[option]["flag"]:
+ parsed[option] = True
+ else:
+ if "=" in arg:
+ parsed[option] = arg.split("=")[1]
+ else:
+ index += 1
+ parsed[option] = args[index]
+ else:
+ parsed["args"].append(arg)
+
+
+ index += 1
+
+ # add all default values to the parsed options
+ for option in options:
+ if not option in parsed:
+ if options[option]["flag"]:
+ parsed[option] = False
+ else:
+ parsed[option] = options[option]["default"]
+
+ return parsed
+
+def print_usage():
+ for option,o in options.items():
+ name = o["name"]
+ description = o["desc"]
+ d = ("[default=" + o["default"] + "]") if not o["flag"] else ""
+
+ print(f"\t-{option}, --{name}\t{d}")
+ print(f"\t\t{description}\n")
+
+ if "verbs" in globals():
+ print("Available actions:")
+ for verb in verbs:
+ print(f"\t{verb}")
+
+
+
diff --git a/src/xi.py b/src/xi.py
index 0711f0a..2449328 100644
--- a/src/xi.py
+++ b/src/xi.py
@@ -1,88 +1,39 @@
-import sys
+import options
-options = {
- "y" : {
- "name" : "no-confirm",
- "flag" : True,
- "desc": "will not prompt the user"
- },
- "r" : {
- "name" : "root",
- "flag" : False,
- "desc" : "specify the directory to use as the system root",
- "default" : "/"
- },
- "h": {
- "name": "help",
- "flag" : True,
- "desc" : "prints the command usage and exists the program",
- }
- }
-
-def parse_args():
-
- # re-organise the options by name rather than by single letter
- # a dict with "name": option_leter
- names = { v["name"] if v["name"] else k : k for k,v in options.items()}
-
- args = sys.argv
- index = 1
-
- # save all of the options into a "parsed" dictionary
- parsed = {"other" : []}
-
- while index < len(args):
- arg = args[index]
-
- if len(arg) > 1 and arg[0] == "-":
- option = None
+def search(terms):
+ print(f"searching for {terms}")
+ pass
- # is a named argument with a --
- if arg[1] == "-" and len(arg) > 2 and arg[2:].split("=")[0] in names:
- option = names[arg[2:].split("=")[0]]
- # is a single letter argument with a -
- elif arg[1] in options:
- option = arg[1]
- else:
- parsed["other"].append(arg)
+def install(terms):
+ print(f"installing for {terms}")
+ pass
- # add the option and any values ot the parsed dict
- if option is not None:
- if options[option]["flag"]:
- parsed[option] = True
- else:
- if "=" in arg:
- parsed[option] = arg.split("=")[1]
- else:
- index += 1
- parsed[option] = args[index]
- else:
- parsed["other"].append(arg)
-
+def remove(terms):
+ print(f"removing for {terms}")
+ pass
- index += 1
-
- # add all default values to the parsed options
- for option in options:
- if not option in parsed:
- if options[option]["flag"]:
- parsed[option] = False
- else:
- parsed[option] = options[option]["default"]
-
- return parsed
-
-def print_usage():
- for option,o in options.items():
- name = o["name"]
- description = o["desc"]
- d = ("[default=" + o["default"] + "]") if not o["flag"] else ""
-
- print(f"\t-{option}, --{name}\t{d}")
- print(f"\t\t{description}\n")
-
-
-opts = parse_args()
-if opts["h"]:
- print_usage()
+verbs = { v: globals()[v] for v in [
+ "search",
+ "install"
+ "remove"
+ ]
+ }
+def main():
+ opts = options.parse_args()
+ args = opts["args"]
+
+ if opts["h"]:
+ options.print_usage()
+ return
+
+ if len(args) > 0:
+ verb = args[0].lower()
+ (
+ verbs[verb] if verb in verbs else search
+ )(
+ args[1:] if len(args) > 1 else []
+ )
+ else:
+ options.print_usage()
+ return