not quite minimalistic enough  

2024-12-08

100 percent useful.

World-shattering Vim discovery of the day: %.

2024-10-26

Complexity for its own sake

Turns out I just discovered how GitHub actions work when I started setting them up in Gitea. OH. MY. GOD.

I spent quite some time wondering about the sheer audacity of fetching action implementations from GitHub. OK, not a big deal, I can do that manually and put them into Gitea so at least it doesn’t try going out to GitHub each time.

But then.

The next error message from the test workflow in the Gitea docs came just after a successful checkout:

Cannot find: node in PATH

So simple. So … deceiving.

OK, something that should be in $PATH isn’t. A bit weird to call a path entry a file system node, but whatever.

To find out what it was that I was missing, I looked at the implementation of actions/checkout.

(Look away now, kids, this isn’t good for you.)

THE BL@@DY CHECKOUT ACTION THAT NEEDS TO RUN ONE, COUNT ‘EM, ONE, GIT COMMAND LINE IS WRITTEN AS SOME FIFTEEN TYPESCRIPT FILES THAT WANT TO BE RUN WITH NODE.JS?!?

ARE YOU F@@@ING KIDDING ME?!? TRUMP HIMSELF COULD NOT HAVE COME UP WITH ANYTHING EVEN APPROACHING THIS UTTER BENIGHTEDNESS!

No wonder everything takes ages these days despite our computers being immeasurably faster than Way Back When.

I’m … let’s call it flummoxed. That is certainly a nicer word than several others I have in mind.

Would the authors of actions/checkout please consider rewriting this … this THING in a saner, and more preserving of its user’s sanity, way?

Thank you. I’ll go cry in the corner now.

i’m scared to look at any others

2024-06-30

Exeunt VMware Tools

In my experience the VMware Tools installers will work only when run on VMware VMs and crash immediately (with error 0xC0000096, STATUS_PRIVILEGED_INSTRUCTION) everywhere else. This is a problem when you move a VM to another platform and either forget to uninstall the tools first, or are reluctant to lose the VMXNET drivers.

There are various sets of instructions on the Internet on how to uninstall VMware Tools using other means than the regular uninstallation, but I have found they either do not work, or are hopelessly difficult to follow. (The latter is not something that should stop you, of course.)

So here is my own hopelessly difficult to follow set of instructions:

  1. Get a current VMware Tools installer from VMware.
  2. Create an AIP from it (VMware-tools-....exe /a).
  3. Use Orca or another MSI editor to remove the VM_LogStart and VM_LogEnd_Def actions from the InstallExecuteSequence and InstallUISequence tables in the .msi file.
  4. Run msiexec /l*v msi.log /x <.msi file>. It will exit immediately, and the log will show that the custom action you just removed was magically run nonetheless.
  5. Look for “Package we’re running from” in the log file. This will show a path in C:\WINDOWS\Installer, and it means that because the product is already installed, msiexec used the cached package instead of the one you gave it.
  6. Rename that cached package to get it out of the way.
  7. Re-run the uninstallation.

This should work. If not, start over.

2024-03-01

The enshittification of Notepad

So Microsoft recently decided that Notepad, the simplest text editor ever that has been a wrapper around a multiline edit control and a few common dialogs for basically ever, needed tabs. Because everything needs tabs now, I suppose. The measure of a complete program is no longer “it can send e-mail”, but “it has tabs”. Or something.

Not only does it have tabs now, but it remembers the contents of those tabs so it can display them again next time you start it. It was not good enough to remember the files to load them again, no, it caches their content.

This means that one use case for Notepad is made massively useless by this highly not-sought-after misfeature: Looking at secrets. It goes like this:

  1. Open a file that has a secret key in it or something.
  2. Use it.
  3. Close Notepad.
  4. Remove the removable storage that the file is on, or “lock” the encrypted volume, or whatever, so the key is isolated from the outside world again.
  5. Start Notepad again.
  6. Stare in horror at the secret key you thought was safe, but which Notepad copied to insecure local storage without asking.
  7. Frenziedly search for where that copy is (%LOCALAPPDATA%\Packages\Microsoft.WindowsNotepad....\LocalState\TabState) and delete it.
  8. Work out that the abomination now called Notepad has a settings window (via the gear menu on the right of the menu bar) and that you can disable the caching by setting it to open a new window on startup (this also deletes the cache) and even get rid of the tabs by setting it to open files in a new window.

Have a nice day.

2022-01-31

Second insight of the day

It’s time for my favorite thing. Let’s have a Python packaging rant.

Most people know that the Python world’s approach to packaging and distribution is best summarized, and probably directly inspired, by xkcd.

A long time ago, the decision was made, or accepted by mutual apathy, how installation tools like pip and the late, unlamented easy_install would find packages:

  1. Predict the file name (possibly more than one).
  2. Load an HTML page.
  3. Check every <a> on that page.
  4. Use the one that points at the most preferred file name variation.

The only thing in the page that is at all interesting in this model are the //a/@hrefs. Everything else is noise.

Enter pip 22.0, released ~2 days ago. It now uses a different parser for HTML pages than previous versions. Instead of the certainly entirely overpowered html5lib, whatever that is, it is now using something else, apparently called html.parser.

Remember, the approach to looking up download links for package files consists of looking at <a> elements. Finding them in HTML, however close to, or far from, the spec it may be, is not a big issue. (Anyone who allows user-generated content on a download page is beyond help anyway.)

Why, then, the switch to a parser that, in order to find <a> elements, requires that the page have a correct <!DOCTYPE html> declaration, i.e. the claim that it adheres to the HTML5 spec?

The HTML5 “spec” shall not be gone into here any further.

The result is pip 22.0.2, an emergency release so urgent that it could not even be tagged in the repo before it was put on PyPI (and the tag has still not been created as of press time). In the typical manner, whenever it encounters a page that does not have the canonical <!DOCTYPE> it will print a warning blaming the user for their audacity in installing packages from sources that do not wrap their unstructured lists of <a> elements in proper, (un)well-specified HTML5.

Hey, PyPA, you want a proper fix for that? Publish a file. One single file. Its name will end in “.xsd”, and it will describe how lists of package links are supposed to look.

Ceterum censeo: This bug would have been avoided by not suggesting to package publishers that you will accept any line noise as long as there are <a> elements in it, then suddenly deciding that the stuff surrounding the <a> elements really matters to you.

tl;dr: Shame on you. This took at least six minutes to write, go enjoy it.

First insight of the day

The trials of testing

PyCharm is a great IDE for Python development. Its support for Django projects is really good (if only it applied environment variables from the Django project setup to run configurations …).

As with everything Python, the structure of Django projects is not set in stone and everyone has their own preferred style. Mine is to have applications in (below) a common subdirectory. Unfortunately this means that Django’s built-in test framework (or possibly just unittest) does not find the tests on its own and I had to invent some complicated workarounds to automate them to my satisfaction.

This morning I discovered that all it needs to work is for me to tell it that that common subdirectory is a module by giving it an __init__.py.

2021-12-24

Not surprising.

So the PHP people, in a display of cleverness akin to that generally displayed in the development of their product, have put their downloads behind an automated guess at the “human-ness” of the client.

This obviously broke all automated updating everywhere, including by the FreeBSD Ports Collection. Very helpful, that.

Their bug tracker is apparently on its Christmas holiday, too.

2021-08-31

Extremely Tenacious

Edge updates (and also others that include something called the Edge WebView2) fail with 0x800951dd on some computers, but not others. Hm. 9 is FACILITY_SECURITY. The event log is full of “Windows Event Reporting”; dozens of events for each installation attempt. What is going on?

From the log (cleverly stored in %PROGRAMDATA%) is appears that the updater really wants to phone home, and if it cannot, it prefers to crash. Where the security thing comes from is unclear, particularly because 0x51dd is undocumented. Direct HTTP is blocked, so the installer prematurely departs this mortal coil. And tries again. And again. And again.

On computers where it works the log shows that the updater figures out where the proxy is, so the quick fix (until I figure out how to make the updater behave) is to tell the updater the same on the problematic systems.

2020-10-02

All glory to ccache!

From the poudriere logs:

Port Build date Elapsed time
devel/llvm90 2020-09-28 05:52:49
devel/llvm90 2020-10-02 00:17:10

Time saved thanks to ccache (your praise be sung in all homes!): 95.13 %, or in other words, a ~2000 % speedup.

2020-09-18

MailItem in changing times.

According to the documentation, the first parameter of the Reply (and ReplyAll, and Forward) events on a MailItem event in Outlook is “the new item being sent in response to the original message”.

Uh, no. At least in VSTO; not sure about VBA, but I cannot see how it could be different there given that VSTO is a wrapper around the same COM interfaces. The argument is the original item that is being responded to:

void OnReply(object Response, ref bool Cancel)
{
    Cancel = false;

    if (Response is Outlook.MailItem item) {
        string html = item.HTMLBody;
        int pos = html.LastIndexOf("</body>");
        item.HTMLBody = html.Insert(pos, "This is the modified item. ");
    }
}

After this handler runs, the original item that was replied to will have the new sentence at the end, while the reply is entirely original. I suppose this means that the response message is created first, and then the event fires with the wrong argument.

Helpfully, though, when using Outlook’s preview/reading pane (whatever its name is this afternoon) the InlineResponse event on the Explorer object actually gets the correct message, i.e. the new one.