Closed IzzySoft closed 1 year ago
I'm not sure if these fields will be useful, I also found that some fields are redundant when refactoring MRepo. When my repo
becomes very complicated, and the established repos
are very different from it, then I have to reconsider their compatibility issues, which will affect my refactoring of MRepo. There are indeed many problems😶🌫️, you can wait to build your repo. I'm currently working on refactoring MRepo, Sync
will not be adjusted until then.
I'm not sure if these fields will be useful,
They were just a suggestion (taken from what I'm used to from F-Droid, plus the counter). If "unknown fields" are simply ignored, that's also OK – I could then place "added" and my personal comments where needed. My main concern was modularity – as with 50+ modules in the repo it becomes harder to handle (my current list already has 14 entries).
then I have to reconsider their compatibility issues
If that's meant to say that the current format is understood by the other clients already (and no separate JSON is needed) I'd agree. But as far as I understood, that's not the case. Apart from that, I didn't mean these additional fields must end up in modules.json
: with per-module-json there'd be no need to touch modules.json
manually, so edits would happen to the per-module JSON – and what ends up in modules.json
is a completely different thing. It could include these additional fields (if unknown fields are ignored by clients) or not.
you can wait to build your repo. I'm currently working on refactoring MRepo, Sync will not be adjusted until then.
Thanks! Waiting for your signal then.
Adding new fields or new JSON will not affect MRepo, I use Retrofit for JSON data requests, it is very powerful and I can not parse fields that are not currently needed. After the MRepo refactoring is completed, this part will be newly processed, and the UI and logic have been modified a lot, which took a lot of time, coming soon🤪
I plan to add a tracks.json
in json/
, the data structure will take the example you gave.
This should not be user facing, this should be useful to repo owners and developers.
As you give the name tracks.json
it looks like a single file. Just to make sure: I meant a single JSON file per module listed in the repo. So if my repo hosts 50 Magisk modules there'd be 50 JSON files, each "tracking" one of the Magisk modules.
Do we both mean the same?
One trace.json per module? , just like update.json. My thought is to have only one tracks.json like modules.json, but one per module seems better.
one per module seems better.
Yupp, easier to maintain I'd say (running my own F-Droid repo with 1k+ apps, and being a maintainer of F-Droid.org with more than 4k apps, where apps are dealt with that way, I guess I can tell :smile:) Glad you like the idea!
May I ask where we stand? I just noticed 2 updates to the app itself, which looks like you made a lot of progress. Looking forward to your "ping" telling me it's time to start with my own modules repo :smiley:
In the past, I have been working on improving MRepo. Now, I will start this part next, and I believe we will see it in the next version😋.
Cool! Eagerly looking forward to that. And yes, first things first – modularization here won't change the "interface" anymore, it's "just" making back-end processing easier :smiley:
PS: My queue of modules is steadily growing. Currently 17 and counting (only those with update.json
– before approaching those without I wanted to have everything else up and running). Thanks for sticking to it!
I see you closed this issue as "completed". Some questions left after looking at the Readme:
templates/
(and I don't know what model you finally decided for – e.g. where the per-module JSON files are expected). Also, some setup instructions would be nice: should one just work from within the cloned repo? Or have the repo inside util/
, and call cli.py
from the parent directory?requirements.txt
list pygithub
as dependencies. Is this also needed if I do not host my repo at Github (but use rsync
)? Seems like without that module, cli.py
is unable to work as it's imported unconditionally. Wouldn't be that useful to install a dependency one does not need :wink: (and I do certainly not want to rely on Github for my repo, which I host myself; so if that's a "hard dependency", I'm sadly out) If it's instead intended to fetch the modules from their resp. repos: not all of them are hosted on Github, there are also other forges (like Codeberg, GitLab, SourceHut etc).main
?PS: I very much hope the pygithub
dependency is not needed (and there's a way to get the repo-util running without it), as that would be a deal-breaker for me otherwise. Not only is pygithub
itself 4 MB, but also has a lot of additional dependencies (so I'm probably ending up with 10 MB dependencies I don't want).
I'm quite "down" at the moment: when I found your project it looked like a nice and simple way to get a Magisk Module repo running, I was so enthusiastic. Now it grew so complex with its dependencies that it makes no longer sense for me. I cannot go with a previous incarnation either, as then there'd be no compatible Android client, which would make my repo useless. :cry:
{
"id": "zygisk_lsposed",
"update_to": "https://lsposed.github.io/LSPosed/release/zygisk.json",
"license": "GPL-3.0",
"added": 1679025505.129431,
"last_update": 1679025505.129431,
"versions": 1
}
Ah, thanks @ya0211 – so there's still hope! I was quite frustrated yesterday thinking all my hopes need to be abandoned…
I haven't updated the README yet.
That explains why I missed the pointers. Some short hints on first-time setup would be really great.
At present, pygithub is only used when I create a mirror of the repo on GitHub. It is really useless for the sync of the traditional mode (hosts.json).
That confirms my guesses, to my relief :smiling_face_with_tear:
I will find a way to reduce their coupling.
That'd be really great! Maybe only importing it when the config points out it's needed – i.e. repo_branch
is set and sync_mode
is git
) – so of someone doesn't use Github for this would not need to have the pygithub
module installed? And can you let me know when that's possible, so I check again?
util does exist git log rewrite and force push.
Yes. Utils do exist to :bomb: and :fire:, too – but that does not mean one should use them lightly (oops). Especially it's strongly recommended to NOT use rewrite for something already published (pushed) and thus might be forked/cloned by others. There are rare cases where it's needed, e.g. if credentials were accidentally published and the corresponding commits must be removed. Such a rewrite breaks all forks and clones, including their branches – they won't be able to pull your changes anymore, but would need to do a "fresh start" and re-apply all the changes they've made, including lots of manual work with diff/patch as a rebase won't be possible.
PS: Shouldn't the timestamp
(from update.json
) also be part of modules.json
as well? Or how does the MRepo client obtain those details to present them to the user (to see when the module itself was last updated/released)? Where does the corresponding date shown in "versions" come from? I don't see that in modules.json
. E.g. the 2023-02-22
here:
If it's not in modules.json
it probably needs an extra request to retrieve it from the update.json
of the corresponding module – which again requires a network connection when browsing a repo. Having all the version details in modules.json
would make that unnecessary (as with F-Droid, just the index – here modules.json
– would be needed to kept up-to-date on-device, and all details were there). Just wondering.
Further, when setting up a new module, would it now suffice to create the corresponding directory and place the corresponding track.json
there, so it would be picked up then? But maybe I should wait for your update to the Readme before asking all the details :wink:
hosts.json
was moved to config
, which I think serves its purposepygithub
is no longer required to be installed, it is optionalrepo_branch
and sync_mode
are no longer needed in config.json
, and the git push will be done by cli.py -p
(the branch used will be read by itself or defined by the user), and other push methods will be done by the user (after cli.py
finishes syncing)2023-02-22
comes from the timestamp in update.json
. I don’t think this part should exist in modules.json
. If the user views the module, he may want to install or update the module or view the changelog, the network connection is alway necessarytrack.json
and update.json
are located in the same directory, more information can be found in README.mdI made some changes and updated REMAD.md
Thanks! Yes, a good help to getting started. A few notes, though:
cli.py --new-config
: "repo_url need to end with /" => this is not checked. If I specify https://example.com/repo
it's taken as-is without a trailing slash.cli.py --add-module
: "continue -> [y/n]" is a bit misleading, should be "add another module -> [y/n]" (I initially hit "yes" as I expected it to write the file then)cli.py -u <username> --no-sync
:
cli.py [-u {username}] --no-sync
instead?-u
it complains about a missing Github tokenjson/modules.json
modules.json
crashes with KeyError: 'modules'
modules
section manually (with the module inside) solves this – but somehow defeats the purpose of running --add-module
to add the first new moduleupdate.json
at e.g. Github. I just wondered why adding a second module I ran into the same issue. I again created the corresponding module manually then. Tried that 3 times now, always ending up with the log message WARNING: clear removed modules: <module_name>
(I had created parts of that, too, as a copy from a former version – see below) so had to do all the work over and again; it should not remove modules automatically without confirmation, if needed it should simply ignore them with a warning message. The log message ERROR: unlimited-hotspot: update module failed: JSONDecodeError(Expecting value: line 8 column 1 (char 7))
was not that helpful if I cannot even tell which of the files it refers to :see_no_evil: (mentioning that would have brought me on the right track much sooner))rsync
instead of Github)?Next I checked if I can add a new module by simply creating its directory and placing a corresponding track.json
inside (this was the idea behind the "one JSON per module") – but that doesn't seem to work: all I get then is a WARNING: clear removed modules: <module_name>
. So it seems everything in modules/
shall not be touched manually, but one needs to edit hosts.json
? Idea was to easily add a module by creating the directory and dropping in its JSON (and remove it the very same way). Else with a lot of modules, maintenance becomes error-prone (the input of --add-module
is hard to automate, dropping in a JSON is easy – and there is not even a --remove-module
).
So why not instead of having an additional hosts.json
, partly duplicating the content of the track.json
but having no additional details) simply use the track.json
files for this? Would make maintenance much easier :smiley:
hosts.json
was moved toconfig
, which I think serves its purpose
Is hosts.json
really needed at all (see above)? Feels somehow redundant. Its contents can easily be produced by parsing the corresponding files from within the modules/
directory.
pygithub
is no longer required to be installed, it is optional
Yes, I can confirm it is not missed :partying_face: Thanks a lot!
repo_branch
andsync_mode
are no longer needed inconfig.json
, and the git push will be done bycli.py -p
(the branch used will be read by itself or defined by the user), and other push methods will be done by the user (aftercli.py
finishes syncing)
Great! Makes the config look much clearer. Only few users will need multiple branches I guess, if at all.
2023-02-22
comes from the timestamp inupdate.json
. I don’t think this part should exist inmodules.json
. If the user views the module, he may want to install or update the module or view the changelog, the network connection is alway necessary
If that's your intention, I'll accept that. But I do not fully agree. You know I run a big F-Droid repo (with more than 1.000 apps) and am also one of the maintainers at F-Droid.org (where the repo houses more than 4.000 apps). We keep all those data in our JSON index (except for the binaries like graphic files or the APKs themselves). The required files (here: changelogs, Readmes) are fetched from their sources at build time and directly integrated. So users can browse the repo without any network connection required (very helpful in several situations – one example a "boring train journey" with no network available, where one can use the time to browse through available modules and read their descriptions), just graphics would be missing then.
Well, but that can also be something for later (if you want me to, I can move that topic to a separate issue to ponder on).
Currently
track.json
andupdate.json
are located in the same directory, more information can be found in README.md
That's totally fine! Everything belonging to a specific module can be found in one place. So if I want to remove a module for some reason, I could simply remove that directory (in my original idea; not working currently as hosts.json
is used for control – which is why I asked above to "obsolete" that; again something that can be moved to its own issue if you want).
Summing up: a big thanks for all your work, @ya0211 – looks like I'm soon ready to start with my repo. Just need to know which files to sync. Am I assuming correctly that just the json/
and modules/
directories would suffice? MRepo most likely just fetches the modules.json
and what's linked from there, right?
cli.py --new-config
: I'd add a check for the repo_url (although I think that, having read the following carefully, this error should not appear🤨, but just in case)cli.py --add-module
: Indeed, it's ambiguous, I'll fix itcli.py -u <username> --no-sync
: In fact, my intention is that as one of the three ways to generate hosts.json, I will improve the README.mdcrashes as it cannot find json/modules.json
: I think it came from Repo.py#L38 and I'll fix itWARNING: clear removed modules: <module_name>
: When you use debug mode(cli.py --debug
), it will no longer be a warning, it will directly throw the errorcli.py --remove-module
: it will come with the next commithosts.json & track.json
: I think they can be merged into tracks.json
, we no longer need hosts.json and track.json of each module, and add --print-track
to cli.pymodules.json & update.json
: Regarding this issue, I think I have to consider that it will be related to the change of the client. But it is undeniable that the current method is a waste of the user's network, also increases the loading time of the page.Summing: @IzzySoft Thank you very much for your attention to this project and the suggestions you provided. This is an opportunity for me to learn Android development, and it has developed far beyond my imagination. Although I don't major in software engineering, but because of the experience of this project, I think I will soon enter this industry 🥳.
I'd add a check for the repo_url
Cool, thanks! Not a prio-1, but good to have (can avoid some confusion).
cli.py --add-module
: Indeed, it's ambiguous, I'll fix it
:+1: Great!
cli.py -u <username> --no-sync
: IIn fact, my intention is that as one of the three ways to generate hosts.json, I will improve the README.md
:smiley:
crashes as it cannot find json/modules.json
: I think it came from Repo.py#L38 and I'll fix it
Yepp, that sounds like it. If no module was added yet, there's nothing to load. So maybe simply create a new one if the file is not (yet) there.
WARNING: clear removed modules: <module_name>
: When you use debug mode(cli.py --debug), it will no longer be a warning, it will directly throw the error
Well, one usually only runs in debug mode when debugging. I was rather thinking along the lines of "throw a warning but do not automatically remove". Like WARNING: detected possibly removed module '<module_name>'. Run 'cli.py --remove-unused' to remove it.
(and have that command available). Else data might be lost due to some typo or whatever.
cli.py --remove-modul
: it will come with the next commit
Great! That piece was really missing :smile: Just take care for consistent spelling: it should be --remove-module
(with a trailing e
) :nerd_face:
hosts.json
&track.json
: I think they can be merged intotracks.json
, we no longer needhosts.json
andtrack.json
of each module, and add--print-track to cli.py
Wait, that might go the wrong way. Do you still have in mind one could manipulate existing modules by simply adding their directory or removing it? track.json
contains the details needed for that. So this file should exist per-module. So to add the module izzy_example
, I'd just do the following:
mkdir -p modules/izzy_example
cat > modules/izzy_example/track.json <<EOF
{
"id": "izzy_example",
"update_to": "https://izzy.example.com/update.json",
"license": "WTFPL"
}
EOF
util/cli.py
(though I'd rather replace the cat
by something like jo -p id=izzy_example update_to=https://izzy.example.com/update.json license=WTFPL
to make sure it's proper JSON) and the module would be added (who prefers --add-module
can still use that). And to remove it, all I had to do would be
rm -rf modules/izzy_example
util/cli.py
(though for that, --remove-module
would be fine, too). Plus I could easily adjust a single module without much risk to modify the wrong one e.g.
sed -i 's/"license": "WTFPL"/"license": "Unlicense"/' modules/izzy_example
That would make automated maintenance much easier! And also avoid adding "duplicate IDs" modifying modules.json
by hand as the inter-active --add-module
cannot be scripted easily :see_no_evil:
modules.json
&update.json
: Regarding this issue, I think I have to consider that it will be related to the change of the client. But it is undeniable that the current method is a waste of the user's network, also increases the loading time of the page.
Yes, exactly. But that's something that can be postponed if you prefer (though then for a while the client would need to support both formats; so the earlier this is decided, the less the impact).
Summing:
:rofl: Yeah. Glad to be of assistance – and even more glad to accept the challenge! I wouldn't have the time to implement all that – but I can (and do gladly) share from my experience running/maintaining larger repos.
track.json(s)
instead of hosts.json
cli.py
stripped to sync, config, github, and add some new commands$ util/cli.py
File "util/cli.py", line 238
match option:
^
SyntaxError: invalid syntax
Python 3.8.10 here. match
was only added with 3.10. And no, I currently cannot upgrade, as that would mean a ton of dependencies on the given machine (entire dist upgrade; there's a reason I'm using LTS :wink:) Maybe one of the alternatives can be used instead? As it's just 3 cases, I guess the "if .. elif` should be easiest
while True:
if option == 1:
print_header("Add Module")
option = add_module()
elif option == 2:
print_header("Remove Module")
option = remove_module()
elif option == 0:
print_header("Modules Manager")
print_value(1, "Add Module")
print_value(2, "Remove Module")
option = input_optional("Option", "[1/2/q]: ", [1, 2])
print()
Works so far then. But now I get some other errors on sync:
Sync ERROR: zygisk_lsposed: update module failed: TypeError(unsupported operand type(s) for *: 'NoneType' and 'float')
Well, "for *" is quite precise. Which asterisk should it be? That's for modules added with the previous version btw. I just added a new one, and the error looks different:
update module failed: JSONDecodeError(Expecting value: line 8 column 1 (char 7))
Tracking it down with debug (-d
), the pointer is
File "util/sync/Repo.py", line 246, in pull
Adding some more debug output I can pin it to versions_item = self._update_module(item, host)
failing. The passed arguments seem fine. Digging deeper with some more added debug print()
lines, I was able to nail that one – again my "good old" Gihub-link error (/blob/
URL instead of /raw/
). To make that easier to catch, it would help to have another check in _get_module_from_json
, or rather an exception handler. The failing command is:
update_json: AttrDict = load_json_url(host.update_to)
not resulting in JSON with /blob/
URLs. So it should be
update_json: AttrDict = load_json_url(host.update_to)
try:
downloader(update_json.zipUrl, tmp_file)
except ...
// log message: URL did not return valid JSON
or maybe catch that in load_json_url
?
Btw: on each call I see
fatal: not a git repository (or any parent up to mount point /)
Do you try syncing with git, despite no git repo is set up? Guess you didn't notice that as you're using git there :see_no_evil:
OK, I'll now check why the other two modules I added before were not working after the update to your newest commit.
Hm, here's the diff (diff -u new_track.json old_track.json
):
"changelog": "",
- "last_update": 1679527941.189307,
+ "added": 1679357931.571593,
+ "last_update": 1679357931.571593,
"versions": 1
so the old one had an additional field which you now dropped. But shouldn't that be ignored when interpreting the JSON object? Just checked: Removing that line, the errors are gone. Not sure how many people use the code already so it would be worth the effort to check and clean that as well?
But COOOL! This now works:
mkdir modules/systemless_debloater
jo -p -- id="systemless_debloater" update_to="https://github.com/Magisk-Modules-Alt-Repo/SystemlessDebloater/raw/main/update.json" license="LGPL-2.1-only" -s changelog="" > modules/systemless_debloater/track.json
util/cli.py sync
:partying_face:
As well as
rm -rf modules/systemless_debloater
util/cli.py sync
Wonderful! :star_struck:
match
: It has been changed to if
fatal: not a git repository (or any parent up to mount point /)
: It has been fixed and this error will no longer be promptedSync ERROR: zygisk_lsposed
: I need more info(track.json
) to locate the source of the errormkdir modules/systemless_debloater
jo -p -- id="systemless_debloater" update_to="https://github.com/Magisk-Modules-Alt-Repo/SystemlessDebloater/raw/main/update.json" license="LGPL-2.1-only" -s changelog="" > modules/systemless_debloater/track.json
util/cli.py sync
can be replaced by
util/cli.py config -a id="systemless_debloater" update_to="https://github.com/Magisk-Modules-Alt-Repo/SystemlessDebloater/raw/main/update.json" license="LGPL-2.1-only" changelog=""
also have 🥳
util/cli.py config -r systemless_debloater
"added": 1679357931.571593,
as seen in above diff :wink:config -a|-r
: yes, already found that when writing my shell auto-completion and investigating all --help
output and using it instead, thanks! :heart_eyes:Remains the update module failed: JSONDecodeError(Expecting value: line 8 column 1 (char 7))
when the server does not return valid JSON, where an exception handler is needed (I meanwhile recognize the error as what it is and immediately know what to do – new users probably won't).
I still don't understand this error about track.json
I can no longer reproduce as I didn't keep the old copies. So maybe let's drop this one (until someone else shows up with the same).
I noticed that there seems to be a gap between the bottom nav bar and the floating button 🤨
Indeed, now that you say it: I just checked whether it's just the screenshot, but no, it shows on-device as well. But still: nice to see my repo in there with 17 modules. Wll probably make it public soon™ – once I found some time for a little care on the web server end (at least having a basic browser front-end would be nice).
What device and Android version is this? There seems to be a issue with the UI when useing the virtual navigation bar.🤔
Wileyfox Swift running Android 10 (LineageOS).
Ok, I'll check this out.
With a growing repo it might be easier to keep track of modules if one could configure them in separate JSON files, one per repo, and named e.g. by their ID. Those files could just contain the basic info which is then "compiled" into
json/modules.json
. It would be great to also have some timestamps there, too, for maintenance purposes. Picking an example from the Readme here:modules/zygisk_lsposed.json
:The timestamps would allow to spot modules having received no updates "for ages" – and the
versions
(to be increased whenever a new version was fetched successfully) help identify very actively maintained ones. What "time format" to use (just the date as above, or datetime, or a Unix timestamp) might be worth thinking about, but IMHO date-as-above would suffice.As indicated, I'd suggest to place those per-module JSON into the
modules/
directory. Not sure if you'd see that as a conflict to the name of thejson/
directory name, but mixing them in there could become a bit confusing (and make parsing harder as you had to skip those two JSON files when scanning the per-module JSONs).PS: Please do not delete solved issues, just close them – they can be helpful in the future for references. I just wanted to look up something in our initial issue here (#1, "Refactor magisk-modules-repo-util") and found it was gone :cry: I wanted to look/ask there about the "current final state", especially concerning support for the format of "established repos" – to know if it makes sense to start on my repo already, or if I had to wait for MRepo being ready for the refactored format.