Context
Long and boring historical context (click to expand)
The userscript copy-commit-reference.user.js
originates from a userscript for Bitbucket Server. Bitbucket Server is the hosting that I use at $dayjob. That userscript is/was part of Atlassian Tweaks, where it is natural to also want to support Bitbucket Cloud, which it did since version 2, which was actually the initial commit for the userscript in that repository (version 1 supported only Bitbucket Server, but wasn't published).
For personal projects, I mostly use GitHub, so I've created a separate userscript for it as well.
Merging the two userscripts seemed like a good idea, because
- it allows for easier code re-use between the two userscripts, which was mostly done by copy-pasting
- it forces to come up with a better architecture for separating the common code from code specific to a particular Git hosting – this separation in the Bitbucket script between Cloud and Server versions was implemented terribly.
Once I had implementation for GitHub and Bitbucket Cloud (Bitbucket Server had to wait a bit), it was natural to want to add more. I started by adding GitWeb and Gitiles, because I was aware of repo.or.cz through its mirror of git.git (uses GitWeb) and I was aware of kernel.googlesource.com (uses Gitiles).
During development of copy-commit-reference.user.js
, I've also figured out how to publish and use libraries for userscripts in a way that is compatible with rules of Greasy Fork.
As of version 2.3, the userscript supports eight different hostings, and there are plans to add seven more (15 in total, if all are implemented).
Problem
As of version 2.3, the userscript has size of 1.5K lines of code at roughly 54 kilobytes of JS. This seems like a bit of an overkill, if a user wants support for only one of the 8-15 supported hostings.
On the other hand, worrying about the code size is probably a premature optimization. For example, a fairly popular userscript – Stack Overflow Extras – is over 160 KB of JS, with 46+ KB of JSON, CSS, and HTML on top of that.
Solution
It might be a good idea to extract the common code of the userscript into a library, and replace the big userscript with 8-15 smaller separate userscripts, one userscript per Git hosting.
Pros
- Smaller footprint, possibly leading to faster execution.
- During publishing of a new version, users only need to update the userscripts relevant to them. For example:
- More obvious/readable applicability to the user – each of the separate userscripts will just have the hosting in the name instead of the generic
Git: copy commit reference
.
- Code simplification: a userscript for a single hosting doesn't need methods
getLoadedSelector
and isRecognized
in the class GitHosting
. This reduces the number of required methods from six to four.
- Contributors, who want to work on existing support of a particular Git hosting need to edit a small file, unencumbered by all other irrelevant Git hostings.
- It is an opportunity to get more experience for maintenance of libraries for userscripts.
- A separate userscript could be in a different repository (how bitbucket-copy-commit-reference.user.js was/is in Atlassian Tweaks, see context above). A separate userscript could be even maintained by another person. This solves the problem of availability of the hostings for testing – a separate maintainer would be responsible for testing their userscript on the instances that they have access to themselves.
- Easier to maintain up-to-date screenshots (cf. 52b8135 and 54d6c4a).
- Git tags no longer need to be created in the main repository for the userscript (might still make sense to do it for the library).
Cons
- If a user uses many hostings (as an example, I use Bitbucket Server, GitHub, and GitLab regularly) they have to install many userscripts
- This also leads to multiple userscripts getting updated, if a change in the common code was published to all userscripts.
- Harder to add support for new hostings. It would require creating infrastructure for a whole new userscript, which not all developers might be familiar with. This could be solved with some kind of template file.
- More complicated and slower iteration, when changes in the common code are needed (add new feature to library > publish library > migrate userscript to new version of library > use new feature of library in userscript)
- Support for userscript libraries in code editors is lacking. This means less information about types, worse auto-completion, etc.
- However, this issue can be worked around at least in VS Code.
- Increased maintenance burden for managing:
- metadata of userscripts (the
// ==UserScript==
section at the top) (solvable with shell scripts)
- documentation on Greasy Fork (solvable by storing it in the repo)
- separate changelogs
- Git tags will no longer be able to be created in a sensible manner – some users coming to a GitHub repo pay attention to presence or absence of recent releases/tags. Though this could be solved by introducing per-hosting tags:
github-1.2
, gitweb-3
, bitbucket-server-4
etc.