构建一个包管理器让我学到了什么
来自官方Zig源的包管理器,即“zig fetch”,让我感到非常烦恼。我讨厌必须先从一个URL获取项目,然后将代码复制到build.zig中,接着又没有智能提示,只能猜测我需要写什么,不需要写什么。这真是一团糟。
所以我解决了这个问题,构建了自己的包管理器zeP。
https://github.com/XerWoho/zeP
这是一个简单的包管理器和Zig版本管理器。
那么我学到了什么呢?首先,构建一个包管理器需要进行大量的规划。目前我仍处于预发布阶段,这里会有很多重大变化,但我已经做出的许多重大改动让我意识到,在承诺某件事情之前,我必须先停止编程,开始思考。
例如,我的可执行文件命名为zeP,这对Linux用户来说是个问题。他们总是必须输入带有大写P的zeP,这实在令人烦恼。
在此之前,我在zeP中有一个Zig版本管理器,在安装Zig版本或切换版本后,会更改可执行文件的路径。也就是说,每次安装或切换时都会添加一个新路径。
~/.zig-0.15.1/x86-windows/:~/.zig-0.13.0/x86-windows:~/.zig-....
可以想象,经过一段时间后,PATH变量会变得多么臃肿,而且不仅如此,这完全没有用,因为我会检查路径是否在PATH变量中,如果在,我就不会再添加它。也就是说(以上面的例子为例),zig 0.13.0将永远不会再被使用,因为它被0.15.1所覆盖。为了解决这个问题,我使用了符号链接。只在主路径~/.local/bin内,zig会在安装和切换之间进行符号链接。
符号链接对我来说非常好,因为我发现了pnpm的工作原理。pnpm使用符号链接,减少了安装、延迟和文件大小,因为有一个主文件夹包含所有文件,并且这些文件在项目之间进行链接。但是,有一个问题。如果你卸载一个包,它会删除主文件夹中的包,这意味着所有可能安装了该包的其他项目将会有一个悬空的符号链接。
再次,解决方案很简单。一个manifest.json。在这里,我们存储所有包及其链接的项目。这个文件会检查链接的项目,如果该包没有链接的项目,才会删除该包;否则,它只会解除项目的链接。
不用说,我遇到了许多需要测试的问题,并且亲自使用zeP。只有通过使用我自己的产品,我才能确定其他人可能遇到的问题。但有些人也提供了反馈,之后我修复了一些问题。
zeP有自己定制的打印结构。它接收数据,然后通过清空整个屏幕再重新打印。这是为了让我可以显示进度条等内容。然而,有用户讨厌zeP会完全占用整个屏幕。因此,现在zeP只会清除自己的行,而不会影响其他内容。
构建一个包管理器不仅需要我这边的测试,还需要社区的反馈。
查看原文
The Package manager from the official Zig source, meaning "zig fetch" was very annoying. I hated having to first fetch the project from a URL, and then copy code into the build.zig, and then have no intellisense, and just GUESS what I have to write, and what I do not have to write. It was chaos.<p>So I fixed it, by building my own package manager, zeP.
https://github.com/XerWoho/zeP<p>It is a simple package manager and Zig version manager.<p>What did I learn, though? First off, building a package manager requires INTENSIVE planning. I am currently still on pre-release, which is where big changes are to be expected, but the number of big changes I have already made has made me realize that I have to stop programming and start thinking before committing to something.<p>For example, my executable was named zeP, which is an issue for Linux users. They always had to type zeP, with the capital P, which is simply annoying.<p>Before that, I had a Zig version manager in zeP, which, after installing a Zig version, or switching to a version, changed the path to the file of the executable. Meaning it added a new path on each install or switch.<p>~/zig-0.15.1/x86-windows/:~/zig-0.13.0/x86-windows:~/zig-....<p>Some can see how bloated a PATH variable can get after a while, and not only that, it is completely useless, because I check if the path is in the PATH variable, and if it is, I do not add it. Meaning that (for the example above), zig 0.13.0 will never be used again, because it gets overshadowed by 0.15.1. To fix this, I use symlinks. Only on main path; ~/.local/bin, and within that path, zig, which is getting symlinked across installs and switches.<p>Symlinks looked very good to me, since I found out how pnpm works. Pnpm works with symlinks, reducing installs, delays, and sizes, because there is a main folder which has ALL the files, and they are getting linked across projects. But, there was a catch. If you uninstall a package, it deletes the package in the main folder, meaning all the other projects which might have that package installed will have a dangling symlink.<p>Again, the solution was simple. A manifest.json. In there, we store all the packages, with their linked projects. This will check the linked projects, and if it the package has no linked projects, only then, will it delete the package; else, it will just unlink the project.<p>Needless to say, there were a lot of issues that required testing and using zeP myself. Only by using my own product, could I determine the issues other people might have with it. But some people also gave feedback, after which I fixed a few issues.<p>zeP has its own custom printer struct. It receives data, and then re-prints it, by clearing the entire screen, and then printing again. This was done, so I had stuff like progress bars, etc. However a user hated the fact, that zeP literally hijacked your entire screen. So now, zeP only clears its OWN lines, and leaves your other stuff alone.<p>Building a package manager does not only require testing on my side, but also community feedback.