uv:用 Rust 寫的 Python Packaging 替代方案

社群好幾個地方都有提到的「uv: Python packaging in Rust」這個,文章開頭的說明有快速說明目標是 pip 的 drop-in replacement:

TL;DR: uv is an extremely fast Python package installer and resolver, written in Rust, and designed as a drop-in replacement for pip and pip-tools workflows.

這跟「Ruff:用 Rust 寫的 Python Linter」都是 Astral 下的專案,主打用 Rust 改善速度的專案。

馬上想到的是 package resolver,這指的是依照每個套件指定的相依條件,找出符合所有條件的版本組合。

這在各個語言的套件系統上都是痛點,而在「Dependency hell is NP-complete」這篇就有指出這是 NP-complete

這是因為 3SAT 問題可以 PTIME 轉成 package resolver 問題 (於是就 NP-hard 了),再加上有 PTIME 的驗證,就變成 NP-complete 了。

但看說明應該是不只這個部分,包括了一些 i/o 類操作的改善。

除了速度以外,uv 也提供了讓測試更方便的功能,像是在計算相容版本時,預設的演算法是儘量都裝最新版,但你可以指定要儘量裝最舊的版本,這樣對於相容性測試頗有用的:

But by passing --resolution=lowest, library authors can test their packages against the lowest-compatible version of their dependencies. (This is similar to Go's Minimal version selection.)

這個工具的出現也是頗有幫助,我記得寫 Python 專案時隨便引入個 Django,再多拉幾個套件,跑起 package resolver 就要花不少時間了,可以想像中大型專案在這塊的痛點...

另外剛剛回去看了 ruff,從去年四月 500+ 條規則增加到 700+ 條了,在發表受到注目後應該補了不少社群常用到的規則,說不定新專案可以無痛跳進去了,去年的時候試著用,有發現常見的規則還沒有支援...

Ubuntu 的 Phased Update

Ubuntu 22.04 上面常常會遇到跑 apt upgrade 時系統跟你說有些 package 不打算升級:

$ sudo apt upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages have been kept back:
  python3-distupgrade ubuntu-release-upgrader-core ubuntu-release-upgrader-gtk
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.

以往遇到這種情況,如果確定要裝就是開 dist-upgrade 下去,但會發現也還是不為所動:

$ sudo apt full-upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages have been kept back:
  python3-distupgrade ubuntu-release-upgrader-core ubuntu-release-upgrader-gtk
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.

這個可能是遇到 PhasedUpdates,這個設計是在最後一關推出去的階段,一次不要更新 100% 的機器。

可以從 apt policy 看到現在的比率是 20%:(這是我已經升級上去的樣子)

$ apt policy python3-distupgrade
python3-distupgrade:
  Installed: 1:22.04.18
  Candidate: 1:22.04.18
  Version table:
 *** 1:22.04.18 500 (phased 20%)
        500 http://tw.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
        500 http://tw.archive.ubuntu.com/ubuntu jammy-updates/main i386 Packages
        100 /var/lib/dpkg/status
     1:22.04.10 500
        500 http://tw.archive.ubuntu.com/ubuntu jammy/main amd64 Packages
        500 http://tw.archive.ubuntu.com/ubuntu jammy/main i386 Packages

而對於 LTS 的使用者,這個功能在 APT 的支援是從 Ubuntu 22.04 開始,以前只有桌面的 Update Manager 才有支援,所以不太會遇到:

Up to Focal (20.04), Update Manager is the only package manager that supports phased updates (reference). Any other update mechanism installs all updates regardless of the Phased-Update-Percentage.

(話說 wiki 頁上面可以看到有「User stories」這段,用 User story 的格式把這個功能的目的描述出來了)

所以一般人可以忽略掉,而對於有意願想要幫忙測試的人,也可以透過設定蓋過 Phased Updates 的比例設定...

Gentoo 宣佈支援 binary package

Hacker News 上看到「Gentoo goes Binary (gentoo.org)」這篇,原文在「Gentoo goes Binary!」這。

Gentooportage 知名,這點在維基百科條目開頭就有提出來:

Gentoo Linux (pronounced /ˈdʒɛntuː/ JEN-too[3]) is a Linux distribution built using the Portage package management system. Unlike a binary software distribution, the source code is compiled locally according to the user's preferences and is often optimized for the specific type of computer.

這算是 Gentoo 的特色,不過即使 Gentoo 超愛 source package,也還是支援 binary package 安裝,但以前只提供重點套件,這包括了像是 Linux kernel 以及 gcc 這種套件,總是要有這些東西才能開始編軟體。

而這次公告宣佈要全面支援 binary package 算是個大轉變:

To speed up working with slow hardware and for overall convenience, we’re now also offering binary packages for download and direct installation!

目前 binary package 的主力會在 amd64 與 arm64 平台,然後提到這會對 mirror site 有額外的空間需求:

For most architectures, this is limited to the core system and weekly updates - not so for amd64 and arm64 however. There we’ve got a stunning >20 GByte of packages on our mirrors, from LibreOffice to KDE Plasma and from Gnome to Docker. Gentoo stable, updated daily.

從文末的圖也可以看到「the amount of binary package data in GByte for each architecture」得資訊:

想得到的客群大概是兩種,第一類是對於想用 Gentoo 看看的人來說會更好入手,尤其是手上是 Raspberry Pi 這些 CPU 不快的 SBC 會方便不少...

另外一種是不太在意效能,但是對某些 package 來說有高度客製化需求的人,會希望自己編這些 package 的人,透過 portage 自己調整。

查詢 Debian 與 Ubuntu 官方的 apt repository 的版本資訊

因為在寫「Python 3 的支援週期」這篇時需要查不同作業系統版本下的 python3-minimal 版本資訊,一開始是到 packages.ubuntu.com 上查,但上面只列出了目前還有支援的作業系統的套件。

所以就到 Ask Ubuntu 上面問:「How to search package information on unsupported Ubuntu distribution」。

看起來有兩個方法可以拉到歷史資料,一個是 devscripts 裡面的 rmadison,直接帶入要查的套件名稱就可以了:

$ rmadison python3-minimal

另外一個是到 https://ubuntu-archive-team.ubuntu.com/madison.cgi 這邊查,這個位置也是 rmadison 預設的 backend,資料應該是一樣的。

而加上 -u debian 可以改查 Debian 這邊的資訊,用 -h 可以看到還有那些 alias 可以用。

目前 Ubuntu 這邊可以查到最舊的版本是 trusty (14.04),如果要更舊的版本資訊,需要去 launchpad.net 上面翻,像是 https://launchpad.net/ubuntu/precise/+package/python3-minimal 這個。

Tailscale 放鬆免費版的使用限制,以及商業版的計算方式

昨天在 Hacker News 上注意到的:「Changes to Tailscale Pricing and Plans (tailscale.com)」,Tailscale 宣佈了新的免費與收費方式 (直接叫做 Pricing v3):「Pricing v3, plans, packages, and debugging」。

這次有許多改變,首先是免費版本來只能一個使用者使用,現在變成三個使用者可以在同一個 tailnet 裡面,這對於超級早期的 startup 方便不少,另外家庭用戶也可以受益。

另外一個是擴大「免費」的定義,本來的「免費」只有在完全免費的方案裡面用,一個人是免費,但五個人會收五個人的費用;現在變成「既然在 Pricing v3 我說三個人以下免費,那五個人的方案裡面還是有三個免費的名額,我就只收額外的兩個人的費用」,而且只有 active user 才會收:

That is, if you have a 5-person team at work, the first three are still free. You’d pay for only the 2 additional users (and only if they’re active, more on that below).

然後是拔掉限制 (包括「No more limits on subnet routers」與「No more limits on admin accounts」),以及放鬆限制 (包括「More free nodes, and twice as many nodes per user」)。

所以看起來 Tailscale 現在的策略是成長,趁這波調價時做了一波 PR...

由 pnpm 做出來的效能比較:npm、yarn 以及 pnpm

找資料的時候看到 pnpm 有在做幾個常見的 javascript package manager 的比較:「Benchmarks of JavaScript Package Managers」。

裡面測了九個項目,其中前八個剛好就是 cache 的有無、lockfile 的有無以及 node_modules 的有無,這三者的組合剛好八個,最後一個是測 update 的速度。

pnpm 因為用了 hard link,我先跳過去,只先關注 npmyarn 的差異。

其中幾個比較重要的項目是 (由最重要開始列):

  • with cache, with lockfile, with node_modules:這個會是一般開發的情境。
  • update:套件有更新時的時間。
  • with lockfile:這個會是第一次 clone 下來後的環境,以及 CI 的環境。

在一般開發環境下,npm 比 yarn 快一些,這點讓我比較意外,我知道 npm 這幾年一直有在改善效率,但沒想到會在 benchmark 下反超,這個是以前 yarn 很大的宣傳點,現在已經不見了。

第二個是 update (upgrade) 的部份,這邊 yarn 比 npm 快一些。

第三個因為是 CI 環境,或是第一次 clone 時的環境,慢通常可以被接受,不要差太多就好,而這邊 npm 比 yarn 快一些。

但不管是哪個,差距都不像以前那麼大了,就效率上來說,官方的 npm 已經沒有太明顯的缺點,因為效率的差異而去選擇 yarn 的理由已經不存在了。

用 fpm 這個工具包 .deb 安裝

先前在「Using Cloudflare R2 as an apt/yum repository」這邊看到的工具,其中一個是 fpm,可以快速包裝成各種套件格式 (符不符合 community standard 就是另外一回事晴了)。

在「deb - Debian package format」這邊就有提到像是之前 HashiCorp 都只有丟 binary 出來時,要怎麼打包。

先抓 binary zip 檔下來,然後直接用 fpm 指定版號與要丟的 prefix,他就幫你包起來:

$ wget https://releases.hashicorp.com/terraform/1.0.10/terraform_1.0.10_linux_amd64.zip
$ fpm -s zip -t deb --prefix /usr/bin -n terraform -v 1.0.10 terraform_1.0.10_linux_amd64.zip

生出來的 terraform_1.0.10_amd64.deb 就可以直接 apt install 或是 dpkg -i 裝進去。

看起來可以是個快速先解決問題的工具,之後遇到沒有提供 apt repository 的套件可以用這個方式先打包起來裝,後續移除也比較簡單,不用靠文件來記錄一堆細節...

Gitea 1.17.0 支援 Package Registry

看到「Gitea 1.17.0 is released」這個,Gitea 1.17.0 開始提供 Package Registry 的功能,支援的包括了:

  • Composer (PHP)
  • Conan (C++)
  • Container
  • Generic
  • Helm
  • Maven (Java)
  • npm (JavaScript)
  • NuGet (.NET)
  • PyPI (Python)
  • RubyGems (Ruby)

基本上常見的都有支援?相比於 GitLabPackage Registry 是少了 Debian 這個,其他的看起來都有...

不過少這個好像剛好是我用的到的...

把 Snap 包裝成 Flatpak 格式的工具

前幾天看到「unsnap」這個工具,可以把 Snap 套件轉成 Flatpak 套件,不過裡面有提到目前軟體的成熟度還沒有很高:

Let's say it's "Pre-alpha", as in "It kinda works on my computer".

但看起來會是個可以玩看看的東西,目前 Flatpak 的市場份額的確是愈吃愈多...

HashiCorp 家的軟體看起來都支援 APT repository 了

以前 HashiCorp 家的軟體大多都是自己下載 binary 後放到 /usr/bin 或是 /usr/local/bin 下使用,剛剛翻了一下 NomadVault,看起來都支援 APT repository 了:「https://apt.releases.hashicorp.com」;另外也有 RPM repository:「https://rpm.releases.hashicorp.com」。

這樣下個禮拜分享會的投影片也要改一改了...

另外看了一下架構,從錯誤訊息觀察,看起來後面是 Amazon S3,前面是 Fastly 的 CDN。