Compare commits

...

13 Commits

Author SHA1 Message Date
387c2c40aa docs: add CLAUDE.md for project guidance
- Introduced CLAUDE.md to provide comprehensive guidance on the macOS Emacs building system, including project overview, common commands, architecture details, and testing instructions.
2026-01-14 18:56:25 +00:00
527f855fbf chore(deps): add macOS SDK version 26
- Added support for macOS SDK version 26 to the list of supported SDKs.
- Reformatted flake.nix with nixfmt.
2026-01-14 18:53:56 +00:00
aafac57b1d chore(deps): update flake.lock and flake.pkgs for dependency versions
- Updated nixpkgs revision and narHash in flake.lock.
- Upgraded expat to version 2.7.3 and openssl to version 3.4.3 in flake.pkgs.
- Modified flake-package-versions command in Makefile for improved output.
2026-01-14 18:50:55 +00:00
jimehbot[bot]
4367d6b80e chore(master): release 0.6.63 (#149)
Co-authored-by: jimehbot[bot] <132453784+jimehbot[bot]@users.noreply.github.com>
2025-09-14 21:01:51 +01:00
b5ed3887c1 feat(icon): add support for Tahoe icons with --tahoe-icon-uri and --tahoe-icon-name options 2025-09-14 20:58:12 +01:00
607076a91b feat(icon): add support for custom application icons via --icon-uri option 2025-09-14 20:57:17 +01:00
1cda2cc3ff style(lint): resolve Naming/PredicateName rubocop complaint 2025-09-14 20:55:50 +01:00
jimehbot[bot]
39a4868313 chore(master): release 0.6.62 (#148)
Co-authored-by: jimehbot[bot] <132453784+jimehbot[bot]@users.noreply.github.com>
2025-09-14 12:25:30 +01:00
2086a773ae feat(deps/nix): upgrade build-time dependencies
In particular, this brings tree-sitter up to v0.25.3, enabling
tree-sitter ABI v15.
2025-09-14 12:23:27 +01:00
jimehbot[bot]
68ecce6158 chore(master): release 0.6.61 (#145)
Co-authored-by: jimehbot[bot] <132453784+jimehbot[bot]@users.noreply.github.com>
2025-08-13 01:40:23 +01:00
7aa4058128 fix(emacs-31-builds): disable fix-window-role patch after it was merged upstream 2025-08-13 01:38:46 +01:00
jimehbot[bot]
67ad73e500 chore(master): release 0.6.60 (#141)
Co-authored-by: jimehbot[bot] <132453784+jimehbot[bot]@users.noreply.github.com>
2025-06-27 22:42:03 +01:00
8ac1f946dd fix(builder/cask): correctly resolve version with build variant to release name (#140) 2025-06-27 22:40:57 +01:00
11 changed files with 433 additions and 125 deletions

View File

@@ -1,3 +1,3 @@
{ {
".": "0.6.59" ".": "0.6.63"
} }

View File

@@ -1,5 +1,34 @@
# Changelog # Changelog
## [0.6.63](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.62...v0.6.63) (2025-09-14)
### Features
* **icon:** add support for custom application icons via --icon-uri option ([607076a](https://github.com/jimeh/build-emacs-for-macos/commit/607076a91bf0f227d16c9404f01a64144290685a))
* **icon:** add support for Tahoe icons with --tahoe-icon-uri and --tahoe-icon-name options ([b5ed388](https://github.com/jimeh/build-emacs-for-macos/commit/b5ed3887c172540de4a6190072b1e15f5d5efe2c))
## [0.6.62](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.61...v0.6.62) (2025-09-14)
### Features
* **deps/nix:** upgrade build-time dependencies ([2086a77](https://github.com/jimeh/build-emacs-for-macos/commit/2086a773ae6bf5f4c2e6863d1b06a85acc082e6d))
## [0.6.61](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.60...v0.6.61) (2025-08-13)
### Bug Fixes
* **emacs-31-builds:** disable fix-window-role patch after it was merged upstream ([7aa4058](https://github.com/jimeh/build-emacs-for-macos/commit/7aa405812802abbd2b78d8c98aee7fca23a2eab2))
## [0.6.60](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.59...v0.6.60) (2025-06-27)
### Bug Fixes
* **builder/cask:** correctly resolve version with build variant to release name ([#140](https://github.com/jimeh/build-emacs-for-macos/issues/140)) ([8ac1f94](https://github.com/jimeh/build-emacs-for-macos/commit/8ac1f946dde2342fa82aff7f90d2126bdd1f0057))
## [0.6.59](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.58...v0.6.59) (2025-06-27) ## [0.6.59](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.58...v0.6.59) (2025-06-27)

80
CLAUDE.md Normal file
View File

@@ -0,0 +1,80 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with
code in this repository.
## Project Overview
macOS Emacs building system with Ruby and Go components:
- **Ruby script** (`build-emacs-for-macos`): Main build script for creating
self-contained Emacs.app bundles
- **Go CLI tool** (`emacs-builder`): Packaging, signing, notarization, and
release management
- **Dual dependency management**: Nix (preferred) or Homebrew
## Common Commands
```bash
# Environment setup (Nix preferred)
nix develop # Default macOS 11 SDK
nix develop .#macos{11-15,26} # Target specific SDK version
# Go development
make build # Build emacs-builder CLI
make test # Run tests with race detection
make lint # Run golangci-lint
make format # Format with gofumpt
# Ruby development
bundle exec rubocop # Lint (with development group)
# Build Emacs
./build-emacs-for-macos # Build from master
./build-emacs-for-macos emacs-29.4
```
## Architecture
### Ruby Build Script (`build-emacs-for-macos`)
Single-file Ruby script (~2500 lines) that:
- Downloads source tarballs from emacs-mirror/emacs on GitHub
- Configures and compiles Emacs with native-comp, tree-sitter support
- Creates self-contained .app bundles by embedding/relinking dependencies
- Uses `ruby-macho` gem for Mach-O binary manipulation (RPATH handling)
### Go CLI (`cmd/emacs-builder/`)
Uses `urfave/cli/v2` framework. Key packages in `pkg/`:
- `cli/`: Commands (plan, sign, sign-files, notarize, package, release, cask)
- `sign/`: macOS code signing via `codesign`
- `notarize/`: Apple notarization workflow via `notarytool`
- `release/`: GitHub release management
- `dmgbuild/`: DMG creation using Python dmgbuild
- `plan/`: Build plan JSON parsing and management
### Nix Environment (`flake.nix`)
- Multi-SDK support: macOS 11-15, 26 via `.#macos{11,12,13,14,15,26}`
- Excludes ncurses intentionally (links against system version for TUI)
- Sets `MACOSX_DEPLOYMENT_TARGET`, `DEVELOPER_DIR`, `NIX_LIBGCCJIT_*`
## Testing
```bash
make test # All Go tests
go test ./pkg/release/... # Single package
go test -run TestName ./pkg/... # Single test
```
Tests use `_test.go` suffix alongside source files.
## Working Directories
- `sources/`: Downloaded/extracted Emacs source (gitignored)
- `builds/`: Build outputs and .app bundles (gitignored)
- `patches/`: Emacs patches applied during build
- `bin/`: Built Go binaries (gitignored)

View File

@@ -141,10 +141,10 @@ nix-flake-update:
.SILENT: flake-package-versions .SILENT: flake-package-versions
flake-package-versions: flake-package-versions:
nix develop --command -- bash -c \ nix develop --command bash -c \
'nix derivation show \ 'nix derivation show \
$$(echo $$PATH | tr ":" "\n" | grep "/nix/store" | sort -u) \ $$(echo $$PATH | tr ":" "\n" | grep "/nix/store" | sort -u) \
| jq -r ".[].name" | sort -u' | jq -r ".derivations[].name" | sort -u'
flake.pkgs: flake.nix flake.lock flake.pkgs: flake.nix flake.lock
$(MAKE) flake-package-versions > "$@" $(MAKE) flake-package-versions > "$@"

View File

@@ -141,7 +141,7 @@ Options:
--[no-]relink-eln-files Enable/disable re-linking shared libraries in bundled *.eln files (default: enabled) --[no-]relink-eln-files Enable/disable re-linking shared libraries in bundled *.eln files (default: enabled)
--[no-]rsvg Enable/disable SVG image support via librsvg (default: enabled) --[no-]rsvg Enable/disable SVG image support via librsvg (default: enabled)
--[no-]dbus Enable/disable dbus support (default: enabled) --[no-]dbus Enable/disable dbus support (default: enabled)
--[no-]alpha-background Enable/disable experimental alpha-background patch when building Emacs 30.x - 31.x (default: disabled) --alpha-background Apply experimental alpha-background patch when building Emacs 30.x - 31.x (default: disabled)
--no-frame-refocus Apply no-frame-refocus patch when building Emacs 27.x - 31.x (default: disabled) --no-frame-refocus Apply no-frame-refocus patch when building Emacs 27.x - 31.x (default: disabled)
--no-titlebar Apply no-titlebar patch when building Emacs 27.x - 28.x (default: disabled) --no-titlebar Apply no-titlebar patch when building Emacs 27.x - 28.x (default: disabled)
--[no-]xwidgets Enable/disable XWidgets when building Emacs 27.x (default: disabled) --[no-]xwidgets Enable/disable XWidgets when building Emacs 27.x (default: disabled)
@@ -155,6 +155,9 @@ Options:
-o, --output DIR Output directory for finished builds (default: <work-dir>/builds) -o, --output DIR Output directory for finished builds (default: <work-dir>/builds)
--build-name NAME Override generated build name --build-name NAME Override generated build name
--dist-include x,y,z List of extra files to copy from Emacs source into build folder/archive (default: COPYING) --dist-include x,y,z List of extra files to copy from Emacs source into build folder/archive (default: COPYING)
--icon-uri URI Local path or URL to a .icns file to replace the default app icon
--tahoe-icon-uri URI Local path or URL to an Assets.car file for macOS 26 icons. Requires --tahoe-icon-name.
--tahoe-icon-name NAME Name of the icon in Assets.car to set as CFBundleIconName
--[no-]self-sign Enable/disable self-signing of Emacs.app (default: enabled) --[no-]self-sign Enable/disable self-signing of Emacs.app (default: enabled)
--[no-]archive Enable/disable creating *.tbz archive (default: enabled) --[no-]archive Enable/disable creating *.tbz archive (default: enabled)
--[no-]archive-keep-build-dir --[no-]archive-keep-build-dir

View File

@@ -229,6 +229,14 @@ class Build
handle_native_lisp(app) handle_native_lisp(app)
if options[:icon_uri] || options[:tahoe_icon_uri] || options[:tahoe_icon_name]
IconEmbedder.new(
app,
icon_uri: options[:icon_uri],
tahoe_icon_uri: options[:tahoe_icon_uri],
tahoe_icon_name: options[:tahoe_icon_name]
).embed
end
CLIHelperEmbedder.new(app).embed CLIHelperEmbedder.new(app).embed
CSourcesEmbedder.new(app, @source_dir).embed CSourcesEmbedder.new(app, @source_dir).embed
LibEmbedder.new( LibEmbedder.new(
@@ -1073,7 +1081,7 @@ class Build
# Enabled by default patches. # Enabled by default patches.
if (26..31).include?(effective_version) if (26..30).include?(effective_version)
p << { p << {
url: url:
'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \ 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
@@ -1081,6 +1089,19 @@ class Build
} }
end end
# The fix-window-role patch was merged into Emacs 31 on 2025-07-31 with
# commit 6e1054a40bf6df1429a2b16fdd0d7652dae4d537. Hence builds for commits
# before then need the patch from the last commit in emacs-plus before it
# was removed.
if effective_version == 31 && meta[:date] < Time.parse('2025-07-31')
p << {
url:
'https://github.com/d12frosted/homebrew-emacs-plus/raw/' \
'3e95d573d5f13aba7808193b66312b38a7c66851/' \
'patches/emacs-31/fix-window-role.patch'
}
end
if (27..31).include?(effective_version) if (27..31).include?(effective_version)
p << { p << {
url: url:
@@ -1400,6 +1421,98 @@ class CSourcesEmbedder < AbstractEmbedder
end end
end end
class IconEmbedder < AbstractEmbedder
include Helpers
def initialize(app, icon_uri: nil, tahoe_icon_uri: nil, tahoe_icon_name: nil)
super(app)
@icon_uri = icon_uri
@tahoe_icon_uri = tahoe_icon_uri
@tahoe_icon_name = tahoe_icon_name
end
def embed
handle_icns if present?(@icon_uri)
handle_tahoe if present?(@tahoe_icon_uri)
ensure
cleanup_tmpdir
end
private
def present?(val)
!val.nil? && !val.strip.empty?
end
def handle_icns
source = resolve_source(@icon_uri, '.icns', 'icon.icns')
target = File.join(resources_dir, 'Emacs.icns')
info 'Replacing application icon (Emacs.icns)...'
run_cmd('cp', '-pRL', source, target)
source
end
def handle_tahoe
fatal '--tahoe-icon-name is required with --tahoe-icon-uri' \
unless present?(@tahoe_icon_name)
source = resolve_source(@tahoe_icon_uri, '.car', 'Assets.car')
target = File.join(resources_dir, 'Assets.car')
info 'Placing Tahoe Assets.car into Resources...'
run_cmd('cp', '-pRL', source, target)
set_cf_bundle_icon_name(@tahoe_icon_name)
source
end
def set_cf_bundle_icon_name(name)
info 'Setting CFBundleIconName in Info.plist...'
info_plist = File.join(app, 'Contents', 'Info.plist')
fatal "Info.plist not found: #{info_plist}" unless File.exist?(info_plist)
# Use plutil which adds/replaces the key as needed
run_cmd(
'plutil', '-replace', 'CFBundleIconName', '-string',
name, info_plist
)
end
def resolve_source(uri, expected_ext, download_name)
file_path = if valid_url?(uri)
download_file(uri, download_name)
else
local = File.expand_path(uri)
unless File.exist?(local)
fatal "File does not exist: #{local}"
end
local
end
ext = File.extname(file_path).downcase
fatal "Unexpected file type: #{ext} (expected #{expected_ext})" \
unless ext == expected_ext
file_path
end
def tmpdir
@tmpdir ||= Dir.mktmpdir(%w[emacs-assets .tmp])
end
def download_file(url, name)
path = File.join(tmpdir, name)
info "Downloading asset from: #{url}"
run_cmd('curl', '-L#', url, '-o', path)
path
end
def cleanup_tmpdir
return unless @tmpdir
FileUtils.rm_rf(@tmpdir)
end
end
class LibEmbedder < AbstractEmbedder class LibEmbedder < AbstractEmbedder
attr_reader :lib_sources attr_reader :lib_sources
attr_reader :extra_libs attr_reader :extra_libs
@@ -1894,7 +2007,7 @@ class GccInfo
def clean_macho_binary(path) def clean_macho_binary(path)
debug "Checking for duplicate RPATHs in #{path}" debug "Checking for duplicate RPATHs in #{path}"
macho_cleaner = MachOCleaner.new(path) macho_cleaner = MachOCleaner.new(path)
return unless macho_cleaner.has_duplicate_rpaths? return unless macho_cleaner.duplicate_rpaths?
begin begin
info "Removing duplicate RPATHs from #{path}" info "Removing duplicate RPATHs from #{path}"
@@ -1958,7 +2071,7 @@ class MachOCleaner
end end
# Check if file has duplicate RPATH commands # Check if file has duplicate RPATH commands
def has_duplicate_rpaths? def duplicate_rpaths?
count_duplicate_rpaths(macho_object).positive? count_duplicate_rpaths(macho_object).positive?
end end
@@ -2088,6 +2201,14 @@ class CLIOptions
def parse!(args) def parse!(args)
parser.parse!(args) parser.parse!(args)
if options[:tahoe_icon_uri] &&
(
options[:tahoe_icon_name].nil? ||
options[:tahoe_icon_name].strip.empty?
)
fatal '--tahoe-icon-name is required when --tahoe-icon-uri is specified'
end
rescue OptionParser::InvalidOption => e rescue OptionParser::InvalidOption => e
fatal e.message fatal e.message
end end
@@ -2114,6 +2235,9 @@ class CLIOptions
github_src_repo: nil, github_src_repo: nil,
github_auth: true, github_auth: true,
dist_include: ['COPYING', 'configure_output.txt'], dist_include: ['COPYING', 'configure_output.txt'],
icon_uri: nil,
tahoe_icon_uri: nil,
tahoe_icon_name: nil,
self_sign: true, self_sign: true,
archive: true, archive: true,
archive_keep: false, archive_keep: false,
@@ -2310,6 +2434,22 @@ class CLIOptions
'folder/archive (default: COPYING)' 'folder/archive (default: COPYING)'
) { |v| options[:dist_include] = v } ) { |v| options[:dist_include] = v }
opts.on(
'--icon-uri URI',
'Local path or URL to a .icns file to replace the default app icon'
) { |v| options[:icon_uri] = v }
opts.on(
'--tahoe-icon-uri URI',
'Local path or URL to an Assets.car file for macOS 26 icons. ' \
'Requires --tahoe-icon-name.'
) { |v| options[:tahoe_icon_uri] = v }
opts.on(
'--tahoe-icon-name NAME',
'Name of the icon in Assets.car to set as CFBundleIconName'
) { |v| options[:tahoe_icon_name] = v }
opts.on( opts.on(
'--[no-]self-sign', '--[no-]self-sign',
'Enable/disable self-signing of Emacs.app (default: enabled)' 'Enable/disable self-signing of Emacs.app (default: enabled)'
@@ -2359,7 +2499,7 @@ if __FILE__ == $PROGRAM_NAME
elsif cli_options[:clean_macho_binary] elsif cli_options[:clean_macho_binary]
macho_cleaner = MachOCleaner.new(cli_options[:clean_macho_binary]) macho_cleaner = MachOCleaner.new(cli_options[:clean_macho_binary])
if macho_cleaner.has_duplicate_rpaths? if macho_cleaner.duplicate_rpaths?
build.info 'Removing duplicate RPATHs from ' \ build.info 'Removing duplicate RPATHs from ' \
"#{cli_options[:clean_macho_binary]}..." "#{cli_options[:clean_macho_binary]}..."
macho_cleaner.clean! macho_cleaner.clean!

8
flake.lock generated
View File

@@ -20,16 +20,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1750646418, "lastModified": 1767313136,
"narHash": "sha256-4UAN+W0Lp4xnUiHYXUXAPX18t+bn6c4Btry2RqM9JHY=", "narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "1f426f65ac4e6bf808923eb6f8b8c2bfba3d18c5", "rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-24.11", "ref": "nixos-25.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }

164
flake.nix
View File

@@ -2,88 +2,104 @@
description = "Development environment flake"; description = "Development environment flake";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = { self, nixpkgs, flake-utils }: outputs =
flake-utils.lib.eachDefaultSystem (system: {
self,
nixpkgs,
flake-utils,
}:
flake-utils.lib.eachDefaultSystem (
system:
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
# List of supported macOS SDK versions. # List of supported macOS SDK versions.
sdk_versions = [ "11" "12" "13" "14" "15" ]; sdk_versions = [
"11"
"12"
"13"
"14"
"15"
"26"
];
default_sdk_version = "11"; default_sdk_version = "11";
mkDevShell = { macos_version ? default_sdk_version }: mkDevShell =
{
macos_version ? default_sdk_version,
}:
let let
apple_sdk = pkgs.${"apple-sdk_${macos_version}"}; apple_sdk = pkgs.${"apple-sdk_${macos_version}"};
in in
pkgs.mkShell { pkgs.mkShell {
# Package list specifically excludes ncurses, so that we link # Package list specifically excludes ncurses, so that we link
# against the system version of ncurses. This ensures emacs' TUI # against the system version of ncurses. This ensures emacs' TUI
# works out of the box without the user having to manually set # works out of the box without the user having to manually set
# TERMINFO in the shell before launching emacs. # TERMINFO in the shell before launching emacs.
packages = with pkgs; [ packages = with pkgs; [
apple_sdk apple_sdk
autoconf autoconf
bash bash
cairo cairo
clang clang
coreutils coreutils
curl curl
darwin.DarwinTools # sw_vers darwin.DarwinTools # sw_vers
dbus dbus
expat expat
findutils findutils
gcc gcc
gettext gettext
giflib giflib
git git
gmp gmp
gnumake gnumake
gnupatch gnupatch
gnused gnused
gnutar gnutar
gnutls gnutls
harfbuzz harfbuzz
jansson jansson
jq jq
lcms2 lcms2
libffi libffi
libgccjit libgccjit
libiconv libiconv
libjpeg libjpeg
libpng libpng
librsvg librsvg
libtasn1 libtasn1
libunistring libunistring
libwebp libwebp
libxml2 libxml2
mailutils mailutils
nettle nettle
pkg-config pkg-config
python3 python313Packages.dmgbuild
rsync rsync
ruby_3_3 ruby
sqlite sqlite
texinfo texinfo
time time
tree-sitter tree-sitter
which which
xcbuild xcbuild
zlib zlib
]; ];
shellHook = '' shellHook = ''
export CC=clang export CC=clang
export MACOSX_DEPLOYMENT_TARGET="${macos_version}.0" export MACOSX_DEPLOYMENT_TARGET="${macos_version}.0"
export DEVELOPER_DIR="${apple_sdk}" export DEVELOPER_DIR="${apple_sdk}"
export NIX_LIBGCCJIT_VERSION="${pkgs.libgccjit.version}" export NIX_LIBGCCJIT_VERSION="${pkgs.libgccjit.version}"
export NIX_LIBGCCJIT_ROOT="${pkgs.libgccjit.outPath}" export NIX_LIBGCCJIT_ROOT="${pkgs.libgccjit.outPath}"
export BUNDLE_WITHOUT=development export BUNDLE_WITHOUT=development
''; '';
}; };
# Generate an attrset of shells for each macOS SDK version. # Generate an attrset of shells for each macOS SDK version.
versionShells = builtins.listToAttrs ( versionShells = builtins.listToAttrs (
@@ -93,10 +109,10 @@
}) sdk_versions }) sdk_versions
); );
in in
{ {
devShells = versionShells // { devShells = versionShells // {
default = mkDevShell {}; default = mkDevShell { };
}; };
} }
); );
} }

View File

@@ -1,67 +1,72 @@
DarwinTools-1 DarwinTools-1
autoconf-2.72 autoconf-2.72
bash-5.2p37 bash-5.2p37
bash-interactive-5.2p37
brotli-1.1.0 brotli-1.1.0
bzip2-1.0.8 bzip2-1.0.8
cairo-1.18.2 cairo-1.18.2
cctools-binutils-darwin-1010.6 cctools-binutils-darwin-1010.6
cctools-binutils-darwin-wrapper-1010.6 cctools-binutils-darwin-wrapper-1010.6
clang-16.0.6 clang-19.1.7
clang-wrapper-16.0.6 clang-wrapper-19.1.7
coreutils-9.5 coreutils-9.7
curl-8.12.1 curl-8.14.1
dbus-1.14.10 dbus-1.14.10
diffutils-3.10 diffutils-3.12
expat-2.7.1 expat-2.7.3
file-5.45 file-5.45
findutils-4.10.0 findutils-4.10.0
fontconfig-2.15.0 fontconfig-2.16.0
freetype-2.13.3 freetype-2.13.3
gawk-5.3.1 gawk-5.3.2
gcc-13.3.0 gcc-14.3.0
gcc-wrapper-13.3.0 gcc-wrapper-14.3.0
gdk-pixbuf-2.42.12 gdk-pixbuf-2.42.12
gettext-0.21.1 gettext-0.22.5
giflib-5.2.2 giflib-5.2.2
git-2.47.2 git-2.50.1
glib-2.82.1 glib-2.84.3
gnugrep-3.11 gnugrep-3.11
gnumake-4.4.1 gnumake-4.4.1
gnused-4.9 gnused-4.9
gnutar-1.35 gnutar-1.35
gnutls-3.8.6 gnutls-3.8.9
graphite2-1.3.14 graphite2-1.3.14
gzip-1.13 gzip-1.14
harfbuzz-10.0.1 harfbuzz-10.2.0
jq-1.7.1 jq-1.7.1
krb5-1.21.3 krb5-1.21.3
lcms2-2.16 lcms2-2.17
libdeflate-1.22 libdeflate-1.23
libgccjit-13.3.0 libgccjit-14.3.0
libiconv-1.17
libiconv-109 libiconv-109
libidn2-2.3.7 libidn2-2.3.8
libjpeg-turbo-3.0.4 libjpeg-turbo-3.0.4
libpng-apng-1.6.43 libpng-apng-1.6.46
libpsl-0.21.5 libpsl-0.21.5
librsvg-2.58.3 librsvg-2.60.0
libtasn1-4.20.0 libtasn1-4.20.0
libtiff-4.7.0 libtiff-4.7.0
libwebp-1.4.0 libwebp-1.5.0
libxml2-2.13.8 libxml2-2.13.8
mailutils-3.17 mailutils-3.18
nettle-3.10 nettle-3.10.1
nghttp2-1.64.0 nghttp2-1.65.0
openssl-3.3.3 openssl-3.4.3
patch-2.7.6 patch-2.7.6
pkg-config-wrapper-0.29.2 pkg-config-wrapper-0.29.2
python3-3.12.8 python3-3.13.5
python3.13-dmgbuild-1.6.2
python3.13-ds-store-1.3.1
python3.13-mac-alias-2.2.2
rsync-3.4.1 rsync-3.4.1
ruby-3.3.8 ruby-3.3.9
sqlite-3.46.1 sqlite-3.48.0
texinfo-7.1.1 texinfo-7.2
time-1.9 time-1.9
tree-sitter-0.24.6 tree-sitter-0.25.3
which-2.21 which-2.23
xcbuild-0.1.1-unstable-2019-11-20 xcbuild-0.1.1-unstable-2019-11-20
xz-5.6.3 xz-5.8.1
zstd-1.5.6 zstd-1.5.7

View File

@@ -4,7 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"regexp" "regexp"
"strings"
) )
// Errors // Errors
@@ -18,8 +17,9 @@ var (
) )
var ( var (
stableVersion = regexp.MustCompile(`^\d+\.\d+(?:[a-z]+)?$`) stableVersion = regexp.MustCompile(`^\d+\.\d+(?:[a-z]+)?(-\d+)?$`)
stableGitRef = regexp.MustCompile(`^emacs-(\d+\.\d+(?:[a-z]+)?)$`) pretestVersion = regexp.MustCompile(`-pretest(-\d+)?$`)
stableGitRef = regexp.MustCompile(`^emacs-(\d+\.\d+(?:[a-z]+)?)$`)
) )
func VersionToName(version string) (string, error) { func VersionToName(version string) (string, error) {
@@ -28,7 +28,7 @@ func VersionToName(version string) (string, error) {
} }
if stableVersion.MatchString(version) || if stableVersion.MatchString(version) ||
strings.HasSuffix(version, "-pretest") { pretestVersion.MatchString(version) {
return "Emacs-" + version, nil return "Emacs-" + version, nil
} }

View File

@@ -30,6 +30,27 @@ func TestVersionToName(t *testing.T) {
}, },
want: "Emacs.2021-07-01.1b88404.master", want: "Emacs.2021-07-01.1b88404.master",
}, },
{
name: "nightly with variant",
args: args{
version: "2021-07-01.1b88404.master-1",
},
want: "Emacs.2021-07-01.1b88404.master-1",
},
{
name: "pretest",
args: args{
version: "30.0.93-pretest",
},
want: "Emacs-30.0.93-pretest",
},
{
name: "pretest with variant",
args: args{
version: "30.0.93-pretest-1",
},
want: "Emacs-30.0.93-pretest-1",
},
{ {
name: "stable", name: "stable",
args: args{ args: args{
@@ -44,6 +65,20 @@ func TestVersionToName(t *testing.T) {
}, },
want: "Emacs-23.3b", want: "Emacs-23.3b",
}, },
{
name: "stable with variant",
args: args{
version: "23.3-1",
},
want: "Emacs-23.3-1",
},
{
name: "stable with letter and variant",
args: args{
version: "23.3b-1",
},
want: "Emacs-23.3b-1",
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {