Compare commits

..

25 Commits

Author SHA1 Message Date
d476fd33ec chore(release): 0.6.27 2021-12-05 12:57:03 +00:00
baa5930467 Merge pull request #63 from jimeh/add-pretest-build-support
feat(plan): add support for pretest and release candidate builds
2021-12-05 12:54:33 +00:00
743b10c751 feat(plan): add support for pretest and release candidate builds
Add support for naming release and builds accordingly when given a git
ref for a pretest (90 or above patch number) or release
candidate ("-rcX" at the end of the tag).
2021-12-05 12:52:08 +00:00
59f1bcd3e8 chore(release): 0.6.26 2021-11-27 05:01:57 +00:00
e767e284b7 Merge pull request #62 from jimeh/improve-shared-library-embedding 2021-11-27 05:01:16 +00:00
8129a2e93b docs(readme): update Status section, and minor tweaks 2021-11-27 04:58:54 +00:00
4ae288cae3 feat(build): re-link eln files by default again
This reverts commit d338c136db.

Thanks to using relinking with @rpath, paths are shorting leaving enough
room in all *.eln files to be signed.
2021-11-27 04:25:03 +00:00
3bd78d130a feat(native-comp): no longer require gcc homebrew formula
This finally makes Emacs.app with native-comp fully self-contained, no
longer requiring the GCC Homebrew formula to be installed when
loading *.eln files that link against
/usr/local/lib/gcc/11/libgcc_s.1.dylib.

By adding the signing entitlement
com.apple.security.cs.allow-dyld-environment-variables, which allows
dynamic library loading to be controlled via DYLD_* environment
variables. It seems the lack of this was preventing Emacs from loading
the bundled libgcc_s.1.dylib file from Contents/Frameworks.

Fixes #53
2021-11-27 04:01:23 +00:00
fb5362ce18 fix(embed): relink shared libraries with @rpath instead of @executable_path
This allows much shorter shared library link paths within *.eln files
compared to when using @executable_path, which leaves enough space in
them to sign all *.eln files, while directly having them linked against
the embedded copy of GCC shared libraries.
2021-11-27 03:47:43 +00:00
1a34a9504a chore(release): 0.6.25 2021-11-25 23:38:52 +00:00
8513521d29 Merge pull request #61 from jimeh/refactor-file-operations 2021-11-25 23:36:55 +00:00
88bbefadc6 refactor(embed): use cp, mv, and chmod shell commands instead of FileUtils
It seems like Ruby's FileUtils.cp_r method especially was messing with
some file attributes, causing Emacs to print details about loading
various elisp files on startup. While when Emacs.app is copied into the
output build directory using "cp -a" instead of FileUtils.cp_r it does
not exhibit this behavior.
2021-11-25 20:14:16 +00:00
f1bf1d93b8 chore(release): 0.6.24 2021-11-24 21:42:52 +00:00
8a467b0d43 fix(embedding): embedding GCC fails when paths do not require sanitizing
It seems homebrew bottle of GCC for macOS Monterey (12.0) have changed their
directory structure slightly, which caused an issue were we were trying
to rename a specific directory to the same name it already had.

This behavior is still required as it looks like GCC on macOS
Catalina (10.15), the GCC homebrew bottle still uses the old directory
structure.
2021-11-24 21:39:03 +00:00
9c29f721b4 chore(release): 0.6.23 2021-11-10 22:19:28 +00:00
4ac71ddf39 docs(readme): update usage section with latest help text 2021-11-10 22:19:06 +00:00
d338c136db fix(build): do not re-link eln files by default
Relinking is currently failing for some of the *.eln files. See #60 for
details of the error.

Long-term plan is to investigate native-comp's compilation options to
hopefully resolve this issue.
2021-11-10 22:11:13 +00:00
d054a17fc7 chore(release): 0.6.22 2021-11-10 01:56:19 +00:00
4030ceb9ca feat(patch): add support for posix-spawn patch from emacs-plus 2021-11-10 01:55:38 +00:00
ad1a7dd62c chore(release): 0.6.21 2021-10-27 21:45:43 +01:00
665e6addec Merge pull request #59 from jimeh/improve-native-comp-patch 2021-10-27 21:42:05 +01:00
7f2aba0e4e chore(builder): add hidden sign-files command for testing purposes
Useful when needing to sign singular files with same ease of signing a
Emacs.app bundle.
2021-10-27 21:38:29 +01:00
be326b22aa refactor(native-comp): improve native-comp env setup patch
Instead of patching emacs sources before building Emacs, we can use
site-start.el instead for a much cleaner way of setting LIBRARY_PATH
before the user config is loaded.
2021-10-27 21:38:29 +01:00
ef4f2ad930 refactor: use site-start.el instead of abusing subdirs.el
Set source-directory in site-start.el instead of subdirs.el which we
were basically abusing to execute Elisp before the user config is
loaded.
2021-10-27 21:38:28 +01:00
2293c87fc9 refactor(build): turn add_cli_helper function into a embedder class 2021-10-27 03:12:30 +01:00
17 changed files with 867 additions and 210 deletions

View File

@@ -2,6 +2,51 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.6.27](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.26...v0.6.27) (2021-12-05)
### Features
* **plan:** add support for pretest and release candidate builds ([743b10c](https://github.com/jimeh/build-emacs-for-macos/commit/743b10c751e146ec7569f39a475c20a0489955f4))
### [0.6.26](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.25...v0.6.26) (2021-11-27)
### Features
* **build:** re-link eln files by default again ([4ae288c](https://github.com/jimeh/build-emacs-for-macos/commit/4ae288cae34c5e1d291dad7b6b654fe37c4a221f))
* **native-comp:** no longer require gcc homebrew formula ([3bd78d1](https://github.com/jimeh/build-emacs-for-macos/commit/3bd78d130a5419a6530a7d30e271569e501870fb)), closes [#53](https://github.com/jimeh/build-emacs-for-macos/issues/53)
### Bug Fixes
* **embed:** relink shared libraries with [@rpath](https://github.com/rpath) instead of [@executable](https://github.com/executable)_path ([fb5362c](https://github.com/jimeh/build-emacs-for-macos/commit/fb5362ce183ce43e52afcc0fc721cf2145f9c85b))
### [0.6.25](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.24...v0.6.25) (2021-11-25)
### [0.6.24](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.23...v0.6.24) (2021-11-24)
### Bug Fixes
* **embedding:** embedding GCC fails when paths do not require sanitizing ([8a467b0](https://github.com/jimeh/build-emacs-for-macos/commit/8a467b0d43140f6956d53c27e2319ae1b572868c))
### [0.6.23](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.22...v0.6.23) (2021-11-10)
### Bug Fixes
* **build:** do not re-link eln files by default ([d338c13](https://github.com/jimeh/build-emacs-for-macos/commit/d338c136db8acc4378154cf66ed7db5462787602)), closes [#60](https://github.com/jimeh/build-emacs-for-macos/issues/60)
### [0.6.22](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.21...v0.6.22) (2021-11-10)
### Features
* **patch:** add support for posix-spawn patch from emacs-plus ([4030ceb](https://github.com/jimeh/build-emacs-for-macos/commit/4030ceb9cab6749af3c28161ac97caec90a8aed0))
### [0.6.21](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.20...v0.6.21) (2021-10-27)
### [0.6.20](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.19...v0.6.20) (2021-10-23)

View File

@@ -17,21 +17,10 @@ Use this script at your own risk.
built from the `master` branch. This script allows you to choose any branch,
tag, or git ref you want.
## Status
## Binary Builds
As of writing (2021-04-25) it works for me on my machine. Your luck may vary.
I have successfully built:
- `emacs-27.1` release git tag
- `master` branch (Emacs 28.x)
- `feature/native-comp` branch (Emacs 28.x)
For reference, my machine is:
- 13-inch MacBook Pro (2020), 10th-gen 2.3 GHz Quad-Core Intel Core i7 (4c/8t)
- macOS Big Sur 11.2.3 (20D91)
- Xcode 12.4 (12D4e)
Nightly and stable binary builds produced with this build script are available
from [jimeh/emacs-builds](https://github.com/jimeh/emacs-builds).
## Limitations
@@ -41,14 +30,9 @@ The build produced does have some limitations:
application will be that of the machine it was built on.
- The minimum required macOS version of the built application will be the same
as that of the machine it was built on.
- The application is not signed, so running it on machines other than the one
that built the application will yield warnings. If you want to make a signed
Emacs.app, google is you friend for finding signing instructions.
## Binary Builds
Nightly and stable binary builds produced with this build script are available
from [jimeh/emacs-builds](https://github.com/jimeh/emacs-builds).
- The application is not signed automatically, but the CLI tool used to sign the
nightly builds is available. Run `go run ./cmd/emacs-builder package --help`
for details. More detailed instructions will come soon.
## Requirements
@@ -66,6 +50,26 @@ from [jimeh/emacs-builds](https://github.com/jimeh/emacs-builds).
brew install ruby
```
## Status
As of writing (2021-11-27) it works for me on my machine and for the nightly
builds in [jimeh/emacs-builds](https://github.com/jimeh/emacs-builds). Your luck
may vary.
I have successfully built:
- `emacs-28` release branch
- `master` branch (Emacs 29.x)
For reference, my machine is:
- 13-inch MacBook Pro (2020), 10th-gen 2.3 GHz Quad-Core Intel Core i7 (4c/8t)
- macOS Monterey 12.0.1 (21A559)
- Xcode 13.1 (13A1030d)
Nightly builds are built with GitHub Actions on GitHub-hosted runners, using
`macos-10.15`.
## Usage
```
@@ -81,8 +85,10 @@ Options:
--[no-]native-comp Enable/disable native-comp (default: enabled if supported)
--[no-]native-march Enable/disable -march=native CFLAG(default: disabled)
--[no-]native-full-aot Enable/disable NATIVE_FULL_AOT / Ahead of Time compilation (default: disabled)
--[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-titlebar Apply no-titlebar patch (default: disabled)
--posix-spawn Apply posix-spawn patch (default: disabled)
--no-frame-refocus Apply no-frame-refocus patch (default: disabled)
--[no-]github-auth Make authenticated GitHub API requests if GITHUB_TOKEN environment variable is set.(default: enabled)
--work-dir DIR Specify a working directory where tarballs, sources, and builds will be stored and worked with
@@ -90,7 +96,8 @@ Options:
--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)
--[no-]archive Enable/disable creating *.tbz archive (default: enabled)
--[no-]archive-keep Enable/disable keeping source folder for archive (default: disabled)
--[no-]archive-keep-build-dir
Enable/disable keeping source folder for archive (default: disabled)
--plan FILE Follow given plan file, instead of using given git ref/sha
```

View File

@@ -26,7 +26,7 @@ module Output
if newline
warn "==> #{msg}"
else
STDERR.print "==> #{msg}"
$stderr.print "==> #{msg}"
end
end
@@ -35,6 +35,19 @@ module Output
end
end
module System
include Output
def run_cmd(*args)
out("CMD: #{args.join(' ')}")
cmd(*args)
end
def cmd(*args)
system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}")
end
end
class OS
def self.version
@version ||= OSVersion.new
@@ -71,6 +84,7 @@ end
class Build
include Output
include System
EMACS_MIRROR_REPO = 'emacs-mirror/emacs'
DOWNLOAD_URL = 'https://github.com/emacs-mirror/emacs/tarball/%s'
@@ -105,8 +119,8 @@ class Build
build_dir, app = create_build_dir(app)
handle_native_lisp(app)
add_cli_helper(app)
CLIHelperEmbedder.new(app).embed
CSourcesEmbedder.new(app, @source_dir).embed
LibEmbedder.new(app, brew_dir, extra_libs, options[:relink_eln]).embed
GccLibEmbedder.new(app, gcc_info).embed if options[:native_comp]
@@ -199,7 +213,7 @@ class Build
end
out "CMD: #{log_args.join(' ')}"
system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}")
cmd(*args)
target
end
@@ -286,8 +300,6 @@ class Build
verify_native_comp
gcc_info.verify_libgccjit
apply_native_comp_env_setup_patch(source)
ENV['CFLAGS'] = [
"-I#{File.join(gcc_info.root_dir, 'include')}",
"-I#{File.join(gcc_info.libgccjit_root_dir, 'include')}",
@@ -402,13 +414,13 @@ class Build
info "Copying \"#{app_name}\" to: #{target_dir}"
FileUtils.mkdir_p(target_dir)
FileUtils.cp_r(app, target_dir)
cmd('cp', '-a', app, target_dir)
options[:dist_include]&.each do |filename|
src = File.join(source_dir, filename)
if File.exist?(src)
info "Copying \"#{filename}\" to: #{target_dir}"
FileUtils.cp_r(src, target_dir)
cmd('cp', '-pRL', src, target_dir)
else
info "Warning: #{filename} does not exist in #{source_dir}"
end
@@ -433,7 +445,7 @@ class Build
info 'Creating symlinks within Emacs.app needed for native-comp'
if !File.exist?('lisp') && File.exist?('Resources/lisp')
FileUtils.ln_s('Resources/lisp', 'lisp')
run_cmd('ln', '-s', 'Resources/lisp', 'lisp')
end
# Check for folder name containing two dots (.), as this causes Apple's
@@ -455,7 +467,7 @@ class Build
new_name = File.join(parent, base.gsub(/\.(.+)\./, '-\\1-'))
info "Renaming: #{old_name} --> #{new_name}"
FileUtils.mv(old_name, new_name)
cmd('mv', old_name, new_name)
end
base = File.basename(parent)
@@ -479,7 +491,7 @@ class Build
end
target = File.basename(source)
FileUtils.ln_s(source, target) unless File.exist?(target)
run_cmd('ln', '-s', source, target) unless File.exist?(target)
end
end
@@ -506,18 +518,6 @@ class Build
end
end
def add_cli_helper(app)
source = File.join(__dir__, 'helper', 'emacs-cli.bash')
target = File.join(app, 'Contents', 'MacOS', 'bin', 'emacs')
dir = File.dirname(target)
info "Adding \"emacs\" CLI helper to #{dir}"
FileUtils.mkdir_p(dir)
FileUtils.cp(source, target)
FileUtils.chmod('+w', target)
end
def build_name
return @build_name if @build_name
return @build_name = options[:build_name] if options[:build_name]
@@ -549,7 +549,7 @@ class Build
if !File.exist?(archive_filename)
info "Creating #{filename} archive in \"#{target_dir}\"..."
FileUtils.cd(parent_dir) do
system('tar', '-cjf', archive_filename, build)
cmd('tar', '-cjf', archive_filename, build)
if options[:archive_keep] == false
info "Removing \"#{build}\" directory from #{parent_dir}"
@@ -614,26 +614,6 @@ class Build
response.body
end
def run_cmd(*args)
out "CMD: #{args.join(' ')}"
system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}")
end
def apply_native_comp_env_setup_patch(source)
term = 'native-compile-setup-environment-variables'
file = 'lisp/emacs-lisp/comp.el'
return if `grep '#{term}' '#{file}'`.strip.size.positive?
template = File.read(
File.join(__dir__, 'patches/native-comp-env-setup.diff.erb')
)
patch = ERB.new(template).result(gcc_info.get_binding)
patch_file = File.join(source, 'macos_patches/native-comp-env-setup.diff')
File.write(patch_file, patch)
apply_patch({ file: patch_file }, source)
end
def effective_version
@effective_version ||= begin
case ref
@@ -680,6 +660,15 @@ class Build
end
end
if %w[emacs-28 emacs-29].include?(effective_version)
if options[:posix_spawn]
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
"patches/#{effective_version}/posix-spawn.patch"
}
end
end
if effective_version == 'emacs-27'
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
@@ -770,6 +759,7 @@ end
class AbstractEmbedder
include Output
include System
attr_reader :app
@@ -780,24 +770,49 @@ class AbstractEmbedder
end
def invocation_dir
File.join(app, 'Contents', 'MacOS')
@invocation_dir ||= File.join(app, 'Contents', 'MacOS')
end
def bin
File.join(invocation_dir, 'Emacs')
@bin ||= File.join(invocation_dir, 'Emacs')
end
def bin_dir
@bin_dir ||= File.join(invocation_dir, 'bin')
end
def lib_dir
File.join(invocation_dir, 'lib')
@lib_dir ||= frameworks_dir
end
def frameworks_dir
@frameworks_dir ||= File.join(app, 'Contents', 'Frameworks')
end
def resources_dir
File.join(app, 'Contents', 'Resources')
@resources_dir ||= File.join(app, 'Contents', 'Resources')
end
end
class CLIHelperEmbedder < AbstractEmbedder
def embed
source = File.join(__dir__, 'helper', 'emacs-cli.bash')
target = File.join(bin_dir, 'emacs')
dir = File.dirname(target)
info 'Adding "emacs" CLI helper to Emacs.app'
FileUtils.mkdir_p(dir)
run_cmd('cp', '-pRL', source, target)
run_cmd('chmod', '+w', target)
end
end
class CSourcesEmbedder < AbstractEmbedder
PATH_PATCH = '(setq source-directory (expand-file-name ".."))'
PATH_PATCH = <<~ELISP
;; Allow Emacs to find bundled C sources.
(setq source-directory (expand-file-name ".."))
ELISP
attr_reader :source_dir
@@ -815,34 +830,35 @@ class CSourcesEmbedder < AbstractEmbedder
rel = f[src_dir.size + 1..-1]
target = File.join(resources_dir, 'src', rel)
FileUtils.mkdir_p(File.dirname(target))
FileUtils.cp(f, target)
cmd('cp', '-pRL', f, target)
end
return if File.read(subdirs_el_file).include?(PATH_PATCH)
return if File.exist?(site_start_el_file) &&
File.read(site_start_el_file).include?(PATH_PATCH)
File.open(subdirs_el_file, 'a') do |f|
File.open(site_start_el_file, 'a') do |f|
f.puts("\n#{PATH_PATCH}")
end
end
private
def subdirs_el_file
@subdirs_el_file ||= File.join(resources_dir, 'lisp', 'subdirs.el')
def site_start_el_file
@site_start_el_file ||= File.join(resources_dir, 'lisp', 'site-start.el')
end
end
class LibEmbedder < AbstractEmbedder
attr_reader :lib_source
attr_reader :extra_libs
attr_reader :embed_eln_files
attr_reader :relink_eln_files
def initialize(app, lib_source, extra_libs = [], embed_eln_files = true)
def initialize(app, lib_source, extra_libs = [], relink_eln_files = true)
super(app)
@lib_source = lib_source
@extra_libs = extra_libs
@embed_eln_files = embed_eln_files
@relink_eln_files = relink_eln_files
end
def embed
@@ -852,15 +868,20 @@ class LibEmbedder < AbstractEmbedder
binary ||= bin
FileUtils.cd(File.dirname(app)) do
rel_path = Pathname.new(lib_dir).relative_path_from(
Pathname.new(File.dirname(binary))
).to_s
rpath = File.join('@executable_path', rel_path)
set_rpath(binary, rpath)
copy_libs(binary)
copy_extra_libs(extra_libs, binary) if extra_libs.any?
if eln_files.any?
if relink_eln_files && eln_files.any?
info "Embedding libraries for #{eln_files.size} *.eln files " \
'within Emacs.app'
rel_path = Pathname.new(lib_dir).relative_path_from(
Pathname.new(File.dirname(binary))
).to_s
eln_files.each { |f| copy_libs(f, rel_path) } if embed_eln_files
eln_files.each { |f| copy_libs(f) }
end
end
end
@@ -871,21 +892,19 @@ class LibEmbedder < AbstractEmbedder
@eln_files ||= Dir[File.join(app, 'Contents', '**', '*.eln')]
end
def copy_libs(exe, rel_path = nil)
exe_file = File.basename(exe)
rel_path ||= Pathname.new(lib_dir).relative_path_from(
Pathname.new(File.dirname(exe))
).to_s
def set_rpath(exe, rpath)
return if rpath.nil? || rpath == ''
rpath = File.join('@executable_path', rel_path)
rpaths = `otool -l "#{exe}" | grep -A 2 'cmd LC_RPATH' | grep 'path'`
return if rpaths.include?(rpath)
unless rpaths.include?(rpath)
while_writable(exe) do
system('install_name_tool', '-add_rpath',
File.join('@executable_path', rel_path), exe)
end
while_writable(exe) do
cmd('install_name_tool', '-add_rpath', rpath, exe)
end
end
def copy_libs(exe)
exe_file = File.basename(exe)
`otool -L "#{exe}"`.split("\n")[1..-1].each do |line|
match = line.match(%r{^\s+(.+/(lib[^/ ]+))\s})
@@ -893,41 +912,37 @@ class LibEmbedder < AbstractEmbedder
while_writable(exe) do
if match[2] == exe_file
system('install_name_tool', '-id',
File.join('@executable_path', rel_path, match[2].to_s), exe)
cmd('install_name_tool', '-id',
File.join('@rpath', match[2].to_s), exe)
else
system('install_name_tool', '-change', match[1],
File.join('@executable_path', rel_path, match[2].to_s), exe)
cmd('install_name_tool', '-change', match[1],
File.join('@rpath', match[2].to_s), exe)
end
end
next if match[2] == exe_file || File.exist?(File.join(lib_dir, match[2]))
FileUtils.mkdir_p(lib_dir)
FileUtils.cp(match[1], lib_dir)
copy_libs(File.join(lib_dir, match[2].to_s), rel_path)
cmd('cp', '-pRL', match[1], lib_dir)
copy_libs(File.join(lib_dir, match[2].to_s))
end
end
def copy_extra_libs(extra_libs, exe, rel_path = nil)
rel_path ||= Pathname.new(lib_dir).relative_path_from(
Pathname.new(File.dirname(exe))
).to_s
def copy_extra_libs(extra_libs, exe)
extra_libs.each do |lib|
lib_file = File.basename(lib)
target = "#{lib_dir}/#{lib_file}"
unless File.exist?(target)
FileUtils.mkdir_p(lib_dir)
FileUtils.cp(lib, lib_dir)
cmd('cp', '-pRL', lib, lib_dir)
end
while_writable(target) do
system('install_name_tool', '-id',
File.join('@executable_path', rel_path, lib_file), target)
cmd('install_name_tool', '-id',
File.join('@rpath', lib_file), target)
end
copy_libs(target, rel_path)
copy_libs(target)
end
end
@@ -936,7 +951,7 @@ class LibEmbedder < AbstractEmbedder
File.chmod(0o775, file)
yield
ensure
File.chmod(mode, file)
File.chmod(mode, file) if File.exist?(file)
end
end
@@ -961,14 +976,51 @@ class GccLibEmbedder < AbstractEmbedder
end
FileUtils.mkdir_p(File.dirname(target_dir))
FileUtils.cp_r(source_dir, target_dir)
run_cmd('cp', '-pRL', source_dir, target_dir)
FileUtils.rm(Dir[File.join(target_dir, '**', '.DS_Store')], force: true)
FileUtils.chmod_R('u+w', target_dir)
FileUtils.mv(source_darwin_dir, target_darwin_dir)
run_cmd('chmod', '-R', 'u+w', target_dir)
if source_darwin_dir != target_darwin_dir
run_cmd('mv', source_darwin_dir, target_darwin_dir)
end
env_setup = ERB.new(NATIVE_COMP_ENV_VAR_TPL).result(gcc_info.get_binding)
return if File.exist?(site_start_el_file) &&
File.read(site_start_el_file).include?(env_setup)
File.open(site_start_el_file, 'a') do |f|
f.puts("\n#{env_setup}")
end
end
private
NATIVE_COMP_ENV_VAR_TPL = <<~ELISP
;; Set LIBRARY_PATH to point at bundled GCC and Xcode Command Line Tools to
;; ensure native-comp works.
(when (and (eq system-type 'darwin)
(string-match-p "\\.app\\/Contents\\/MacOS\\/?$"
invocation-directory))
(let* ((library-path-env (getenv "LIBRARY_PATH"))
(devtools-dir
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib")
(gcc-dir (expand-file-name
"<%= app_bundle_relative_lib_dir %>"
invocation-directory))
(darwin-dir (expand-file-name
"<%= app_bundle_relative_darwin_lib_dir %>"
invocation-directory))
(lib-paths (list)))
(if library-path-env
(push library-path-env lib-paths))
(if (file-directory-p devtools-dir)
(push devtools-dir lib-paths))
(push darwin-dir lib-paths)
(push gcc-dir lib-paths)
(setenv "LIBRARY_PATH" (mapconcat 'identity lib-paths ":"))))
ELISP
def embedded?
Dir[File.join(target_dir, 'libgcc*')].any?
end
@@ -992,6 +1044,10 @@ class GccLibEmbedder < AbstractEmbedder
def relative_dir(path, root)
Pathname.new(path).relative_path_from(Pathname.new(root)).to_s
end
def site_start_el_file
@site_start_el_file ||= File.join(resources_dir, 'lisp', 'site-start.el')
end
end
class GccInfo
@@ -1013,7 +1069,7 @@ class GccInfo
end
def relative_lib_dir
@relative_lib_dir ||= relative_dir(lib_dir, root_dir)
@relative_lib_dir ||= relative_dir(lib_dir, File.join(root_dir, 'lib'))
end
def darwin_lib_dir
@@ -1028,7 +1084,9 @@ class GccInfo
end
def relative_darwin_lib_dir
@relative_darwin_lib_dir ||= relative_dir(darwin_lib_dir, root_dir)
@relative_darwin_lib_dir ||= relative_dir(
darwin_lib_dir, File.join(root_dir, 'lib')
)
end
# Sanitize folder name with full "MAJOR.MINOR.PATCH" version number to just
@@ -1186,6 +1244,10 @@ if __FILE__ == $PROGRAM_NAME
cli_options[:no_titlebar] = true
end
opts.on('--posix-spawn', 'Apply posix-spawn patch (default: disabled)') do
cli_options[:posix_spawn] = true
end
opts.on('--no-frame-refocus',
'Apply no-frame-refocus patch (default: disabled)') do
cli_options[:no_frame_refocus] = true

View File

@@ -1,57 +0,0 @@
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 638d4b274c..2599211936 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -4224,6 +4224,52 @@ native-compile-async
(let ((load (not (not load))))
(native--compile-async files recursively load selector)))
+;;;###autoload
+(defun native-compile-setup-environment-variables (&rest _args)
+ "Ensure LIBRARY_PATH is set correctly when libgccjit is bundled."
+ (when (and (eq system-type 'darwin)
+ (string-match-p "\.app\/Contents\/MacOS\/?$"
+ invocation-directory))
+ (let* ((library-path-env (getenv "LIBRARY_PATH"))
+ (devtools-dir
+ "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib")
+ (gcc-dir (expand-file-name
+ "<%= app_bundle_relative_lib_dir %>"
+ invocation-directory))
+ (darwin-dir (expand-file-name
+ "<%= app_bundle_relative_darwin_lib_dir %>"
+ invocation-directory))
+ (lib-paths (list)))
+
+ (if library-path-env
+ (push library-path-env lib-paths))
+ (if (file-directory-p devtools-dir)
+ (push devtools-dir lib-paths))
+ (push darwin-dir lib-paths)
+ (push gcc-dir lib-paths)
+
+ (setenv "LIBRARY_PATH" (mapconcat 'identity lib-paths ":"))))
+
+ ;; Remove advice, as it only needs to run once.
+ (advice-remove 'native-compile
+ 'native-compile-setup-environment-variables)
+ (advice-remove 'comp--native-compile
+ 'native-compile-setup-environment-variables)
+ (advice-remove 'native-compile-async
+ 'native-compile-setup-environment-variables)
+ (advice-remove 'native--compile-async
+ 'native-compile-setup-environment-variables))
+
+;; Ensure environment setup runs before any native compilation.
+(advice-add 'native-compile :before
+ 'native-compile-setup-environment-variables)
+(advice-add 'comp--native-compile :before
+ 'native-compile-setup-environment-variables)
+(advice-add 'native-compile-async :before
+ 'native-compile-setup-environment-variables)
+(advice-add 'native--compile-async :before
+ 'native-compile-setup-environment-variables)
+
(provide 'comp)
;; LocalWords: limplified limplified limplification limplify Limple LIMPLE libgccjit elc eln

View File

@@ -393,9 +393,7 @@ func (s *Updater) renderCask(
filename := asset.GetName()
s.logger.Debug("processing asset", "filename", filename)
if strings.HasSuffix(filename, ".sha256") {
filename = strings.TrimSuffix(filename, ".sha256")
}
filename = strings.TrimSuffix(filename, ".sha256")
if _, ok := info.Assets[filename]; !ok {
info.Assets[filename] = &ReleaseAsset{

View File

@@ -46,6 +46,7 @@ func New(version, commit, date string) *CLI {
Commands: []*cli2.Command{
planCmd(),
signCmd(),
signFilesCmd(),
notarizeCmd(),
packageCmd(),
releaseCmd(),

View File

@@ -112,3 +112,49 @@ func signAction(c *cli2.Context, opts *Options) error {
return sign.Emacs(c.Context, app, signOpts)
}
func signFilesCmd() *cli2.Command {
signCmd := signCmd()
var flags []cli2.Flag
for _, f := range signCmd.Flags {
n := f.Names()
if len(n) > 0 && n[0] == "plan" {
continue
}
flags = append(flags, f)
}
return &cli2.Command{
Name: "sign-files",
Usage: "sign files with codesign",
ArgsUsage: "<file> [<file>...]",
Hidden: true,
Flags: flags,
Action: actionWrapper(signFilesAction),
}
}
func signFilesAction(c *cli2.Context, opts *Options) error {
signOpts := &sign.Options{
Identity: c.String("sign"),
Options: c.StringSlice("options"),
Deep: c.Bool("deep"),
Timestamp: c.Bool("timestamp"),
Force: c.Bool("force"),
Verbose: c.Bool("verbose"),
CodeSignCmd: c.String("codesign"),
}
if v := c.StringSlice("entitlements"); len(v) > 0 {
e := sign.Entitlements(v)
signOpts.Entitlements = &e
}
if !opts.quiet {
signOpts.Output = os.Stdout
}
return sign.Files(c.Context, c.Args().Slice(), signOpts)
}

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"regexp"
"strconv"
"strings"
"github.com/hashicorp/go-hclog"
@@ -13,10 +14,13 @@ import (
"github.com/jimeh/build-emacs-for-macos/pkg/osinfo"
"github.com/jimeh/build-emacs-for-macos/pkg/release"
"github.com/jimeh/build-emacs-for-macos/pkg/repository"
"github.com/jimeh/build-emacs-for-macos/pkg/sanitize"
"github.com/jimeh/build-emacs-for-macos/pkg/source"
)
var nonAlphaNum = regexp.MustCompile(`[^\w_-]+`)
var gitTagMatcher = regexp.MustCompile(
`^emacs(-.*)?-((\d+\.\d+)(?:\.(\d+))?(-rc\d+)?(.+)?)$`,
)
type TestBuildType string
@@ -37,7 +41,7 @@ type Options struct {
Output io.Writer
}
func Create(ctx context.Context, opts *Options) (*Plan, error) {
func Create(ctx context.Context, opts *Options) (*Plan, error) { //nolint:funlen
logger := hclog.FromContext(ctx).Named("plan")
repo, err := repository.NewGitHub(opts.EmacsRepo)
@@ -66,19 +70,36 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) {
return nil, err
}
version := fmt.Sprintf(
absoluteVersion := fmt.Sprintf(
"%s.%s.%s",
commitInfo.DateString(),
commitInfo.ShortSHA(),
sanitizeString(opts.Ref),
sanitize.String(opts.Ref),
)
releaseName := fmt.Sprintf("Emacs.%s", version)
version, channel, err := parseGitRef(opts.Ref)
if err != nil {
return nil, err
}
var releaseName string
switch channel {
case release.Stable, release.RC:
releaseName = "Emacs-" + version
case release.Pretest:
version += "-pretest"
absoluteVersion += "-pretest"
releaseName = "Emacs-" + version
default:
version = absoluteVersion
releaseName = "Emacs." + version
}
buildName := fmt.Sprintf(
"Emacs.%s.%s.%s",
version,
sanitizeString(osInfo.Name+"-"+osInfo.DistinctVersion()),
sanitizeString(osInfo.Arch),
absoluteVersion,
sanitize.String(osInfo.Name+"-"+osInfo.DistinctVersion()),
sanitize.String(osInfo.Arch),
)
diskImage := buildName + ".dmg"
@@ -97,7 +118,8 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) {
OS: osInfo,
Release: &Release{
Name: releaseName,
Prerelease: true,
Prerelease: channel != release.Stable,
Channel: channel,
},
Output: &Output{
Directory: opts.OutputDir,
@@ -105,28 +127,18 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) {
},
}
// If given git ref is a stable release tag (emacs-23.2b, emacs-27.2, etc.)
// we modify release properties accordingly.
if v, err := release.GitRefToStableVersion(opts.Ref); err == nil {
plan.Release.Prerelease = false
plan.Release.Name, err = release.VersionToName(v)
if err != nil {
return nil, err
}
}
if opts.TestBuild != "" {
testName := sanitizeString(opts.TestBuild)
testName := sanitize.String(opts.TestBuild)
plan.Build.Name += ".test." + testName
plan.Release.Title = "Test Builds"
plan.Release.Title = "Test Builds (" + testName + ")"
plan.Release.Name = "test-builds"
plan.Release.Prerelease = true
plan.Release.Draft = false
if opts.TestBuildType == Draft {
plan.Release.Prerelease = false
plan.Release.Draft = true
plan.Release.Prerelease = false
plan.Release.Draft = true
if opts.TestBuildType == Prerelease {
plan.Release.Prerelease = true
plan.Release.Draft = false
}
index := strings.LastIndex(diskImage, ".")
@@ -137,6 +149,35 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) {
return plan, nil
}
func sanitizeString(s string) string {
return nonAlphaNum.ReplaceAllString(s, "-")
func parseGitRef(ref string) (string, release.Channel, error) {
m := gitTagMatcher.FindStringSubmatch(ref)
if len(m) == 0 {
return "", release.Nightly, nil
}
if strings.Contains(m[1], "pretest") {
return m[2], release.Pretest, nil
}
if m[4] != "" {
n, err := strconv.Atoi(m[4])
if err != nil {
return "", "", err
}
if n >= 90 {
return m[2], release.Pretest, nil
}
}
if strings.HasPrefix(m[5], "-rc") {
return m[2], release.RC, nil
}
if m[2] == m[3] {
return m[2], release.Stable, nil
}
return "", "", nil
}

421
pkg/plan/create_test.go Normal file
View File

@@ -0,0 +1,421 @@
package plan
import (
"testing"
"github.com/jimeh/build-emacs-for-macos/pkg/release"
"github.com/stretchr/testify/assert"
)
func Test_parseGitRef(t *testing.T) {
t.Parallel()
type args struct {
ref string
}
type want struct {
version string
channel release.Channel
err string
}
tests := []struct {
name string
args args
want want
}{
{
name: "master",
args: args{ref: "master"},
want: want{version: "", channel: release.Nightly, err: ""},
},
{
name: "emacs-28",
args: args{ref: "emacs-28"},
want: want{version: "", channel: release.Nightly, err: ""},
},
{
name: "emacs-27",
args: args{ref: "emacs-27"},
want: want{version: "", channel: release.Nightly, err: ""},
},
{
name: "emacs-26",
args: args{ref: "emacs-26"},
want: want{version: "", channel: release.Nightly, err: ""},
},
{
name: "emacs-24",
args: args{ref: "emacs-24"},
want: want{version: "", channel: release.Nightly, err: ""},
},
{
name: "feature/native-comp",
args: args{ref: "feature/native-comp"},
want: want{version: "", channel: release.Nightly, err: ""},
},
{
name: "feature/pgtk",
args: args{ref: "feature/pgtk"},
want: want{version: "", channel: release.Nightly, err: ""},
},
{
name: "emacs-19.34",
args: args{ref: "emacs-19.34"},
want: want{version: "19.34", channel: release.Stable, err: ""},
},
{
name: "emacs-20.4",
args: args{ref: "emacs-20.4"},
want: want{version: "20.4", channel: release.Stable, err: ""},
},
{
name: "emacs-22.3",
args: args{ref: "emacs-22.3"},
want: want{version: "22.3", channel: release.Stable, err: ""},
},
{
name: "emacs-23.4",
args: args{ref: "emacs-23.4"},
want: want{version: "23.4", channel: release.Stable, err: ""},
},
{
name: "emacs-24.0.97",
args: args{ref: "emacs-24.0.97"},
want: want{version: "24.0.97", channel: release.Pretest, err: ""},
},
{
name: "emacs-24.2",
args: args{ref: "emacs-24.2"},
want: want{version: "24.2", channel: release.Stable, err: ""},
},
{
name: "emacs-24.2.90",
args: args{ref: "emacs-24.2.90"},
want: want{version: "24.2.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-24.2.93",
args: args{ref: "emacs-24.2.93"},
want: want{version: "24.2.93", channel: release.Pretest, err: ""},
},
{
name: "emacs-24.3",
args: args{ref: "emacs-24.3"},
want: want{version: "24.3", channel: release.Stable, err: ""},
},
{
name: "emacs-24.3-rc1",
args: args{ref: "emacs-24.3-rc1"},
want: want{version: "24.3-rc1", channel: release.RC, err: ""},
},
{
name: "emacs-24.3.90",
args: args{ref: "emacs-24.3.90"},
want: want{version: "24.3.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-24.3.94",
args: args{ref: "emacs-24.3.94"},
want: want{version: "24.3.94", channel: release.Pretest, err: ""},
},
{
name: "emacs-24.4",
args: args{ref: "emacs-24.4"},
want: want{version: "24.4", channel: release.Stable, err: ""},
},
{
name: "emacs-24.4-rc1",
args: args{ref: "emacs-24.4-rc1"},
want: want{version: "24.4-rc1", channel: release.RC, err: ""},
},
{
name: "emacs-24.4.90",
args: args{ref: "emacs-24.4.90"},
want: want{version: "24.4.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-24.4.91",
args: args{ref: "emacs-24.4.91"},
want: want{version: "24.4.91", channel: release.Pretest, err: ""},
},
{
name: "emacs-24.5",
args: args{ref: "emacs-24.5"},
want: want{version: "24.5", channel: release.Stable, err: ""},
},
{
name: "emacs-24.5-rc1",
args: args{ref: "emacs-24.5-rc1"},
want: want{version: "24.5-rc1", channel: release.RC, err: ""},
},
{
name: "emacs-24.5-rc3",
args: args{ref: "emacs-24.5-rc3"},
want: want{version: "24.5-rc3", channel: release.RC, err: ""},
},
{
name: "emacs-24.5-rc3-fixed",
args: args{ref: "emacs-24.5-rc3-fixed"},
want: want{version: "24.5-rc3-fixed", channel: release.RC, err: ""},
},
{
name: "emacs-25.0.90",
args: args{ref: "emacs-25.0.90"},
want: want{version: "25.0.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-25.0.95",
args: args{ref: "emacs-25.0.95"},
want: want{version: "25.0.95", channel: release.Pretest, err: ""},
},
{
name: "emacs-25.1",
args: args{ref: "emacs-25.1"},
want: want{version: "25.1", channel: release.Stable, err: ""},
},
{
name: "emacs-25.1-rc1",
args: args{ref: "emacs-25.1-rc1"},
want: want{version: "25.1-rc1", channel: release.RC, err: ""},
},
{
name: "emacs-25.1-rc2",
args: args{ref: "emacs-25.1-rc2"},
want: want{version: "25.1-rc2", channel: release.RC, err: ""},
},
{
name: "emacs-25.1.90",
args: args{ref: "emacs-25.1.90"},
want: want{version: "25.1.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-25.1.91",
args: args{ref: "emacs-25.1.91"},
want: want{version: "25.1.91", channel: release.Pretest, err: ""},
},
{
name: "emacs-25.2",
args: args{ref: "emacs-25.2"},
want: want{version: "25.2", channel: release.Stable, err: ""},
},
{
name: "emacs-25.2-rc1",
args: args{ref: "emacs-25.2-rc1"},
want: want{version: "25.2-rc1", channel: release.RC, err: ""},
},
{
name: "emacs-25.2-rc2",
args: args{ref: "emacs-25.2-rc2"},
want: want{version: "25.2-rc2", channel: release.RC, err: ""},
},
{
name: "emacs-26.0.90",
args: args{ref: "emacs-26.0.90"},
want: want{version: "26.0.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-26.0.91",
args: args{ref: "emacs-26.0.91"},
want: want{version: "26.0.91", channel: release.Pretest, err: ""},
},
{
name: "emacs-26.1",
args: args{ref: "emacs-26.1"},
want: want{version: "26.1", channel: release.Stable, err: ""},
},
{
name: "emacs-26.1-rc1",
args: args{ref: "emacs-26.1-rc1"},
want: want{version: "26.1-rc1", channel: release.RC, err: ""},
},
{
name: "emacs-26.1.90",
args: args{ref: "emacs-26.1.90"},
want: want{version: "26.1.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-26.1.92",
args: args{ref: "emacs-26.1.92"},
want: want{version: "26.1.92", channel: release.Pretest, err: ""},
},
{
name: "emacs-26.2",
args: args{ref: "emacs-26.2"},
want: want{version: "26.2", channel: release.Stable, err: ""},
},
{
name: "emacs-26.2.90",
args: args{ref: "emacs-26.2.90"},
want: want{version: "26.2.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-26.3",
args: args{ref: "emacs-26.3"},
want: want{version: "26.3", channel: release.Stable, err: ""},
},
{
name: "emacs-26.3-rc1",
args: args{ref: "emacs-26.3-rc1"},
want: want{version: "26.3-rc1", channel: release.RC, err: ""},
},
{
name: "emacs-27.0.90",
args: args{ref: "emacs-27.0.90"},
want: want{version: "27.0.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-27.0.91",
args: args{ref: "emacs-27.0.91"},
want: want{version: "27.0.91", channel: release.Pretest, err: ""},
},
{
name: "emacs-27.1",
args: args{ref: "emacs-27.1"},
want: want{version: "27.1", channel: release.Stable, err: ""},
},
{
name: "emacs-27.1-rc1",
args: args{ref: "emacs-27.1-rc1"},
want: want{version: "27.1-rc1", channel: release.RC, err: ""},
},
{
name: "emacs-27.1-rc2",
args: args{ref: "emacs-27.1-rc2"},
want: want{version: "27.1-rc2", channel: release.RC, err: ""},
},
{
name: "emacs-27.1.90",
args: args{ref: "emacs-27.1.90"},
want: want{version: "27.1.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-27.1.91",
args: args{ref: "emacs-27.1.91"},
want: want{version: "27.1.91", channel: release.Pretest, err: ""},
},
{
name: "emacs-27.2",
args: args{ref: "emacs-27.2"},
want: want{version: "27.2", channel: release.Stable, err: ""},
},
{
name: "emacs-27.2-rc1",
args: args{ref: "emacs-27.2-rc1"},
want: want{version: "27.2-rc1", channel: release.RC, err: ""},
},
{
name: "emacs-27.2-rc2",
args: args{ref: "emacs-27.2-rc2"},
want: want{version: "27.2-rc2", channel: release.RC, err: ""},
},
{
name: "emacs-28.0.90",
args: args{ref: "emacs-28.0.90"},
want: want{version: "28.0.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-21.0.100",
args: args{ref: "emacs-pretest-21.0.100"},
want: want{version: "21.0.100", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-21.0.106",
args: args{ref: "emacs-pretest-21.0.106"},
want: want{version: "21.0.106", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-21.0.90",
args: args{ref: "emacs-pretest-21.0.90"},
want: want{version: "21.0.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-21.0.99",
args: args{ref: "emacs-pretest-21.0.99"},
want: want{version: "21.0.99", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-22.0.90",
args: args{ref: "emacs-pretest-22.0.90"},
want: want{version: "22.0.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-22.0.99",
args: args{ref: "emacs-pretest-22.0.99"},
want: want{version: "22.0.99", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-22.0.990",
args: args{ref: "emacs-pretest-22.0.990"},
want: want{version: "22.0.990", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-22.1.90",
args: args{ref: "emacs-pretest-22.1.90"},
want: want{version: "22.1.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-22.2.90",
args: args{ref: "emacs-pretest-22.2.90"},
want: want{version: "22.2.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-23.0.90",
args: args{ref: "emacs-pretest-23.0.90"},
want: want{version: "23.0.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-23.1.90",
args: args{ref: "emacs-pretest-23.1.90"},
want: want{version: "23.1.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-23.2.90",
args: args{ref: "emacs-pretest-23.2.90"},
want: want{version: "23.2.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-23.2.91",
args: args{ref: "emacs-pretest-23.2.91"},
want: want{version: "23.2.91", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-23.2.93",
args: args{ref: "emacs-pretest-23.2.93"},
want: want{version: "23.2.93", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-23.2.93.1",
args: args{ref: "emacs-pretest-23.2.93.1"},
want: want{version: "23.2.93.1", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-23.3.90",
args: args{ref: "emacs-pretest-23.3.90"},
want: want{version: "23.3.90", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-24.0.05",
args: args{ref: "emacs-pretest-24.0.05"},
want: want{version: "24.0.05", channel: release.Pretest, err: ""},
},
{
name: "emacs-pretest-24.0.90",
args: args{ref: "emacs-pretest-24.0.90"},
want: want{version: "24.0.90", channel: release.Pretest, err: ""},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, gotChannel, err := parseGitRef(tt.args.ref)
assert.Equal(t, tt.want.version, got)
assert.Equal(t, tt.want.channel, gotChannel)
if tt.want.err == "" {
assert.NoError(t, err)
} else {
assert.EqualError(t, err, tt.want.err)
}
})
}
}

View File

@@ -7,6 +7,7 @@ import (
"os"
"github.com/jimeh/build-emacs-for-macos/pkg/osinfo"
"github.com/jimeh/build-emacs-for-macos/pkg/release"
"github.com/jimeh/build-emacs-for-macos/pkg/source"
"gopkg.in/yaml.v3"
)
@@ -78,10 +79,11 @@ type Build struct {
}
type Release struct {
Name string `yaml:"name" json:"name"`
Title string `yaml:"title,omitempty" json:"title,omitempty"`
Draft bool `yaml:"draft,omitempty" json:"draft,omitempty"`
Prerelease bool `yaml:"prerelease,omitempty" json:"prerelease,omitempty"`
Name string `yaml:"name" json:"name"`
Title string `yaml:"title,omitempty" json:"title,omitempty"`
Draft bool `yaml:"draft,omitempty" json:"draft,omitempty"`
Prerelease bool `yaml:"prerelease,omitempty" json:"prerelease,omitempty"`
Channel release.Channel `yaml:"channel,omitempty" json:"channel,omitempty"`
}
type Output struct {

11
pkg/release/channel.go Normal file
View File

@@ -0,0 +1,11 @@
package release
type Channel string
// Release channels
const (
Stable Channel = "stable"
RC Channel = "release-candidate"
Pretest Channel = "pretest"
Nightly Channel = "nightly"
)

View File

@@ -18,7 +18,7 @@ var (
var (
stableVersion = regexp.MustCompile(`^\d+\.\d+(?:[a-z]+)?$`)
stableGetRef = regexp.MustCompile(`^emacs-(\d+\.\d+(?:[a-z]+)?)$`)
stableGitRef = regexp.MustCompile(`^emacs-(\d+\.\d+(?:[a-z]+)?)$`)
)
func VersionToName(version string) (string, error) {
@@ -34,7 +34,7 @@ func VersionToName(version string) (string, error) {
}
func GitRefToStableVersion(ref string) (string, error) {
if m := stableGetRef.FindStringSubmatch(ref); len(m) > 1 {
if m := stableGitRef.FindStringSubmatch(ref); len(m) > 1 {
return m[1], nil
}

View File

@@ -128,3 +128,15 @@ func (s *Repository) ActionRunURL(runID string) string {
return ""
}
}
func (s *Repository) ReleaseURL(releaseName string) string {
if releaseName == "" {
return ""
}
switch s.Type {
case GitHub:
return GitHubBaseURL + s.Source + "/releases/tag/" + releaseName
default:
return ""
}
}

View File

@@ -0,0 +1,54 @@
package repository
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestRepository_ReleaseURL(t *testing.T) {
type fields struct {
Type Type
Source string
}
type args struct {
releaseName string
}
tests := []struct {
name string
fields fields
args args
want string
}{
{
name: "empty name",
fields: fields{Type: GitHub, Source: "foo/bar"},
args: args{releaseName: ""},
want: "",
},
{
name: "GitHub, foo/bar, v1.0.0",
fields: fields{Type: GitHub, Source: "foo/bar"},
args: args{releaseName: "v1.0.0"},
want: "https://github.com/foo/bar/releases/tag/v1.0.0",
},
{
name: "Not GitHub, foo/bar, v1.0.0",
fields: fields{Type: Type("oops"), Source: "foo/bar"},
args: args{releaseName: "v1.0.0"},
want: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
repo := &Repository{
Type: tt.fields.Type,
Source: tt.fields.Source,
}
got := repo.ReleaseURL(tt.args.releaseName)
assert.Equal(t, tt.want, got)
})
}
}

9
pkg/sanitize/string.go Normal file
View File

@@ -0,0 +1,9 @@
package sanitize
import "regexp"
var nonAlphaNum = regexp.MustCompile(`[^\w_-]+`)
func String(s string) string {
return nonAlphaNum.ReplaceAllString(s, "-")
}

View File

@@ -14,6 +14,7 @@ var DefaultEmacsEntitlements = []string{
"com.apple.security.cs.allow-jit",
"com.apple.security.network.client",
"com.apple.security.cs.disable-library-validation",
"com.apple.security.cs.allow-dyld-environment-variables",
"com.apple.security.automation.apple-events",
}

View File

@@ -50,6 +50,7 @@ var entitlementsTestCases = []struct {
"com.apple.security.cs.allow-jit",
"com.apple.security.network.client",
"com.apple.security.cs.disable-library-validation",
"com.apple.security.cs.allow-dyld-environment-variables",
"com.apple.security.automation.apple-events",
},
//nolint:lll
@@ -64,6 +65,8 @@ var entitlementsTestCases = []struct {
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>
</dict>
@@ -78,6 +81,7 @@ func TestDefaultEmacsEntitlements(t *testing.T) {
"com.apple.security.cs.allow-jit",
"com.apple.security.network.client",
"com.apple.security.cs.disable-library-validation",
"com.apple.security.cs.allow-dyld-environment-variables",
"com.apple.security.automation.apple-events",
},
DefaultEmacsEntitlements,