Posts tagged with "FOSS"

More syncing GitHub to GitLab and Codeberg

1 min read

Following on from my first post about this, I've tweaked the script I'm using to backup a repo to GitLab and Codeberg:

#!/bin/sh

# Check if the current directory is a Git repository
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
    echo "Error: This directory is not a Git repository."
    exit 1
fi

REPO_NAME="$1"

# If no repository name was provided, try to get it from the origin remote
if [ -z "$REPO_NAME" ]; then
    ORIGIN_URL=$(git remote get-url origin 2>/dev/null)
    if [ -n "$ORIGIN_URL" ]; then
        REPO_NAME=$(basename -s .git "$ORIGIN_URL")
    else
        echo "Error: No repository name provided and no 'origin' remote found."
        echo "Usage: $0 <repo-name>"
        exit 1
    fi
fi

echo "Configuring multi-forge backup sync for: $REPO_NAME"

# Set up the remote called backups. Anchor it to Codeberg.
git remote remove backups > /dev/null 2>&1
git remote add backups "ssh://git@codeberg.org/davep/${REPO_NAME}.git"

# Set up the push URLs.
git remote set-url --push backups "ssh://git@codeberg.org/davep/${REPO_NAME}.git"
git remote set-url --add --push backups "git@gitlab.com:davep/${REPO_NAME}.git"

# Only ever backup main.
git config remote.backups.push refs/heads/main:refs/heads/main

# Also backup all tags.
git config --add remote.backups.push 'refs/tags/*:refs/tags/*'

echo "----------------------------------------------------"
echo "Backups configured:"
git remote -v
echo "----------------------------------------------------"
echo "To perform the initial sync, run: git push backups"

### setup-forge-sync ends here

The changes from last time include:

  • The repo name now defaults to whatever is used for GitHub, so I don't have to copy/paste it or type it out.
  • It now backs up all the tags too.

I've been running with this for a couple of days now and it's proving really useful. Well, when Codeberg is available to push anything to...

More Codeberg issues

1 min read

As I've said earlier, I'm not looking to move off GitHub any time soon, but I am curious about evaluating the options. So far, while trying out Codeberg, I am finding it to be very unstable.

A little earlier I was simply browsing some of the repositories I've been adding and got very slow load times, and then a 500.

Codeberg 500 error

As I've said elsewhere: I really wouldn't expect perfection. I doubt that Codeberg has the money behind it that GitHub does. But, again, there is that issue with moving off GitHub because of instability; from that point of view it would feel like swapping some occasional instability for what, at the moment, is feeling like regular instability to the point that I wouldn't get too much done.

Syncing GitHub to GitLab and Codeberg

2 min read

I've had a GitLab account since December 2017. This came about because of the new job I started in January 2018. They used a self-hosted internal instance of GitLab for all their code, so it made sense I get familiar with it (it wasn't hard; especially back in 2017 it was near enough a clone of GitHub in terms of what it did). Since then, though, I've never really done anything with it. I think I had a repo or two on there for a short while, but I must have nuked them at some point because the account has been empty for the longest time.

A Codeberg account, on the other hand, only got created the other day. Having created this, I got to thinking about how I might use it. In doing so I thought back to my GitLab account and then also got to thinking about where all my public code lives, and how "safe" it is.

Now, sure, the whole point of Git is that it's distributed. Forges are a useful thing to have and work with, but they shouldn't be the place where your code lives. On the other hand, I've had so many machines, and so many work environments, that it has become the case that my GitHub account has become the storage location for my code and projects.

Mostly this is fine. If GitHub were to disappear tomorrow I imagine we'd all have bigger things to be worrying about anyway. But the principle stands: why not distribute the load? Why not distribute the effort when it comes to sharing code I write?

So yesterday I finally decided on a plan: for the moment at least, I'm going to keep using GitHub as my "primary" location for working on stuff. It's where I'll have WiP branches, it's where I'll keep issues, it's where I'll encourage people to raise requests and stuff, it's where I'll host this blog. But I'm going to start syncing projects to both GitLab and Codeberg. I see this as having two benefits: anyone who doesn't want to interact with GitHub can now easily fork code, and if they wish they can raise issues and the like too. Meanwhile, in doing this, I'll also have the added benefit of my code being "backed up" in at least three different locations1.

The approach I've settled on, for the moment, is based around this little shell script:

#!/bin/sh

# Check if a repository name was provided
if [ -z "$1" ]; then
    echo "Error: No repository name provided."
    echo "Usage: $0 <repo-name>"
    exit 1
fi

REPO_NAME="$1"

# Check if the current directory is a Git repository
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
    echo "Error: This directory is not a Git repository."
    exit 1
fi

echo "Configuring multi-forge backup sync for: $REPO_NAME"

# Set up the remote called backups. Anchor it to Codeberg.
git remote remove backups > /dev/null 2>&1
git remote add backups "ssh://git@codeberg.org/davep/${REPO_NAME}.git"

# Set up the push URLs.
git remote set-url --push backups "ssh://git@codeberg.org/davep/${REPO_NAME}.git"
git remote set-url --add --push backups "git@gitlab.com:davep/${REPO_NAME}.git"

# Only ever backup main.
git config remote.backups.push refs/heads/main:refs/heads/main

echo "----------------------------------------------------"
echo "Backups configured:"
git remote -v
echo "----------------------------------------------------"
echo "To perform the initial sync, run: git push backups main"

### setup-forge-sync ends here

I'm going to keep all repo names the same2. So when I use this script it'll set things up so I can git push backups and main will then get pushed up to both GitLab and Codeberg. I don't feel the need to be keeping any WiP branches in sync or kicking about, likewise any gh-pages branches.

While I'm sure I could have done something a little more automated, this feels like a neat and simple approach, and also allows me to curate what appears in the two other places over time (I suppose, eventually, I'll mirror everything that isn't a dead experimental repo, but meanwhile I'll prioritise projects that are either still very useful or which I'm actively developing and maintaining).


  1. Yes, I have other backups too, but they're always current-working-machine type backups. 

  2. Except, perhaps, for any repo whose name starts with .; I seem to recall that GitLab can't handle that, for some bizarre reason. Perhaps that's fixed now? 

Trying out Codeberg

2 min read

Following on from what I wrote about GitHub recently, I thought I'd check out Codeberg. While I'm aware of it (it is supported by Hike after all), I've never actually used it and have never had an account there.

I was delighted to find my preferred user name was actually available, which made me more inclined to create an account. The account creation process itself seemed a bit of a faff. I can't remember the details now, but it took a couple of goes and necessitated a password reset and recovery to actually get in (I recall there was some sort of error when I tried to use the activation link sent in the email, which took quite a while to turn up, but the rest is hazy, and I wasn't taking notes). It might be that it didn't help that I was signing up in a mobile browser.

That aside, though, I got up and going in the end.

At this point I'm not quite sure what I want to do with the account. While I'm nowhere near being willing or able to move my GitHub activity over there, it at least feels like it might be a viable backup location via which I can make code available. Also, and probably more importantly, it makes it easier for me to follow projects that use it as their primary (or only) forge.

This morning I found myself following a link to a project hosted there. It looked interesting, it looked like something I'd want to follow. It didn't go so well. I hit the star button and... busy circle.

Slow star

This lasted for a while with nothing happening. So I refreshed the page, no star on the repo, so I tried again. Same result. I tried a third time and got something different right away.

Codeberg error

At some point I ended up with a big fat 500 page.

Do I see this as an issue? Of course not. Could be I caught it on a bad day. Stuff happens. I've seen a 500 from things I'm responsible for before now. I'm not going to expect perfection. But it does remind me that leaping from one forge to another, to chase platform stability, and in doing so give up a long history, is a risky endeavour without a guaranteed payoff.

On GitHub

2 min read

It seems that dunking on GitHub is the flavour of the day. At the moment most of the social/news type things I tend to read are filled with the Ghostty news, as well as a small revival of posts and links to blog posts about all the recent outages. It's understandable. It does seem that something has shifted with GitHub in the last few months. While it hasn't been the site I used to enjoy for quite some time now, it just seems to be getting worse at the moment.

It's even pissing off the loyal AI enthusiasts with the Copilot changes.

As I read all of this I find myself mostly nodding along. For the most part I'm not finding that GitHub is getting in the way and stopping me from doing the things I want to do, and for the most part it does act as a vital tool that lets me get work done, and also lets me enjoy my longest-enjoyed hobby. On the other hand I couldn't help but sigh and think "yeah, I get why this is the time that people are done" when I opened up the PR page for this blog, just now, and saw this:

A warning about my PRs

It does get me thinking about my relationship with GitHub, and how long I've been using it. As I've written before, I created my account back in 2008; I was within the first 30,000 users. While my use of it was only very occasional for quite a long time, for the last decade I've been constantly interacting with it. It is somewhere I visit constantly, not just to do work on my own projects, but to read what other people are doing. One of the first things I do every morning, when I sit down at my desk, is open my GitHub dashboard page and have a scroll through the feed to see what people I follow have been up to.

It's generally been the most fulfilling feed I've read.

But I'm also getting that feeling I got when I hung on to my Twitter account far longer than I really should have; not just because of the general vibe of "it's falling apart", but also other types of questionable behaviour. The degrading performance, the troubling business relationships, the over-emphasis on all things AI... it adds up.

There is a sense that some time ago was the time to move elsewhere as my sociable forge (probably around the time that Microsoft took over), and that not having done that, now is the second best time. But the effort of making that move is non-trivial and, quite frankly, I'd want to see where folk start to land, if they started to move away in any numbers at all. For me the real utility of GitHub isn't the "it's somewhere to store my shit" thing, it's the socially coding thing.

Then there's the follow-up problem: if some other forge was to become the next flavour of the decade, it too would probably end up suffering the same fate as GitHub.

Perhaps now is the time for me to start looking into options for collaborative code forges that offer the same sort of solution that Mastodon does for Twitter-like nattering.

unabbrev.el v1.0.0

3 min read

Back in the late 1990s, like plenty of people who were very online, I was a very avid user of Usenet. There were a few groups I was very active in, even a couple that I maintained a FAQ for. Being that active and wanting to help and answer questions, I was forever posting and pasting links to various resources. Given that I used Emacs to edit my posts1, I eventually realised that I should come up with a tool that let me call on common URLs quickly.

So back in 1998 handyurl.el was born. It was a simple idea: have a file of URLs that I commonly refer to and let me quickly pick from one and paste it. This made for a useful tool and also gave me something to build given I was learning Emacs Lisp at the time.

For reasons I can't quite recall, some time later (the next year, by the looks of things), I wrote quickurl.el as a successor to handyurl.el. I honestly can't remember why this happened, I can't remember why I didn't just keep extending handyurl.el. But, anyway, quickurl.el did more and was more flexible, with built-in URL-grabbing and editing and so on.

Not that long later I got an email from the FSF asking if I might be willing to hand over copyright so that quickurl.el could become part of Emacs itself. I was, of course, delighted to do so.

Eventually quickurl.el was declared obsolete and, while it seems to still be shipped with Emacs, it's not documented or easy to discover.

In the deprecation notice in NEWS the suggestion is that the user should switch to one or more of 3 alternatives:

** The quickurl.el library is now obsolete.
Use 'abbrev', 'skeleton' or 'tempo' instead.

abbrev I know, the other two I've never noticed and don't know anything about.

Obviously, between quickurl.el being pulled into Emacs, and it being made obsolete, my use of it fell right off. I eventually stopped posting to and reading Usenet, I also stopped using mutt+Emacs as my mail client of choice, and so found myself seldom writing things that needed lots of links, in Emacs.

Until recently.

At the moment I'm finding that I'm wanting to write on my blog more and more, and doing that means I often want to include some common links, and I write my posts in Emacs using markdown-mode and with a little help from blogmore.el; the need to have an easy-to-pick-from common menu of URLs is back.

Driven by this I've made a point of using abbrev to initially solve this problem. This works, but I do have a problem: I keep forgetting what the abbreviations are. I find myself wanting to have a key binding that lets me at the very least completing-read the desired abbrev. So yesterday I quickly knocked up unabbrev.el.

It's simple, straightforward, small and does the job I needed. Doubtless there's something else out there that can do this sort of thing too, but part of the fun of Emacs (for me) is that I find I have a need and I can hack together some Lisp and get that problem solved.

unabbrev in action

I suppose what I should do is revive either handyurl.el or quickurl.el and tweak and update whichever, at the very least adding some sort of insert formatting facility that is sensitive to the underlying mode (because links in Markdown need a format different from links in HTML, etc).

For now though unabbrev.el is going to help my failing memory when I want to link a common resource.

As an aside, all of this does have me wonder about one thing: is the Free Software Foundation the place that code goes to die? Like, sure, of course I can make changes to quickurl.el and do my own thing with it, as long as I don't misrepresent the copyright status and maintain a compatible licence, etc; but there is this thing where, if Emacs doesn't want that code any more, if the FSF don't want that code any more, wouldn't it be nice if they'd sign it back over again?

I am tempted to drop them a line and see what the deal is. I did tag-ask on Mastodon but got no reply. Unfortunately though that account looks like the FSF treat Mastodon as a write-only resource.


  1. But curiously never got into Gnus, my news client of choice was slrn and I composed posts in Emacs. 

Astral and OpenAI

1 min read

It's a couple of days now since the news hit that OpenAI are in the process of purchasing Astral. When I first saw this my initial reaction was pretty much "woah", followed by getting on with what I was doing.

Until, that is, I opened up the socials. On Mastodon, Reddit, BSky, Threads, etc... anywhere I followed any Python-based content, I was seeing very firm opinions posted. Plenty of folk either talking like it was the end of their tooling as they know it, or proudly boasting that they'd avoided uv and ruff (and lately ty too I guess -- not that I've really tried that yet myself) because they'd predicted this evil outcome from the start and they were untainted by this but look at all you idiots who fell for this long play!

Okay, I exaggerate slightly, but there were some pretty strong opinions kicking around, especially in the (often fairly smug) "I stayed pure and never used uv" camp.

Personally, I don't get it. The last I looked the tools I use that Astral are behind are FOSS. Also, the last I looked, plenty of FOSS tooling is written by folk who are either paid to do so (I had my moment), given some time in the day job to work on those tools, or just plain have a day job and also work on those tools. If, as plenty are speculating, the Astral purchase is an acqui-hire, the likely result is going to be one of those three scenarios.

If it isn't one of those scenarios, if work on uv and friends just ceases, well, at best some smart folk can fork the tools that are useful and keep them going (this is a major benefit of FOSS after all) and, at worst, well... we can fork them and agent the shit out of them. Right?

You get what you pay for

2 min read

Just recently I saw a post go past on Mastodon, complaining about the author's perception that there was a breakdown of trust in the FOSS world, in respect to the use of AI to work on FOSS projects, or at least the willingness to accept AI-assisted contributions. The post also highlighted the author's reliance on FOSS projects and how they're driven by ethical and financial motivations (some emphasis was placed on how they had no money to spend on these things so it wasn't even necessarily a choice to FOSS up their environment).

This was, of course, in response to the current fuss about how Vim is being developed these days.

I don't want to comment on the Vim stuff -- I've got no dog in that fight -- but something about the post I mention above got me thinking, and troubled me.

Back when I first ran into the concept of Free Software, before the concept of Open Source had ever been thought of, I can remember reading stuff opposed to the idea that mostly worked along the lines of "you get what you pay for" -- the implication being that Free Software would be bad software. I think it's fair to say that history has now shown that this isn't the case.

But... I think it's fair to say that you do get what you pay for, but in a different sense.

If your computing environment is fully reliant on the time, money and effort of others; reliant on people who are willing to give all of that without the realistic expectation of any contribution back from you; I feel it's safe to say that you are getting a bloody good deal. To then question the motivations and abilities of those people, because they are exploring and embracing other methods of working, is at best a bad-faith argument and at worst betrays a deep sense of entitlement.

What I also found wild was, the post went on to document the author's concerns that they now have to worry about the ability of FOSS project maintainers to detect bad contributions. This for me suggests a lack of understanding of how non-trivial FOSS projects have worked ever since it was a thing.

I mean, sure, there are some projects that are incredibly useful and which have a solo developer working away (sometimes because nobody else wants to contribute, but also sometimes because that solo developer doesn't play well with others -- you pick which scenario you think is more healthy), but for the most part the "important" projects have multitudes working on them, with contributions coming from many people of varying levels of ability. The point here being that, all along, you've been relying on the discernment and mentoring abilities of those maintainers.

To suggest they're suddenly unworthy of your trust because they might be "using the AIs" is... well, it feels driven by dogma and it reads like a disingenuous take.

Don't get me wrong though: you are right to be suspicious, you are right to want to question the trust you place in those who donate so much to you; almost always this is made explicit in the licence they extended to you in the first place. But to suggest that suddenly they're unworthy of your trust because they're donating so much value to you in a way you don't approve of...

...well, perhaps it's time for you to pay it back?

How not to ask for help

8 min read

My association with Textual works on two levels: on the one hand, sure, it's currently my day job; on the other hand it's a FOSS project that I'm keen to support so "free time me" tries to work with it and support others working with it too. For this reason you'll often see me being terminally1 online in the Textual Discord, trying to answer questions as they come up, every waking free moment.

Almost without exception the people who ask for help are appreciative and ask in the spirit of wanting help and wanting to work together with whoever is helping them to get an answer. That... that's actually quite a cool thing to be part of. I like the sense of community that comes from someone going "bah I'm trying to do this thing and it isn't working PLEASE HELP!".

And then... well, let's just say that sometimes the odd question will crop up that seems to be asked from a less collaborative position.

Without wanting to appear to dunk on an individual (I don't wish to), I want to break down an example that happened yesterday. For some background, I'd been AFK all day, having a wonderful time in town with a friend, shopping, lunch, a movie, that sort of thing. A nicely-chilled day where I didn't even look at the Discord notifications that had popped up on my watch and phone.

However, later on that evening, finally home and flopped on the sofa, I saw a question pop up that, while lacking any useful detail and possibly suffering a wee bit from being an XY problem, the immediate answer was clear:

BadIdentifier: 'test.udp_json_client-input' is an invalid id; identifiers must contain only letters, numbers, underscores, or hyphens, and must not begin with a number.

????????????????? a dot isn't allowed?

Like I say: it lacks context and detail, and the number of question marks doesn't really clarify much, but the core question that seems to be at play here is "is it true that a full stop can't be used as part of the ID of a widget?".

The answer is: no, it can't. There's a reason for that too, and if someone were to take a step back for a moment and think about how IDs play a part in queries and how they'd be used in a stylesheet, the reason for that might pop out. So, to help the person asking the question walk in the direction of the answer, I reply:

When you come to query that how would the parser know it’s not ID “test” combined with a class, if dot was allowed?

Before we go on, to illustrate my point, consider this ID: foo.bar. When you come to query that back, or use it in a stylesheet, how would #foo.bar look? Is it a widget with the ID foo.bar; or is it a widget with the id foo and the class bar?

As far as Textual's CSS is concerned, it would be the latter.

But at this point it didn't seem necessary to get into all that detail; I like to try and assume knowledge on the part of the person asking the question, sans any other evidence, so for the moment I'll assume a "oh, right, yeah, that's a damn good point" kind of reply. Or if not, perhaps a "I don't quite follow, could you explain?" reply, in which case I'm happy to go into all the detail.

The reply was neither:

why are element ID and classes co-mingled?

this was previously allowed so your question doesn't really make sense to me

Now I'm confused. Asking why element IDs and classes are co-mingled seems odd; but I'm used to chatting with people who don't have English as a first language so I'm going to assume it's just a wording choice; but the latter part is very odd: this has never been allowed. Or, more to the point... without any proper context I can't really appreciate what claim is being made here.

You see... I did notice a bug in Textual recently, when it came to widget IDs. Long story short: when you set your ID for the widget in your code, no actual validation of the ID was being done. This was an oversight that was fixed in the latest release.

But knowing that that's the case would be guesswork on my part; I'm also fresh at my desk after a day out; I'm probably not quite in the coding/Textual zone yet, so rather than try and guess half of the conversation, it's easier to just ask the person who is asking. So I ask them to restate the question, and give some more background.

The reply is:

the objective is to put a string like test.udp_json_client-input as the label of a tab, which previously just used the ID property. from skimming release notes, is it better to explicitly set the label, and then assign something compliant for the ID separately?

Wait... what? I thought we were talking about valid widget IDs, now we're talking about tabs and labels? Do we mean TabbeContent and the labels of a TabPane? This is a bit different. So I'm sat there trying to figure out this person's thought process so I can offer the help they're after and this follows:

okay @davep, you have a real bug. --content-tab- prefix is not ephemeral. if I create a tab and grab .id, that prefix comes with it, so if you save it for later and try to set .active, assigning .active doesn't agree that there is a tab --content-tab-thing

so I need to de-mangle the name manually before assigning .active I guess?

Wut? Like... wut? Okay, we do seem to be talking about TabbedContent, I recognise the values being mentioned here; we did some work late on last year that added some namespacing to parts of the TabbedContent widget in an effort to reduce some foot-gun situations.

But... there's no . being used in the IDs as part of that; why are we now proclaiming a bug in an unrelated PR? That's quite the leap with zero evidence. Like... sure, I'm all for being alerted to bugs and fixing them, but this doesn't seem like that.

And then there's the "so I need to..." conclusion that also seems to have no connection to the original question.

Anyone who has ever done support will recognise this situation, I'm sure. Someone has seen a problem, they've dug around a little and reached a conclusion about what the cause is, and turns up looking for help with the conclusion they've reached (very much a variant of a XY problem).

That almost never gets us where we want to go, so I do the obvious thing; I try and reboot the question; I try and get us back to the start and try and get some clarity; I try and encourage asking the question with zero assumptions:

I'm afraid I'm still not really understanding your question, as it now no longer seems to relate to what you very first asked. Perhaps you could start again, ideally with an MRE of what you're looking at and trying to do, for clarity?

I figure, whatever the problem is, it can be illustrated with like a dozen lines of code. Also, when asking people to do this, it often actually helps them rubber-duck their own problem. There's been plenty of times on Discord where someone's "found a bug" in Textual, they're asked to make an MRE of it, and they come back and go "oh, shoot, right, I did that and realised the bug was in my code". It's cool when they happens; everyone learns something.

So... no MRE comes back, but this is the reply:

I'm trying to fix multiple breakages in my application from some recent changes. Right now I can't wrap my head around what to assign a tabbed_content.active for it to work how it did before (where if you have a tab with ID sample, you can assign tabbed_content.active = "sample", but you can't do that anymore)

While not an MRE, I can work with this. It seems clear that they have a TabbedContent where they have a TabPane with the ID "sample" and they are struggling to make it the active tab by setting active to "sample". That seems hugely unlikely, this is what TabbedContent is all about, I think we'd have noticed (I'm petty sure we've got unit tests that cover this), but I'm game. I can test this. And the MRE I write will illustrate there isn't a problem.

So I reply:

Again, I can only suggest that you make an MRE of the issue you're seeing. For example, here's me making a set of tabs, the last of which has the ID "four", and I set the active to "four":

and provide the code:

from textual.app import App, ComposeResult
from textual.widgets import TabbedContent, TabPane, Label

class TabbedContentApp(App[None]):

    def compose(self) -> ComposeResult:
        with TabbedContent():
            with TabPane("One", id="one"):
                yield Label("One")
            with TabPane("Two", id="two"):
                yield Label("Two")
            with TabPane("Three", id="three"):
                yield Label("Three")
            with TabPane("Four", id="four"):
                yield Label("Four")

    def on_mount(self) -> None:
        self.query_one(TabbedContent).active = "four"

if __name__ == "__main__":
    TabbedContentApp().run()

Based on what they've most-recently said is the problem, I'm confident they'll see that this MRE is their situation in a nutshell, and we can work out from there and figure out what the problem is they're seeing and where this . in their IDs is coming from (because I'm very confident it isn't coming from the work that was done on TabbedContent).

This is good. We're getting close to heading down a good path; I can feel it!

I was wrong.

https://github.com/Textualize/textual/blob/main/src/textual/widgets/_tabbed_content.py#L513

there's no way you can deny you just added a metric ton of shenanigans with the tab ID stuff. I can't get it to work at all anymore (assigning .active), but yes I will either come up with an MRE or find the bug and let you know

So, rather than back up a wee bit, work with the MRE I wrote for them so we can take a walk through the problem, they instead decide to tell me that the PR I did last year (which still isn't implicated in any of this outwith of them seemingly assuming it's the cause of all the issues, presented with zero evidence that it is) was simply "a metric ton of shenanigans".

No!

Stop!

This is not how you ask for help.

This isn't how you ask for help from a product or service you pay for. This really isn't how you ask for help from a Free Software project, where the people who are offering you help are doing so in their free time because they want people to be able to build cool things with it.

It really isn't hard at all to show just a wee bit of respect for people's time and willingness to try and help you.

Now... I get it. I can imagine a scenario where someone has just updated Textual and their application suddenly starts throwing all sorts of weird and new errors. That happens. That happened to me on Thursday evening just gone. But that's no reason for approaching getting help like this.

The way to approach it is this: pin the problem dependency, perhaps publish a new version of your application so there's no accidental update of the dependency, then head to any of the help resources for the dependency has and work with people who want to help you to find the cause of the problem. Trust me, it'll go a lot faster if you work with them, take on board suggestions (no matter how odd they might first appear), and really don't call their code "a metric ton of shenanigans".

The conclusion to all of this? The person asking the question eventually found they were setting some widget's ID to an invalid ID; one with a . in it. So as I suspected and wanted to walk them to: they had invalid IDs all along and they only found out about this because ID validation was fixed.

Perhaps one day they'll retract the claim that my actually-unrelated code that wasn't "just" released but was from last year is "a metric ton of shenanigans". ¯\_(ツ)_/¯


  1. Geddit? GEDDIT?