You are browsing as a guest. Sign up (or log in) to start making projects!

Glitchy

@Glitchy

Joined May 31st, 2026

  • 32Devlogs
  • 1Projects
  • 1Ships
  • 9Votes
Ship Pending review

I made a package manager for Windows, which is somewhat backwards compatible with scoop packages. To be honest there’s still a lot of work that I want to do, but I have exams and college application coming up soon so I can’t.

That’s not to say I’m not happy with the state of the ship. At the very least it has all the core features that a package manager should have, but there are still a lot of bugs which is why this is only v0.0.1.

The biggest challenge by far was trying to figure out how Scoop does things internally. A lot of stuff just doesn’t have documentation, so you have to dig through the really messy PowerShell source code.

  • 31 devlogs
  • 101h
Try project → See source code →
Open comments for this post

1h 46m 34s logged

So I wrote a README, added a license (MIT of course) and setup CI/CD so that releases are automatically built and deployed.

Honestly I forgot how hard it is to write a good README. You need to get a lot of information through without it looking like a wall of text.

0
0
7
Open comments for this post

5h 48m 17s logged

I forgot to make a devlog in between so this will be like 2 bigger devlogs.

I parallelized bucket updates, which speeds it up quite a bit. This also allowed me to try out parallelism even more, which I plan to apply throughout the CLI later on.

I also added configuration options for the runners which mocha shim will use to run certain file types. For example, you can set the python-runner to select the python version that’ll be used to run python scripts that are shimmed.

Downloads now have a progress bar, so you don’t need to wonder whether something is happening or not during a long download. Finally env_set is fully supported since I added the relevant variable parsing.

This was pretty much just me cleaning out the TODO list before I ship. I also did a lot of smaller bug fixes and refactors as seen below.

  • fix(commands): prevent app installation if already installed (cb27d07)
  • fix(commands): fix config opening with “start” (74f3679)
  • fix(commands): correctly handle non-apps when upgrading (f7419f6)
  • fix: make LogOutput go to Stdout not Stderr (bc10357)
  • fix: handle empty versions correctly (2287da9)
  • fix(pkg): remove correct temp dir (33189b6)
  • fix(shim): warn for unknown shim extension (622c2b4)
  • fix: skip downloads with no hash by default (69d4e35)
  • fix: use correct timeout for downloads (44e527b)
  • fix: drop unnecessary return value from GetExecutableEntries (9fd845c)
  • fix(config): remove unused option (1339971)
  • fix(commands): don’t error for valid results (87c4d6c)
  • refactor(config): rename variables/functions (f253d9d)
  • fix: use unique temp directories (a159e23)
  • refactor: use fmt.Fprintln directly (d2d54bf)
0
0
9
Open comments for this post

2h 32m 19s logged

Lots of small bug fixes and changes, I’ll just list them out:

  • feat(cmd): allow removal of multiple shims in one execution (f2fae3f)
  • fix(manifest): correctly ignore invalid shortcut entries (6a08478)
  • fix(fileops): use correct registry type (5d5d796)
  • fix(config): seed config with defaults (9dfaaff)
  • fix(cmd): use correct release sources (a2a9ba1)
  • fix(cmd): use bucket from install info (5a9109b)

I also added support for more file types being shimmed, which helps a lot with compatibility. The file types are .py, .bat, .cmd, .jar and .ps1.

0
0
15
Open comments for this post

4h 40m 33s logged

Lot of time going into this devlog, but it makes sense since I did do a lot.

I did this sweeping refactor of the entire commands module which moved around a lot of code. Essentially each command now gets it’s own directory under the commands module that represents it’s children/parents. For example commands/shim/remove/cmd.go contains code for the mocha shim remove command.

Each cmd.go contains a Command struct that has the relevant fields and functions attached to it. This structure just makes things more organized and also means adding test files will be a bit easier since functionality is now isolated.

I also sorted out the shim binary. So essentially https://github.com/ScoopInstaller/Shim offers different version of the shim binary which can be installed. Previously I hard coded the code to install cpp v0.1.0 but now users can run mocha shim binary releases to see the options and mocha shim binary setup to install their chosen binary. This also means we actually get the latest releases from GitHub.

0
0
4
Open comments for this post

3h 40m 20s logged

Finally got a bit of time to do a bit of development.

First thing I did was remove a field from install.json to match scoop. This means that mocha should be a drop in replacement for existing scoop installs.

Then I added partial support for env_set and env_add_path. The main thing I need to do to complete the feature is parse variables and replace them with the appropriate paths.

These 2 fields are some of the last manifest fields I need to support besides pre/post (un)install hooks.

0
0
4
Open comments for this post

2h 34m 40s logged

My summer break has ended so development is going to be a lot slower from now. I added mocha outdated so you can list outdated apps before upgrading them to a newer version.

Besides that I tweaked a lot of stuff related to CLI output. For example I changed search to output one table, and simply outputting exact matches at the top of that table.

I also changed a lot of messages which were using LogOutput to LogInfo so they use the correct color and output to stderr and not stdout.

0
0
4
Open comments for this post

1h 32m 53s logged

Not sure why I didn’t do this earlier, but I’ve added success messages to commands where it makes sense. Also added a success color to the config so you can change what the success color is.

I do still need to improve CLI output quite a bit, but it’s slowly getting there.

0
0
6
Open comments for this post

2h 11m 32s logged

I’m writing this one right before F1 Qualifying at Spa! Continuing with the trend of some of my recent work, I improved what table outputs look like to be a little bit more readable.

We now use proper separators in the form of Unicode Box Drawing Characters. I also made column alignment configurable, which improves legibility for some commands like mocha bucket list and mocha cache show.

I’ve attached an image of the scoop and mocha versions of bucket list so you can compare for yourself.

0
0
4
Open comments for this post

3h 28m 47s logged

I love refactoring!!!! I’ll probably end up spending another 20 hours just on refactoring because it’s so fun!!!!

This time around I wanted to refactor the code so that our commands orchestrate stuff instead of the helper functions. For example, pkg.Install would first download a package, then install it, and then link it through shims and shortcuts all by itself.

This causes issues because it means error messages become slightly worse, and it creates a class of bugs due to edge cases where we don’t necessarily want this order of orchestration. Hence I did a lot of refactoring in the pkg module.

I also ended up adding a way to skip verification of downloads when downloading, installing or updating a package through --skip-verify. It’s a useful option in situations where there is a malformed manifest or simply no hash to begin with.

0
0
2
Open comments for this post

4h 37m 37s logged

mocha now supports a user defined theme for output colors. In the process I ended up doing a lot of stuff related to the config. First thing I did was swap to fatih/color for colored output, since it handles stuff like colors in command prompt and removing color when output is piped.

Then I refactored the config module. Earlier I would pass around a MochaConfiguration object through every function. Now I use a config singleton that’s accessible from any function. Why? Because it means I don’t need to pass the object every time I want to log information. Also means I don’t need to pass mochaDir through almost every function in the codebase.

Getting user defined themes was a bit complicated because I needed a good way to handle a default theme so output doesn’t look bad if parsing fails. I handled this by only using the configured theme if every color resolves properly. Otherwise output falls back to the already loaded default theme. Due to this you still get colored output even if there are errors or warning before the configuration and theme is loaded.

0
0
4
Open comments for this post

4h 43m 17s logged

So I’ve been doing a bit of refactoring, a bit of bug fixing and a bit of optimization. Essentially just polishing mocha before I work on the next feature.

Here’s some of the stuff I did:

  • created tests for ParseRefString to validate behavior
  • cache manifest json between info calls since I/O is really slow
  • bumped dependency versions
  • refactored manifest/info.go

Besides that I fixed the uninstall flow since it was really bugged after the latest changes. Essentially mocha would uninstall apps with incorrect info. It would also try to remove shims/shortcuts for apps which don’t have any active shims/shortcuts.

I then added a bit of logging since the uninstall command didn’t give any user output for whatever reason (i forgot to earlier).

0
0
3
Open comments for this post

6h 29m 51s logged

This is going to be the equivalent of 2 devlogs since I thought I made one earlier for persists but I didn’t.


New feature! We now handle persist items in order to store data between versions. These are files which are persisted between versions of an app.

Lets take git as an example to explain why persist exists. Say you want to make sure your git config isn’t deleted every time you update. The issue with this is that the config file is saved in the version specfic directory.

To resolve this we can keep the config in $MOCHA_DIR/persist and then symlink the config to where it needs to be, which is essentially what persist tells us to do.


Since we handled persist items last time we can now implement mocha upgrade to update apps. The way scoop handles updates is by first removing anything that references the app, like shortcuts or shims.

Then we just follow the install process from scratch. This leaves the old version available in case a user wants to revert versions due to a bug, while also updating to the latest available version.

This can be seen in the video below, which shows me updating llama.cpp-hip-radeon.

0
0
4
Open comments for this post

3h 31m 48s logged

We now create shortcuts! This means any GUI apps should show up properly in the start menu, just like they do when you install with scoop. All I really had to do was a bit of orchestration since I decided to vendor in an implementation from https://github.com/jxeng/shortcut

Besides that I expanded the number of apps that are supported by implementing a bit of code that handle architecture specific bin fields, along with bin fields which store 2D arrays.

I also cleared up some of the TODO items. I swapped the junction implementation to an implementation from https://github.com/nyaosorg/go-windows-junction since we were previously shelling out to CLI. That and I added a bit more zip bomb protection

For the purposes of the video below I changed the location which shortcuts get put to my desktop. It’ll probably be configurable, and match scoop by putting shortcuts in the startup menu by default

0
0
4
Open comments for this post

3h 18m 32s logged

As I mentioned in the previous devlog I added good help information to every bit of the CLI. It’s surprisingly difficult to write good help messages which explains everything to users in a few words

I also changed the behaviour of the mocha cache clear command to not clear all cache by default. That’s now gated behind the --all flag in order to match scoop a bit more

0
0
3
Open comments for this post

1h 4m 20s logged

Typically I don’t want to make devlogs for small stuff like this, but this is something I found really cool.

So I was working on help messages for all the commands when I realized that mocha bucket list felt a bit slower than pretty much every other command.

This is because we need to shell out to git 2 times per bucket, and I had 4 buckets added. While 8 git commands might not sound like a lot, it was enough to make mocha bucket list feel slow.

So what I did is I parallelized the metadata fetching through an errgroup. Instead of fetching the metadata for each bucket in order, we fetch the metadata for all 4 buckets simultaneously.

This led to a big performance uplift. About 3 times faster than the old version of mocha, and just over 12 times faster than scoop for this operation. See the video below.

0
0
2
Open comments for this post

2h 14m 47s logged

I finished up mocha uninstall and mocha list, which means you can actually manage installed apps instead of manually deleting them.

There’s not much that goes into mocha uninstall. You just need to remove the relevant shims and app directories since the apps that mocha supports are all portable.

mocha list is similarly simple. It’s just loops over the directories in $MOCHA_DIR/apps and looks for apps along with the versions installed for each app.

0
0
3
Open comments for this post

5h 27m 45s logged

So I added support for more apps by implementing more extractors. This means in theory any apps which don’t need a pre-install or post-install should work.

To be more specific, I handle a few more properties on manifests. Those being extract_dir and innosetup, which inform how an app needs to be installed. I also implement 7zip and innounp as extractors to support more file formats which applications are distributed in.

Of course there’s still a lot of work before I consider this ready for public use. I need to create commands for some basic operations like uninstalling, updating and listing apps. I also need to handle shortcuts otherwise GUI apps can’t be accessed from the start menu.

Besides that I need to improve the user experience. As you can see in the video below mocha just sort of dumps everything to the console even if it’s not relevant. Help menus are also critical to get working properly.

0
0
3
Open comments for this post

3h 47m 2s logged

Finished up the code cleanup in commands, fileops and manifests. I did catch a few edge cases and some incorrect behavior in the process, which is why I always spend so much time reviewing code.

I did use AI to assist with code review because I think it’s an area where AI shines. AI is really good at finding small errors or inconsistencies in the codebase which I probably wouldn’t notice.

For example, it identified that the ManifestReferences argument was not a required argument for the download command, which meant no help message was displayed on incorrect usage like the other commands.

One big thing I will work on eventually is console output. Right now errors are well formatted but a lot of the time commands just run stuff without providing a lot of insight into what actions they are taking which isn’t great. Even the help menu is pretty useless right now (see the image below).

Extra context: A manifest reference is a pointer to an app (e.g. main/[email protected])

0
0
2
Open comments for this post

5h 18m 9s logged

Before working on more features and expanding the amount of apps mocha actually supports I wanted to go through the codebase and do a lot of cleanup since the codebase is quite messy. There are silly mistakes in some files and bad implementations in others.

Hence the time I spent during this period was focused on moving code to where it should be and cleaning up some edge cases, specifically related to the bucket, config and shim modules.

A good example of this is moving the code to get the active config to the config module instead of leaving it in main.go. Next up will be refactoring the commands, fileops, and manifest modules.

I don’t have much to show so I figured I would present a feature I added but didn’t show earlier: the ability to skip cache hits with the --force flag when installing or downloading an app.

Some context I forgot to add initially: I renamed the app module to manifest since I felt it was more accurate to what it actually handles scope wise.

0
0
4
Loading more…

Followers

Loading…