Compare commits

..

2 Commits

Author SHA1 Message Date
876388f686 fix(signing): remove entitlements which I believe caused the app to not launch 2021-11-28 13:43:34 +00:00
1be824cc49 feat(signing); add a number of additional entitlements
The list of additional entitlements have been picked mostly on a
best-guess basis of what's reasonable.
2021-11-27 23:55:30 +00:00
18 changed files with 186 additions and 1047 deletions

View File

@@ -1,30 +1,9 @@
AllCops:
TargetRubyVersion: 2.4
TargetRubyVersion: 2.3
NewCops: enable
Layout/LineLength:
Max: 80
Style/AccessorGrouping:
Enabled: false
Style/Documentation:
Enabled: false
Metrics/AbcSize:
Enabled: false
Metrics/BlockLength:
Enabled: false
Metrics/ClassLength:
Enabled: false
Metrics/CyclomaticComplexity:
Enabled: false
Metrics/MethodLength:
Enabled: false
Metrics/PerceivedComplexity:
Enabled: false

View File

@@ -2,7 +2,7 @@
brew 'autoconf'
brew 'coreutils'
brew 'dbus'
brew 'curl'
brew 'expat'
brew 'gcc'
brew 'gmp'
@@ -22,8 +22,5 @@ brew 'make'
brew 'ncurses'
brew 'nettle'
brew 'pkg-config'
brew 'sqlite'
brew 'texinfo'
brew 'tree-sitter'
brew 'webp'
brew 'zlib'

View File

@@ -2,111 +2,6 @@
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.42](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.41...v0.6.42) (2023-07-31)
### Features
* options for log-level and github source repository ([d08d1b9](https://github.com/jimeh/build-emacs-for-macos/commit/d08d1b9b5c4001302564dc8915884c465802f3b5))
### [0.6.41](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.40...v0.6.41) (2023-01-16)
### [0.6.40](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.39...v0.6.40) (2023-01-08)
### [0.6.39](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.38...v0.6.39) (2022-12-04)
### Features
* **deprecate:** posix-spawn patch is no longer supported ([c3d1969](https://github.com/jimeh/build-emacs-for-macos/commit/c3d19694e7e4d33d462c9917683c2d63f69002f5))
* **version:** correctly handle Emacs 30.x builds ([8b447b6](https://github.com/jimeh/build-emacs-for-macos/commit/8b447b6237fbbd94c4e72af8ee79969c7cfc9363))
### [0.6.38](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.37...v0.6.38) (2022-12-01)
### Features
* **patch:** add round-undecorated-frame from emacs-plus for 29.x ([48a512f](https://github.com/jimeh/build-emacs-for-macos/commit/48a512fbce79759caa987e2880585bd0bc937977))
* **patch:** add support for experimental poll patch from emacs-plus for 29.x ([a3530c0](https://github.com/jimeh/build-emacs-for-macos/commit/a3530c02e8260106f87d464e5cb398dcb2819460))
### [0.6.37](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.36...v0.6.37) (2022-12-01)
### Features
* **tree-sitter:** support new --with-tree-sitter configure flag ([0ba971e](https://github.com/jimeh/build-emacs-for-macos/commit/0ba971ef61a195c91e87aa381d5d3b044461b4f6))
### [0.6.36](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.35...v0.6.36) (2022-10-08)
### Bug Fixes
* **native-comp:** support new configure flag format ([1f2868d](https://github.com/jimeh/build-emacs-for-macos/commit/1f2868d4b3784e906665e9f3b6b9bba8fd72292f)), closes [#76](https://github.com/jimeh/build-emacs-for-macos/issues/76)
### [0.6.35](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.34...v0.6.35) (2022-08-10)
### Bug Fixes
* **native-comp:** compatibility with libgccjit 12 homebrew formula ([e0fd2b1](https://github.com/jimeh/build-emacs-for-macos/commit/e0fd2b16eb91ac5a98ed4ec31f4773ab22cbd470))
### [0.6.34](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.33...v0.6.34) (2022-07-27)
### Bug Fixes
* **emacs-28:** patch configure.ac to support latest libgccjit ([b582523](https://github.com/jimeh/build-emacs-for-macos/commit/b582523642ad4c5298f5a7890edd9b48c0433684)), closes [#72](https://github.com/jimeh/build-emacs-for-macos/issues/72)
### [0.6.33](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.32...v0.6.33) (2022-04-30)
### [0.6.32](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.31...v0.6.32) (2022-04-30)
### Features
* **dbus:** add flag to explicitly disable dbus support ([8ad3ff4](https://github.com/jimeh/build-emacs-for-macos/commit/8ad3ff4f53505408aa097527177032a1fd6008e0)), closes [#69](https://github.com/jimeh/build-emacs-for-macos/issues/69)
* **deps:** add sqlite brew dependency for Emacs 29.x ([a20a845](https://github.com/jimeh/build-emacs-for-macos/commit/a20a8456ab1e8de6357d5d121b9565ba65a6dd71))
### Bug Fixes
* **native-comp:** support libgccjit 11.3.0 ([e31f5aa](https://github.com/jimeh/build-emacs-for-macos/commit/e31f5aaf9355b674c2a86b8eda35f6513f344b72)), closes [#71](https://github.com/jimeh/build-emacs-for-macos/issues/71)
### [0.6.31](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.30...v0.6.31) (2022-02-25)
### Bug Fixes
* set source-directory correctly ([07e0e3d](https://github.com/jimeh/build-emacs-for-macos/commit/07e0e3dacddfbdb7a59aceaa2dc9cdf503ac2bcc)), closes [#68](https://github.com/jimeh/build-emacs-for-macos/issues/68)
### [0.6.30](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.29...v0.6.30) (2022-02-08)
### Bug Fixes
* **site-lisp:** add Homebrew's site-lisp directory to locallisppath ([cbd8cb2](https://github.com/jimeh/build-emacs-for-macos/commit/cbd8cb27b6ceff2e128c38cd1cc8f8380b9b4bfb))
### [0.6.29](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.28...v0.6.29) (2022-02-07)
### Features
* **cask:** add support for pretest builds ([084776d](https://github.com/jimeh/build-emacs-for-macos/commit/084776db6b7e61958088d7b2a2588e9889e60c21))
### [0.6.28](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.27...v0.6.28) (2022-01-15)
### Features
* **build:** add dbus dependency to enable support in Emacs builds ([68ef4c0](https://github.com/jimeh/build-emacs-for-macos/commit/68ef4c066c3fd1a7337198e8f773866088b4f481))
### [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)

View File

@@ -7,7 +7,6 @@ require 'erb'
require 'etc'
require 'fileutils'
require 'json'
require 'logger'
require 'net/http'
require 'optparse'
require 'pathname'
@@ -19,68 +18,33 @@ require 'yaml'
class Error < StandardError; end
module Output
class << self
LEVELS = {
debug: Logger::DEBUG,
error: Logger::ERROR,
fatal: Logger::FATAL,
info: Logger::INFO,
unknown: Logger::UNKNOWN,
warn: Logger::WARN
}.freeze
def info(msg, newline: true)
out "INFO: #{msg}", newline: newline
end
def log_level
LEVELS.key(logger.level)
end
def log_level=(level)
logger.level = LEVELS.fetch(level&.to_sym)
end
def logger
@logger ||= Logger.new($stderr).tap do |logger|
logger.level = Logger::INFO
logger.formatter = proc do |severity, _datetime, _progname, msg|
"==> #{severity.upcase}: #{msg}"
end
end
def out(msg, newline: true)
if newline
warn "==> #{msg}"
else
$stderr.print "==> #{msg}"
end
end
%i[debug info warn error].each do |severity|
define_method(severity) do |msg, newline: true|
logger.send(severity, format_msg(msg, newline: newline))
end
end
def fatal(msg = nil)
def err(msg = nil)
raise Error, msg
end
private
def logger
Output.logger
end
def format_msg(msg, newline: true)
msg = msg.join("\n") if msg.is_a?(Array)
msg = msg.strip
msg = "#{msg}\n" if newline
msg
end
end
module System
include Output
def run_cmd(*args)
debug "executing: #{args.join(' ')}"
out("CMD: #{args.join(' ')}")
cmd(*args)
end
def cmd(*args)
system(*args) || fatal("Exit code: #{$CHILD_STATUS.exitstatus}")
system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}")
end
end
@@ -97,7 +61,7 @@ end
class OSVersion
def initialize
@version = `sw_vers -productVersion`.match(
/(?<major>\d+)(?:\.(?<minor>\d+)(?:\.(?<patch>\d+))?)?/
/(?<major>\d+)(?:\.(?<minor>\d+)(:?\.(?<patch>\d+))?)?/
)
end
@@ -122,7 +86,8 @@ class Build
include Output
include System
DEFAULT_GITHUB_REPO = 'emacs-mirror/emacs'
EMACS_MIRROR_REPO = 'emacs-mirror/emacs'
DOWNLOAD_URL = 'https://github.com/emacs-mirror/emacs/tarball/%s'
attr_reader :root_dir
attr_reader :source_dir
@@ -141,7 +106,7 @@ class Build
load_plan(options[:plan]) if options[:plan]
unless meta[:sha] && meta[:date]
fatal 'Failed to get commit info from GitHub.'
err 'Failed to get commit info from GitHub.'
end
tarball = download_tarball(meta[:sha])
@@ -157,9 +122,7 @@ class Build
CLIHelperEmbedder.new(app).embed
CSourcesEmbedder.new(app, @source_dir).embed
LibEmbedder.new(
app, brew_dir, extra_libs, relink_eln_files: options[:relink_eln]
).embed
LibEmbedder.new(app, brew_dir, extra_libs, options[:relink_eln]).embed
GccLibEmbedder.new(app, gcc_info).embed if options[:native_comp]
archive_build(build_dir) if options[:archive]
@@ -168,7 +131,6 @@ class Build
private
def load_plan(filename)
debug "Loading plan from: #{filename}"
plan = YAML.safe_load(File.read(filename), [:Time])
@ref = plan.dig('source', 'ref')
@@ -201,10 +163,6 @@ class Build
@output_dir ||= (options[:output] || File.join(root_dir, 'builds'))
end
def github_src_repo
@github_src_repo ||= options[:github_src_repo] || DEFAULT_GITHUB_REPO
end
def brew_dir
@brew_dir ||= `brew --prefix`.chomp
end
@@ -231,8 +189,8 @@ class Build
def download_tarball(sha)
FileUtils.mkdir_p(tarballs_dir)
url = "https://github.com/#{github_src_repo}/tarball/#{sha}"
filename = "#{github_src_repo.gsub(/[^a-zA-Z0-9-]+/, '-')}-#{sha[0..6]}.tgz"
url = (DOWNLOAD_URL % sha)
filename = "emacs-mirror-emacs-#{sha[0..6]}.tgz"
target = File.join(tarballs_dir, filename)
if File.exist?(target)
@@ -254,7 +212,7 @@ class Build
log_args[1..-1]
end
debug "executing: #{log_args.join(' ')}"
out "CMD: #{log_args.join(' ')}"
cmd(*args)
target
@@ -273,7 +231,7 @@ class Build
info 'Extracting tarball...'
result = run_cmd('tar', '-xzf', filename, '-C', sources_dir)
fatal 'Tarball extraction failed.' unless result
err 'Tarball extraction failed.' unless result
patches.each { |patch| apply_patch(patch, target) }
@@ -292,53 +250,26 @@ class Build
@supports_xwidgets ||= !!configure_help.match(/\s+--with-xwidgets\s+/)
end
def supports_tree_sitter?
@supports_tree_sitter ||= !!configure_help.match(
/\s+--with-tree-sitter(\s|=).+/
)
end
def supports_native_comp?
@supports_native_comp ||= !native_comp_configure_flag.nil?
end
def native_comp_configure_match
@native_comp_configure_match ||= configure_help.match(
/\s+?(--with-native(?:comp|-compilation))(.+)?\s+?/
)
end
def native_comp_configure_flag
return @native_comp_configure_flag if @native_comp_configure_flag
return unless native_comp_configure_match&.[](1)
@native_comp_configure_flag = [
native_comp_configure_match[1],
native_comp_configure_flag_arg
].compact.join('=')
end
def native_comp_configure_flag_arg
return @native_comp_configure_flag_arg if @native_comp_configure_flag_arg
return if native_comp_configure_match&.[](2) != '[=TYPE]'
@native_comp_configure_flag_arg = \
(options[:native_full_aot] ? 'aot' : 'yes')
@native_comp_configure_flag ||= configure_help.match(
/\s+(--with-native(?:comp|-compilation))\s+/
)&.[](1)
end
def detect_native_comp
info 'Detecting native-comp support...'
info 'Detecting native-comp support: ', newline: false
options[:native_comp] = supports_native_comp?
info 'Native-comp is: ' \
"#{options[:native_comp] ? 'Supported' : 'Not supported'}"
puts options[:native_comp] ? 'Supported' : 'Not supported'
end
def verify_native_comp
return if supports_native_comp?
fatal 'This emacs source tree does not support native-comp'
err 'This emacs source tree does not support native-comp'
end
def autogen
@@ -357,7 +288,7 @@ class Build
if File.exist?(emacs_app)
info 'Emacs.app already exists in ' \
"\"#{target.gsub("#{root_dir}/", '')}\", attempting to use."
"\"#{target.gsub(root_dir + '/', '')}\", attempting to use."
return emacs_app
end
@@ -374,7 +305,7 @@ class Build
"-I#{File.join(gcc_info.libgccjit_root_dir, 'include')}",
'-O2',
(options[:native_march] ? '-march=native' : nil),
ENV.fetch('CFLAGS', nil)
ENV['CFLAGS']
].compact.join(' ')
ENV['LDFLAGS'] = [
@@ -385,14 +316,14 @@ class Build
"-I#{File.join(gcc_info.libgccjit_root_dir, 'include')}",
# Ensure library re-linking and code signing will work after building.
'-Wl,-headerpad_max_install_names',
ENV.fetch('LDFLAGS', nil)
ENV['LDFLAGS']
].compact.join(' ')
ENV['LIBRARY_PATH'] = [
gcc_info.lib_dir,
gcc_info.darwin_lib_dir,
gcc_info.libgccjit_lib_dir,
ENV.fetch('LIBRARY_PATH', nil)
ENV['LIBRARY_PATH']
].compact.join(':')
end
@@ -406,7 +337,7 @@ class Build
File.join(brew_dir, 'opt/zlib/lib/pkgconfig'),
File.join(brew_dir, 'Homebrew/Library/Homebrew/os/mac/pkgconfig',
OS.version.to_s),
ENV.fetch('PKG_CONFIG_PATH', nil)
ENV['PKG_CONFIG_PATH']
].compact.join(':')
ENV['PATH'] = [
@@ -415,11 +346,11 @@ class Build
File.join(brew_dir, 'opt/gnu-sed/libexec/gnubin'),
File.join(brew_dir, 'bin'),
File.join(brew_dir, 'opt/texinfo/bin'),
ENV.fetch('PATH', nil)
ENV['PATH']
].compact.join(':')
ENV['LIBRARY_PATH'] = [
ENV.fetch('LIBRARY_PATH', nil),
ENV['LIBRARY_PATH'],
'/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib'
].compact.join(':')
@@ -428,20 +359,15 @@ class Build
'--with-modules',
'--enable-locallisppath=' \
'/Library/Application Support/Emacs/${version}/site-lisp:' \
'/Library/Application Support/Emacs/site-lisp:' \
'/usr/local/share/emacs/site-lisp'
'/Library/Application Support/Emacs/site-lisp'
]
if options[:xwidgets] && supports_xwidgets?
configure_flags << '--with-xwidgets'
end
if options[:tree_sitter] && supports_tree_sitter?
configure_flags << '--with-tree-sitter'
end
configure_flags << native_comp_configure_flag if options[:native_comp]
configure_flags << '--without-rsvg' if options[:rsvg] == false
configure_flags << '--without-dbus' if options[:dbus] == false
run_cmd './configure', *configure_flags.compact
run_cmd './configure', *configure_flags
# Disable aligned_alloc on Mojave and below. See issue:
# https://github.com/daviderestivo/homebrew-emacs-head/issues/15
@@ -458,12 +384,8 @@ class Build
make_flags << "BYTE_COMPILE_EXTRA_FLAGS=--eval '(setq comp-speed 2)'"
if options[:native_full_aot]
info 'Using native compile full AOT'
# We do not need to supply the full AOT make arg if
# --with-native-compilation=aot configure flag is supported.
unless native_comp_configure_flag_arg
make_flags << 'NATIVE_FULL_AOT=1'
end
info 'Using NATIVE_FULL_AOT=1'
make_flags << 'NATIVE_FULL_AOT=1'
ENV.delete('NATIVE_FAST_BOOT')
else
ENV.delete('NATIVE_FULL_AOT')
@@ -471,11 +393,11 @@ class Build
end
end
run_cmd 'make', *make_flags.compact
run_cmd 'make', *make_flags
run_cmd 'make', 'install'
end
fatal 'Build failed.' unless File.exist?(emacs_app)
err 'Build failed.' unless File.exist?(emacs_app)
emacs_app
end
@@ -485,8 +407,8 @@ class Build
target_dir = File.join(output_dir, build_name)
if File.exist?(target_dir)
fatal "Output directory #{target_dir} already exists, " \
'please delete it and try again'
err "Output directory #{target_dir} already exists, " \
'please delete it and try again'
end
info "Copying \"#{app_name}\" to: #{target_dir}"
@@ -564,8 +486,7 @@ class Build
'MacOS/lib/emacs/**/native-lisp'].first
if source.nil?
fatal 'Failed to find native-lisp cache directory for ' \
'symlink creation.'
err 'Failed to find native-lisp cache directory for symlink creation.'
end
end
@@ -581,7 +502,7 @@ class Build
contents_dir = File.join(app, 'Contents')
FileUtils.cd(contents_dir) do
filename = Dir['MacOS/Emacs.pdmp', 'MacOS/libexec/Emacs.pdmp'].first
fatal "no Emacs.pdmp file found in #{app}" unless filename
err "no Emacs.pdmp file found in #{app}" unless filename
info 'patching Emacs.pdmp to point at new native-lisp paths'
content = File.read(filename, mode: 'rb').gsub(
@@ -593,7 +514,7 @@ class Build
"../native-lisp/#{sanitized_eln_version}/"
)
File.write(filename, content)
File.open(filename, 'w') { |f| f.write(content) }
end
end
@@ -625,10 +546,7 @@ class Build
build = File.basename(build_dir)
parent_dir = File.dirname(build_dir)
if File.exist?(archive_filename)
info "#{filename} archive exists in " \
"#{target_dir}, skipping archving."
else
if !File.exist?(archive_filename)
info "Creating #{filename} archive in \"#{target_dir}\"..."
FileUtils.cd(parent_dir) do
cmd('tar', '-cjf', archive_filename, build)
@@ -638,6 +556,9 @@ class Build
FileUtils.rm_rf(build_dir)
end
end
else
info "#{filename} archive exists in " \
"#{target_dir}, skipping archving."
end
end
@@ -653,7 +574,7 @@ class Build
.gsub('#define HAVE_ALLOCA_H 1',
'#undef HAVE_ALLOCA_H')
File.write(filename, content)
File.open(filename, 'w') { |f| f.write(content) }
end
def meta
@@ -662,9 +583,9 @@ class Build
ref_sha = options[:git_sha] || ref
info "Fetching info for git ref: #{ref_sha}"
commit_json = github_api_get(
"/repos/#{github_src_repo}/commits/#{ref_sha}"
"/repos/#{EMACS_MIRROR_REPO}/commits/#{ref_sha}"
)
fatal "Failed to get commit info about: #{ref_sha}" if commit_json.nil?
err "Failed to get commit info about: #{ref_sha}" if commit_json.nil?
commit = JSON.parse(commit_json)
meta = {
@@ -694,32 +615,31 @@ class Build
end
def effective_version
@effective_version ||= case ref
when /^emacs-26.*/
'emacs-26'
when /^emacs-27.*/
'emacs-27'
when /^emacs-28.*/
'emacs-28'
when /^emacs-29.*/
'emacs-29'
else
'emacs-30'
end
@effective_version ||= begin
case ref
when /^emacs-26.*/
'emacs-26'
when /^emacs-27.*/
'emacs-27'
when /^emacs-28.*/
'emacs-28'
else
'emacs-29'
end
end
end
def patches(opts = {})
p = []
if %w[emacs-26 emacs-27 emacs-28 emacs-29 emacs-30]
.include?(effective_version)
if %w[emacs-26 emacs-27 emacs-28 emacs-29].include?(effective_version)
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
"patches/#{effective_version}/fix-window-role.patch"
}
end
if %w[emacs-27 emacs-28 emacs-29 emacs-30].include?(effective_version)
if %w[emacs-27 emacs-28 emacs-29].include?(effective_version)
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
"patches/#{effective_version}/system-appearance.patch"
@@ -740,41 +660,15 @@ class Build
end
end
if %w[emacs-29 emacs-30].include?(effective_version)
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
"patches/#{effective_version}/round-undecorated-frame.patch"
}
if options[:poll]
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}/poll.patch"
"patches/#{effective_version}/posix-spawn.patch"
}
end
end
if effective_version == 'emacs-28'
p << {
replace: [
'configure.ac',
'grep libgccjit.so\$',
'grep -E \'libgccjit\.(so|dylib)$\''
],
allow_failure: true
}
end
if %w[emacs-28 emacs-29].include?(effective_version)
p << {
replace: [
'configure.ac',
'grep -E \'libgccjit\.(so|dylib)$\'',
'grep -E \'libgccjit\.(so|dylib)$\' | tail -1'
],
allow_failure: true
}
end
if effective_version == 'emacs-27'
p << {
url: 'https://github.com/d12frosted/homebrew-emacs-plus/raw/master/' \
@@ -793,7 +687,7 @@ class Build
end
def apply_patch(patch, target)
fatal "\"#{target}\" does not exist." unless File.exist?(target)
err "\"#{target}\" does not exist." unless File.exist?(target)
if patch[:file]
info 'Applying patch...'
@@ -821,37 +715,20 @@ class Build
end
elsif patch[:replace]
fatal 'Patch replace input error' unless patch[:replace].size == 3
err 'Patch replace input error' unless patch[:replace].size == 3
file, before, after = patch[:replace]
info "Applying patch to #{file}..."
filepath = File.join(target, file)
unless File.exist?(filepath)
if patch[:allow_failure]
info "File #{filepath} does not exist, skipping patch."
return
end
fatal "\"#{file}\" does not exist in #{target}"
end
err "\"#{file}\" does not exist in #{target}" unless File.exist?(filepath)
f = File.open(filepath, 'rb')
s = f.read
sub = s.gsub!(before, after)
if sub.nil?
if patch[:allow_failure]
info 'Patch did not apply, skipping.'
return
end
fatal "Replacement failed in #{file}"
end
err "Replacement filed in #{file}" if sub.nil?
f.reopen(filepath, 'wb').write(s)
f.close
info "#{file} patched."
end
end
@@ -887,15 +764,11 @@ class AbstractEmbedder
attr_reader :app
def initialize(app)
fatal "#{app} does not exist" unless File.exist?(app)
err "#{app} does not exist" unless File.exist?(app)
@app = app
end
def relative_path(path)
Pathname.new(path).relative_path_from(Pathname.new(app)).to_s
end
def invocation_dir
@invocation_dir ||= File.join(app, 'Contents', 'MacOS')
end
@@ -938,8 +811,7 @@ end
class CSourcesEmbedder < AbstractEmbedder
PATH_PATCH = <<~ELISP
;; Allow Emacs to find bundled C sources.
(setq source-directory
(expand-file-name ".." (file-name-directory load-file-name)))
(setq source-directory (expand-file-name ".."))
ELISP
attr_reader :source_dir
@@ -951,16 +823,12 @@ class CSourcesEmbedder < AbstractEmbedder
end
def embed
info 'Bundling C source files into Emacs.app for documentation purposes...'
info 'Embedding C source files into Emacs.app for documentation purposes'
src_dir = File.join(source_dir, 'src')
target_dir = File.join(resources_dir, 'src')
debug "Copying *.c and *.h files from '#{src_dir}' " \
"to: #{relative_path(target_dir)}"
Dir[File.join(src_dir, '**', '*.{c,h}')].each do |f|
rel = f[src_dir.size + 1..-1]
target = File.join(target_dir, rel)
target = File.join(resources_dir, 'src', rel)
FileUtils.mkdir_p(File.dirname(target))
cmd('cp', '-pRL', f, target)
end
@@ -968,8 +836,6 @@ class CSourcesEmbedder < AbstractEmbedder
return if File.exist?(site_start_el_file) &&
File.read(site_start_el_file).include?(PATH_PATCH)
debug "Patching '#{relative_path(site_start_el_file)}' to allow Emacs to " \
'find bundled C sources'
File.open(site_start_el_file, 'a') do |f|
f.puts("\n#{PATH_PATCH}")
end
@@ -987,7 +853,7 @@ class LibEmbedder < AbstractEmbedder
attr_reader :extra_libs
attr_reader :relink_eln_files
def initialize(app, lib_source, extra_libs = [], relink_eln_files: true)
def initialize(app, lib_source, extra_libs = [], relink_eln_files = true)
super(app)
@lib_source = lib_source
@@ -996,7 +862,7 @@ class LibEmbedder < AbstractEmbedder
end
def embed
info 'Bundling shared libraries into Emacs.app...'
info 'Embedding libraries into Emacs.app'
binary = "#{bin}-bin" if File.exist?("#{bin}-bin")
binary ||= bin
@@ -1012,7 +878,7 @@ class LibEmbedder < AbstractEmbedder
copy_extra_libs(extra_libs, binary) if extra_libs.any?
if relink_eln_files && eln_files.any?
info "Bundling shared libraries for #{eln_files.size} *.eln files " \
info "Embedding libraries for #{eln_files.size} *.eln files " \
'within Emacs.app'
eln_files.each { |f| copy_libs(f) }
@@ -1033,76 +899,49 @@ class LibEmbedder < AbstractEmbedder
return if rpaths.include?(rpath)
while_writable(exe) do
debug "Setting rpath for '#{relative_path(exe)}' to: #{rpath}"
cmd('install_name_tool', '-add_rpath', rpath, exe)
end
end
def copy_libs(exe)
exe_filename = File.basename(exe)
exe_file = File.basename(exe)
copied_libs = []
debug "Bundling shared libraries for: #{relative_path(exe)}"
`otool -L "#{exe}"`.split("\n")[1..-1].each do |line|
# Parse otool -L output
match = line.match(%r{^\s+(.+/(lib[^/ ]+))\s})
next unless match
lib_filepath = match[1]
lib_filename = File.basename(lib_filepath)
# Only bundle libraries from lib_source.
next unless lib_filepath.start_with?(lib_source)
unless File.exist?(lib_filepath)
warn "-- Shared library '#{lib_filepath}' does not exist, skipping"
next
end
copied = false
next unless match && match[1].start_with?(lib_source)
while_writable(exe) do
if lib_filename == exe_filename
id_name = File.join('@rpath', lib_filename)
debug "-- Setting install name to: #{id_name}"
cmd('install_name_tool', '-id', id_name, exe)
if match[2] == exe_file
cmd('install_name_tool', '-id',
File.join('@rpath', match[2].to_s), exe)
else
debug "-- Bundling shared library: #{lib_filepath}"
lib_target = File.join(lib_dir, lib_filename)
unless File.exist?(lib_target)
debug '-- -- Copying to: ' \
"#{relative_path(File.join(lib_dir, lib_filename))}"
FileUtils.mkdir_p(lib_dir)
cmd('cp', '-pRL', lib_filepath, lib_target)
copied_libs << lib_target
copied = true
end
change_target = File.join('@rpath', lib_filename)
debug "-- -- Relinking to: #{change_target}"
cmd('install_name_tool', '-change', lib_filepath, change_target, exe)
cmd('install_name_tool', '-change', match[1],
File.join('@rpath', match[2].to_s), exe)
end
end
next if lib_filename == exe_filename || !copied
end
next if match[2] == exe_file || File.exist?(File.join(lib_dir, match[2]))
copied_libs.each { |lib| copy_libs(lib) }
FileUtils.mkdir_p(lib_dir)
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)
def copy_extra_libs(extra_libs, exe)
extra_libs.each do |lib|
debug "Bundling extra shared library: #{lib}"
lib_file = File.basename(lib)
target = "#{lib_dir}/#{lib_file}"
unless File.exist?(target)
FileUtils.mkdir_p(lib_dir)
debug "-- Copying to: #{lib_file}"
cmd('cp', '-pRL', lib, lib_dir)
end
while_writable(target) do
cmd('install_name_tool', '-id',
File.join('@rpath', lib_file), target)
end
copy_libs(target)
end
end
@@ -1130,10 +969,10 @@ class GccLibEmbedder < AbstractEmbedder
return
end
info 'Bundling libgccjit into Emacs.app'
info 'Embedding libgccjit into Emacs.app'
if gcc_info.lib_dir.empty?
fatal "No suitable GCC lib dir found in #{gcc_info.root_dir}"
err "No suitable GCC lib dir found in #{gcc_info.root_dir}"
end
FileUtils.mkdir_p(File.dirname(target_dir))
@@ -1148,7 +987,6 @@ class GccLibEmbedder < AbstractEmbedder
return if File.exist?(site_start_el_file) &&
File.read(site_start_el_file).include?(env_setup)
debug 'Setting up site-start.el for self-contained native-comp Emacs.app'
File.open(site_start_el_file, 'a') do |f|
f.puts("\n#{env_setup}")
end
@@ -1286,8 +1124,7 @@ class GccInfo
def libgccjit_lib_dir
@libgccjit_lib_dir ||= Dir[
File.join(libgccjit_root_dir, 'lib/gcc/*/libgccjit*.dylib'),
File.join(libgccjit_root_dir, 'lib/gcc/*/libgccjit.so*'),
File.join(libgccjit_root_dir, 'lib/gcc/*/libgccjit.so*')
]
.map { |path| File.dirname(path) }
.select { |path| File.basename(path).match(/^\d+$/) }
@@ -1295,18 +1132,18 @@ class GccInfo
end
def verify_libgccjit
fatal 'gcc not installed' unless Dir.exist?(root_dir)
fatal 'libgccjit not installed' unless Dir.exist?(libgccjit_root_dir)
err 'gcc not installed' unless Dir.exist?(root_dir)
err 'libgccjit not installed' unless Dir.exist?(libgccjit_root_dir)
if libgccjit_lib_dir.empty?
fatal "Detected libgccjit (#{libgccjit_root_dir}) does not have any " \
'libgccjit.so* files. Please try reinstalling libgccjit: ' \
'brew reinstall libgccjit'
if libgccjit_lib_dir&.empty?
err "Detected libgccjit (#{libgccjit_root_dir}) does not have any " \
'libgccjit.so* files. Please try reinstalling libgccjit: ' \
'brew reinstall libgccjit'
end
return if major_version == libgccjit_major_version
fatal <<~TEXT
err <<~TEXT
Detected GCC and libgccjit library paths do not belong to the same major
version of GCC. Detected paths:
- #{lib_dir}
@@ -1314,7 +1151,7 @@ class GccInfo
TEXT
end
def get_binding # rubocop:disable Naming/AccessorMethodName
def get_binding
binding
end
@@ -1337,15 +1174,11 @@ if __FILE__ == $PROGRAM_NAME
native_march: false,
parallel: Etc.nprocessors,
rsvg: true,
dbus: true,
xwidgets: true,
tree_sitter: true,
github_src_repo: nil,
github_auth: true,
dist_include: ['COPYING'],
archive: true,
archive_keep: false,
log_level: 'info'
archive_keep: false
}
begin
@@ -1377,12 +1210,6 @@ if __FILE__ == $PROGRAM_NAME
cli_options[:xwidgets] = v
end
opts.on('--[no-]tree-sitter',
'Enable/disable tree-sitter if supported' \
'(default: enabled)') do |v|
cli_options[:tree_sitter] = v
end
opts.on('--[no-]native-comp',
'Enable/disable native-comp ' \
'(default: enabled if supported)') do |v|
@@ -1413,17 +1240,12 @@ if __FILE__ == $PROGRAM_NAME
cli_options[:rsvg] = v
end
opts.on('--[no-]dbus',
'Enable/disable dbus support (default: enabled)') do |v|
cli_options[:dbus] = v
end
opts.on('--no-titlebar', 'Apply no-titlebar patch (default: disabled)') do
cli_options[:no_titlebar] = true
end
opts.on('--posix-spawn', 'Apply posix-spawn patch (deprecated)') do
warn '==> WARN: posix-spawn patch is deprecated as has no effect.'
opts.on('--posix-spawn', 'Apply posix-spawn patch (default: disabled)') do
cli_options[:posix_spawn] = true
end
opts.on('--no-frame-refocus',
@@ -1431,19 +1253,6 @@ if __FILE__ == $PROGRAM_NAME
cli_options[:no_frame_refocus] = true
end
opts.on('--[no-]poll',
'Enable/disable experimental use of poll() instead of select() ' \
'to support > 1024 file descriptors ' \
'(default: disabled)') do |v|
cli_options[:poll] = v
end
opts.on('--github-src-repo REPO',
'Specify a GitHub repo to download source tarballs from ' \
'(default: emacs-mirror/emacs)') do |v|
cli_options[:github_src_repo] = v
end
opts.on('--[no-]github-auth',
'Make authenticated GitHub API requests if GITHUB_TOKEN ' \
'environment variable is set.' \
@@ -1484,11 +1293,6 @@ if __FILE__ == $PROGRAM_NAME
cli_options[:archive_keep] = v
end
opts.on('--log-level LEVEL',
'Build script log level (default: info)') do |v|
cli_options[:log_level] = v
end
opts.on(
'--plan FILE',
'Follow given plan file, instead of using given git ref/sha'
@@ -1497,7 +1301,6 @@ if __FILE__ == $PROGRAM_NAME
end
end.parse!
Output.log_level = cli_options[:log_level]
work_dir = cli_options.delete(:work_dir)
Build.new(work_dir, ARGV.shift, cli_options).build
rescue Error => e

2
go.mod
View File

@@ -16,7 +16,7 @@ require (
github.com/hexops/gotextdiff v1.0.3
github.com/jimeh/undent v1.1.0
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mitchellh/gon v0.2.5
github.com/mitchellh/gon v0.2.3
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/stretchr/testify v1.7.0
github.com/urfave/cli/v2 v2.3.0

4
go.sum
View File

@@ -160,8 +160,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/gon v0.2.5 h1:mVWtqTzV03W0avJqmqjk9M0qls3TDUXfc9ETJaPIOWY=
github.com/mitchellh/gon v0.2.5/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8=
github.com/mitchellh/gon v0.2.3 h1:fObN7hD14VacGG++t27GzTW6opP0lwI7TsgTPL55wBo=
github.com/mitchellh/gon v0.2.3/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
resolve_link() {
"$(command -v greadlink || command -v readlink)" "$1"
"$(type -p greadlink readlink | head -1)" "$1"
}
abs_dirname() {

View File

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

View File

@@ -5,7 +5,6 @@ import (
"fmt"
"io"
"regexp"
"strconv"
"strings"
"github.com/hashicorp/go-hclog"
@@ -14,13 +13,10 @@ 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 gitTagMatcher = regexp.MustCompile(
`^emacs(-.*)?-((\d+\.\d+)(?:\.(\d+))?(-rc\d+)?(.+)?)$`,
)
var nonAlphaNum = regexp.MustCompile(`[^\w_-]+`)
type TestBuildType string
@@ -41,7 +37,7 @@ type Options struct {
Output io.Writer
}
func Create(ctx context.Context, opts *Options) (*Plan, error) { //nolint:funlen
func Create(ctx context.Context, opts *Options) (*Plan, error) {
logger := hclog.FromContext(ctx).Named("plan")
repo, err := repository.NewGitHub(opts.EmacsRepo)
@@ -70,36 +66,19 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) { //nolint:funlen
return nil, err
}
absoluteVersion := fmt.Sprintf(
version := fmt.Sprintf(
"%s.%s.%s",
commitInfo.DateString(),
commitInfo.ShortSHA(),
sanitize.String(opts.Ref),
sanitizeString(opts.Ref),
)
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
}
releaseName := fmt.Sprintf("Emacs.%s", version)
buildName := fmt.Sprintf(
"Emacs.%s.%s.%s",
absoluteVersion,
sanitize.String(osInfo.Name+"-"+osInfo.DistinctVersion()),
sanitize.String(osInfo.Arch),
version,
sanitizeString(osInfo.Name+"-"+osInfo.DistinctVersion()),
sanitizeString(osInfo.Arch),
)
diskImage := buildName + ".dmg"
@@ -118,8 +97,7 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) { //nolint:funlen
OS: osInfo,
Release: &Release{
Name: releaseName,
Prerelease: channel != release.Stable,
Channel: channel,
Prerelease: true,
},
Output: &Output{
Directory: opts.OutputDir,
@@ -127,18 +105,28 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) { //nolint:funlen
},
}
// 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 := sanitize.String(opts.TestBuild)
testName := sanitizeString(opts.TestBuild)
plan.Build.Name += ".test." + testName
plan.Release.Title = "Test Builds (" + testName + ")"
plan.Release.Title = "Test Builds"
plan.Release.Name = "test-builds"
plan.Release.Prerelease = false
plan.Release.Draft = true
if opts.TestBuildType == Prerelease {
plan.Release.Prerelease = true
plan.Release.Draft = false
plan.Release.Prerelease = true
plan.Release.Draft = false
if opts.TestBuildType == Draft {
plan.Release.Prerelease = false
plan.Release.Draft = true
}
index := strings.LastIndex(diskImage, ".")
@@ -149,35 +137,6 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) { //nolint:funlen
return plan, nil
}
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
func sanitizeString(s string) string {
return nonAlphaNum.ReplaceAllString(s, "-")
}

View File

@@ -1,421 +0,0 @@
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,7 +7,6 @@ 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"
)
@@ -79,11 +78,10 @@ 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"`
Channel release.Channel `yaml:"channel,omitempty" json:"channel,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"`
}
type Output struct {

View File

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

View File

@@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"regexp"
"strings"
)
// Errors
@@ -19,7 +18,7 @@ var (
var (
stableVersion = regexp.MustCompile(`^\d+\.\d+(?:[a-z]+)?$`)
stableGitRef = regexp.MustCompile(`^emacs-(\d+\.\d+(?:[a-z]+)?)$`)
stableGetRef = regexp.MustCompile(`^emacs-(\d+\.\d+(?:[a-z]+)?)$`)
)
func VersionToName(version string) (string, error) {
@@ -27,8 +26,7 @@ func VersionToName(version string) (string, error) {
return "", ErrEmptyVersion
}
if stableVersion.MatchString(version) ||
strings.HasSuffix(version, "-pretest") {
if stableVersion.MatchString(version) {
return "Emacs-" + version, nil
}
@@ -36,7 +34,7 @@ func VersionToName(version string) (string, error) {
}
func GitRefToStableVersion(ref string) (string, error) {
if m := stableGitRef.FindStringSubmatch(ref); len(m) > 1 {
if m := stableGetRef.FindStringSubmatch(ref); len(m) > 1 {
return m[1], nil
}

View File

@@ -128,15 +128,3 @@ 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

@@ -1,54 +0,0 @@
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)
})
}
}

View File

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

View File

@@ -11,11 +11,14 @@ import (
// DefaultEmacsEntitlements is the default set of entitlements application
// bundles are signed with if no entitlements are provided.
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.developer.mail-client",
"com.apple.developer.web-browser",
"com.apple.security.automation.apple-events",
"com.apple.security.cs.allow-dyld-environment-variables",
"com.apple.security.cs.allow-jit",
"com.apple.security.cs.disable-library-validation",
"com.apple.security.network.client",
"com.apple.security.network.server",
}
//go:embed entitlements.tpl

View File

@@ -47,11 +47,14 @@ var entitlementsTestCases = []struct {
{
name: "many",
entitlements: Entitlements{
"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.developer.mail-client",
"com.apple.developer.web-browser",
"com.apple.security.automation.apple-events",
"com.apple.security.cs.allow-dyld-environment-variables",
"com.apple.security.cs.allow-jit",
"com.apple.security.cs.disable-library-validation",
"com.apple.security.network.client",
"com.apple.security.network.server",
},
//nolint:lll
want: undent.String(`
@@ -59,15 +62,21 @@ var entitlementsTestCases = []struct {
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<key>com.apple.developer.mail-client</key>
<true/>
<key>com.apple.security.network.client</key>
<key>com.apple.developer.web-browser</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
</dict>
</plist>`,
@@ -78,11 +87,14 @@ var entitlementsTestCases = []struct {
func TestDefaultEmacsEntitlements(t *testing.T) {
assert.Equal(t,
[]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.developer.mail-client",
"com.apple.developer.web-browser",
"com.apple.security.automation.apple-events",
"com.apple.security.cs.allow-dyld-environment-variables",
"com.apple.security.cs.allow-jit",
"com.apple.security.cs.disable-library-validation",
"com.apple.security.network.client",
"com.apple.security.network.server",
},
DefaultEmacsEntitlements,
)