Multitool - An implementation and feature discussion.

Thank you again. I do not multi-task well and am focused on writing a document for real life and a KoLmafia test but this is next on the list.
 
New version. I now attempt to ignore local files that don't match the expected name convention which is ToolName-version-M.jar or ToolName-version.jar. I need to look at your failure to launch report. Any chance the multitool log file has something? I may also have incorrectly detected how to run Java on your system. Thanks.
 
Yep, that's exactly the problem.


This is essentially backsliding from attempting to solve https://kolmafia.us/threads/multito...d-feature-discussion.30272/page-2#post-176348 -- you really should look into setting up tests.
*snicker*

I'm fundamentally lazy, don't multi-task well and this never stays at the top of my queue for very long. Working on it is also a reminder of how far my skills and knowledge are from the current state of the art ;-)

I'd love tests. I had not done them yet because I'm not sure I am prepared to relearn what little I knew about mocking and not sure what other techniques would actually be beneficial for code that does most of its work querying the OS, file system and external web sites. That said, there is something to be looked since the code finds java at C:/Program\ Files/Java/jdk-21/bin/java but Cygwin finds it at c/Program Files/Common Files/Oracle/Java/javapath/java so there are some tests that would be helpful.

I am also dragging my feet on test because there are some implementation details that almost certainly won't survive scrutiny. I have a class that I think could be a Record and my avoidance of regex and JSON parsing is painfully obvious. So do put the effort into tests before or after code changes to resolve those? The right answer is before but note "fundamentally lazy" ;-)

But thank you for comments that will eventually move me in the right direction.
 
a class that I think could be a Record
Observation before you go too far down that path: Record didn't come until what, Java 15? (okay, looks like first preview was Java 14 and it was finalized in 16.)

So do put the effort into tests before or after code changes to resolve those? The right answer is before but note "fundamentally lazy" ;-)
You're correct that the right answer is generally "before refactoring" to prevent further backsliding :)

Regarding the reported failure mode, I suspect the simplest fix is to use Runtime.exec(String[]) so Java doesn't need to tokenize your string for you.
 
Observation before you go too far down that path: Record didn't come until what, Java 15? (okay, looks like first preview was Java 14 and it was finalized in 16.)


You're correct that the right answer is generally "before refactoring" to prevent further backsliding :)

Regarding the reported failure mode, I suspect the simplest fix is to use Runtime.exec(String[]) so Java doesn't need to tokenize your string for you.

I didn't use a record because I was too lazy (there's that word again) to see when they were introduced but not using one was easier than looking it up.

Just FYI it isn't logging anything either and with the run parameter and failure it never runs mafia

I just got a KoLmafia test working so am resting on my laurels momentarily. multitool is not especially robust in the sense of detecting and working around errors. It really depends on the naming convention so fixing the NPE could have broken something downstream. I have things to chew on. As it stands if the only KoLmafia jar files is "misnamed" then I would expect it to download latest mafia and multitool jars but launch nothing. But if you rerun multitool I would expect it to launch the mafia jar that was just downloaded because it would be named properly. I need to dig deeper. I may have to decide to allow "Latest" to, by definition, be newer than any numbered version or just delete delete everything in the directory that does not fit the pattern.

As currently implemented the log file name is based on date and the file is overwritten, not appended to, so you probably need to look at the file to see if anything is going on and I probably need to timestamp entries and perhaps Append.
 
As it stands if the only KoLmafia jar files is "misnamed" then I would expect it to download latest mafia and multitool jars but launch nothing. But if you rerun multitool I would expect it to launch the mafia jar that was just downloaded because it would be named properly.
I am surprised by the notion that multitool might download a new jar, and then not launch it. Would it launch the old jar? Would it do nothing?

IMO the "expected" behavior from what I am viewing as a launcher + auto-updater is the following steps:
  1. Update Mafia if necessary.
  2. Clean up old versions.
  3. Launch the latest jar.
just delete delete everything in the directory that does not fit the pattern
Please don't do this -- you will get many angry comments from people complaining that you nuked their Downloads folder or worse.

As currently implemented the log file name is based on date and the file is overwritten, not appended to, so you probably need to look at the file to see if anything is going on and I probably need to timestamp entries and perhaps Append.
There are pros and cons. I personally opt to clobber my logfile because I don't really care about execution history across days, and I like not having to worry about cleaning up the log file periodically.
 
I am surprised by the notion that multitool might download a new jar, and then not launch it. Would it launch the old jar? Would it do nothing?

IMO the "expected" behavior from what I am viewing as a launcher + auto-updater is the following steps:
  1. Update Mafia if necessary.
  2. Clean up old versions.
  3. Launch the latest jar.

Please don't do this -- you will get many angry comments from people complaining that you nuked their Downloads folder or worse.


There are pros and cons. I personally opt to clobber my logfile because I don't really care about execution history across days, and I like not having to worry about cleaning up the log file periodically.

Multitool's origin story is rooted in an attempt allow a user to determine whether their current version of Java was sufficient to run KoLmafia. That was me reacting to the Java nag PR. gausie suggested it could download and launch KoLmafia and that was easy to add. But now that the launcher is the aspect getting the most interest, I need to revisit several implementation decisions. So I generally agree with your expectations but have not implemented them.

I have a struggle balancing flexibility and simplicity and should probably err on the side of simplicity unless or until I implement a GUI or preferences file, both of which I am resisting.

The "pattern" that would have triggered deletions would have been <ToolName><version>.jar so I wouldn't really have trashed someone's downloads directory but yeah, that was a scarily ambiguous statement.

The log file was my response to not wanting to write a GUI yet and not being able to guarantee that multitool would be running in a console that would display output. I do think managing the user's expectation's with documentation (one log per day, overwrites previous, use OS time stamp to determine when something migth have happened).

I am learning how to mimic redirects in tests so will get back to this momentarily.
 
I am surprised by the notion that multitool might download a new jar, and then not launch it. Would it launch the old jar? Would it do nothing?

IMO the "expected" behavior from what I am viewing as a launcher + auto-updater is the following steps:
  1. Update Mafia if necessary.
  2. Clean up old versions.
  3. Launch the latest jar.

Please don't do this -- you will get many angry comments from people complaining that you nuked their Downloads folder or worse.


There are pros and cons. I personally opt to clobber my logfile because I don't really care about execution history across days, and I like not having to worry about cleaning up the log file periodically.
I removed all the jars other than the current and still get the same results of the second error. It updates both mafia and multitool fine
 
Yeah, the second error is because Java is in a directory with a space in the name (which primarily affects Windows users, who usually have Java under C:\Program Files\). Known issue; we'll provide an update when that's fixed.
 
I am writing tests. Might take a couple of days since I think I will have to relearn how to Mock classes and I know I need to make and use the equivalent of KoLmafia's root - KoLmafia/test/root

Once I have tests I am going to return to some of the issues reported above. I will also consider whether this it the time to replace String operations with regex and JSON parsing.

Then I will work on my roadmap, laid out below. I am sharing because it is open for discussion although I am striving for something that "Just works" and does so quietly.

  • Determine latest local version of multitool.
  • Determine latest remote version multitool.
  • If remote is newer then
    • Download remote version.
    • Restart multitool using downloaded version which should now be latest local version.
  • Delete all versions of multitool except the latest.
  • Determine local version of Java.
  • Determine minimum version of Java for latest version of KoLmafia.
  • If local Java version is inadequate for KoLmafia then
    • Emit message and exit.
  • Determine latest local version of KoLmafia.
  • Determine latest remote version KoLmafia.
  • If remote is newer then
    • Download remote version of KoLmafia.
  • Delete all versions of KoLmafia except the latest.
  • Launch latest version of KoLmafia and exit multitool, leaving KoLmafia running.
Notes:

All file and version operations depend upon a filename convention - prefix-version.jar - where prefix is either “multitool” or “KoLmafia” and version is a string of digits corresponding to the version number, possibly with “-M” appended. File names will be case sensitive when created by multitool but case insensitive when making comparisons involving files in local storage. Similar, but non-matching file names such as KoLmafia-Latest.jar will be ignored and neither deleted nor launched.

Normal logging will be to a log file, that is overwritten each time multitool is launched and to System.out. Logging will be limited failure messages typically when one of the above steps fails.

File deletion needs to be robust enough to not delete a running jar until it exits. It is likely file deletion will be deferred until later in the implementation.
 
I got some tests written and working. A side effect was that I am parsing Json in at least one place instead of using a mix of indedOf and substring. I was searching for something, could not find it and could not figure out how my search differed from what was in the file so I gave up and used a Json parser. I won't actually commit all of that until I have at least verified that the things that worked before still work. I tried to get coverage reports and haven't yet succeeded but I can run them locally so at least I have the information. Today's plan is more test coverage and then start restructuring according to my outline above. Posts like this help hold me accountable and ignore the next shiny thing when it comes up.
 
Hit a break point. r64 should do what previous versions did and might fix something, but probably not. Some testing and I removed some jar files that were bundled but not needed and so the jar is much smaller. There are some case sensitive bugs I need to investigate. If I actually write a file I want it to have the canonical capitalization. multitool does what I expect on my Debian 10/Java 11 test system - detects Java 11 and refuses to run KoLmafia. I note that when I ran KoLmafia anyway, from a command line, there was a fairly explicit message about the wrong Java version. Perhaps the angst about users who could not run mafia and didn't know why was because they were launching from a situation where System.out is lost.
 
Back
Top