mirror of
https://github.com/jimeh/build-emacs-for-macos.git
synced 2026-02-19 13:06:38 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
6d7ab95ca2
|
|||
|
f4d6e3a56d
|
|||
|
3f1059940d
|
|||
|
5c722e36c5
|
|||
|
f52dd8dc6d
|
|||
|
4cdbaf1ec0
|
16
CHANGELOG.md
16
CHANGELOG.md
@@ -2,6 +2,22 @@
|
||||
|
||||
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.8](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.7...v0.6.8) (2021-07-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **builds:** add support for stable builds ([f4d6e3a](https://github.com/jimeh/build-emacs-for-macos/commit/f4d6e3a56d2c15b0c86af18e8d16bebbeb92a8ab))
|
||||
|
||||
### [0.6.7](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.6...v0.6.7) (2021-07-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bundle:** move bundled shared libraries to Contents/Frameworks ([5c722e3](https://github.com/jimeh/build-emacs-for-macos/commit/5c722e36c571aa7bf558b7f210c011f12d8d8a1c))
|
||||
|
||||
### [0.6.6](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.5...v0.6.6) (2021-07-01)
|
||||
|
||||
### [0.6.5](https://github.com/jimeh/build-emacs-for-macos/compare/v0.6.4...v0.6.5) (2021-07-01)
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ require 'net/http'
|
||||
require 'optparse'
|
||||
require 'pathname'
|
||||
require 'time'
|
||||
require 'tmpdir'
|
||||
require 'uri'
|
||||
require 'yaml'
|
||||
|
||||
@@ -735,8 +736,6 @@ class AbstractEmbedder
|
||||
@app = app
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def invocation_dir
|
||||
File.join(app, 'Contents', 'MacOS')
|
||||
end
|
||||
@@ -746,7 +745,7 @@ class AbstractEmbedder
|
||||
end
|
||||
|
||||
def lib_dir
|
||||
File.join(invocation_dir, 'lib')
|
||||
File.join(app, 'Contents', 'Frameworks')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -902,15 +901,15 @@ class GccLibEmbedder < AbstractEmbedder
|
||||
end
|
||||
|
||||
def target_dir
|
||||
File.join(invocation_dir, gcc_info.relative_lib_dir)
|
||||
File.join(lib_dir, gcc_info.relative_lib_dir)
|
||||
end
|
||||
|
||||
def source_darwin_dir
|
||||
File.join(invocation_dir, gcc_info.relative_darwin_lib_dir)
|
||||
File.join(lib_dir, gcc_info.relative_darwin_lib_dir)
|
||||
end
|
||||
|
||||
def target_darwin_dir
|
||||
File.join(invocation_dir, gcc_info.sanitized_relative_darwin_lib_dir)
|
||||
File.join(lib_dir, gcc_info.sanitized_relative_darwin_lib_dir)
|
||||
end
|
||||
|
||||
def source_dir
|
||||
@@ -966,7 +965,21 @@ class GccInfo
|
||||
def sanitized_relative_darwin_lib_dir
|
||||
@sanitized_relative_darwin_lib_dir ||= File.join(
|
||||
File.dirname(relative_darwin_lib_dir),
|
||||
File.basename(relative_darwin_lib_dir).split('.').first
|
||||
File.basename(relative_darwin_lib_dir).gsub('.', '_')
|
||||
)
|
||||
end
|
||||
|
||||
def app_bundle_relative_lib_dir
|
||||
@app_bundle_relative_lib_dir ||= relative_dir(
|
||||
File.join(embedder.lib_dir, relative_lib_dir),
|
||||
embedder.invocation_dir
|
||||
)
|
||||
end
|
||||
|
||||
def app_bundle_relative_darwin_lib_dir
|
||||
@app_bundle_relative_darwin_lib_dir ||= relative_dir(
|
||||
File.join(embedder.lib_dir, sanitized_relative_darwin_lib_dir),
|
||||
embedder.invocation_dir
|
||||
)
|
||||
end
|
||||
|
||||
@@ -1013,6 +1026,10 @@ class GccInfo
|
||||
|
||||
private
|
||||
|
||||
def embedder
|
||||
@embedder ||= AbstractEmbedder.new(Dir.mktmpdir(['Emacs', '.app']))
|
||||
end
|
||||
|
||||
def relative_dir(path, root)
|
||||
Pathname.new(path).relative_path_from(Pathname.new(root)).to_s
|
||||
end
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
|
||||
index 8c638312b0..87af889ef4 100644
|
||||
index 638d4b274c..2599211936 100644
|
||||
--- a/lisp/emacs-lisp/comp.el
|
||||
+++ b/lisp/emacs-lisp/comp.el
|
||||
@@ -4215,6 +4215,52 @@ native-compile-async
|
||||
@@ -4224,6 +4224,52 @@ native-compile-async
|
||||
(let ((load (not (not load))))
|
||||
(native--compile-async files recursively load selector)))
|
||||
|
||||
@@ -16,10 +16,10 @@ index 8c638312b0..87af889ef4 100644
|
||||
+ (devtools-dir
|
||||
+ "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib")
|
||||
+ (gcc-dir (expand-file-name
|
||||
+ "<%= relative_lib_dir %>"
|
||||
+ "<%= app_bundle_relative_lib_dir %>"
|
||||
+ invocation-directory))
|
||||
+ (darwin-dir (expand-file-name
|
||||
+ "<%= sanitized_relative_darwin_lib_dir %>"
|
||||
+ "<%= app_bundle_relative_darwin_lib_dir %>"
|
||||
+ invocation-directory))
|
||||
+ (lib-paths (list)))
|
||||
+
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/hexops/gotextdiff/myers"
|
||||
"github.com/hexops/gotextdiff/span"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/gh"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/release"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/repository"
|
||||
)
|
||||
|
||||
@@ -42,11 +43,11 @@ type UpdateOptions struct {
|
||||
// BuildsRepo is the GitHub repository containing binary releases.
|
||||
BuildsRepo *repository.Repository
|
||||
|
||||
// TapRepo is the GitHub repository to update the cask formula in.
|
||||
// TapRepo is the GitHub repository to update the casks in.
|
||||
TapRepo *repository.Repository
|
||||
|
||||
// Ref is the git ref to apply cask formula updates on top of. Default
|
||||
// branch will be used if empty.
|
||||
// Ref is the git ref to apply cask updates on top of. Default branch will
|
||||
// be used if empty.
|
||||
Ref string
|
||||
|
||||
// OutputDir specifies a directory to write cask files to. When set, tap
|
||||
@@ -56,10 +57,10 @@ type UpdateOptions struct {
|
||||
|
||||
// Force update will ignore the outdated live check flag, and process all
|
||||
// casks regardless. But it will only update the cask in question if the
|
||||
// resulting output cask formula is different.
|
||||
// resulting output cask is different.
|
||||
Force bool
|
||||
|
||||
// TemplatesDir is the directory where cask formula templates are located.
|
||||
// TemplatesDir is the directory where cask templates are located.
|
||||
TemplatesDir string
|
||||
|
||||
LiveChecks []*LiveCheck
|
||||
@@ -150,7 +151,7 @@ func (s *Updater) putFile(
|
||||
content []byte,
|
||||
) (bool, error) {
|
||||
parent := filepath.Dir(filename)
|
||||
s.logger.Info("processing formula update",
|
||||
s.logger.Info("processing cask update",
|
||||
"output-directory", parent, "cask", chk.Cask, "file", filename,
|
||||
)
|
||||
|
||||
@@ -164,18 +165,18 @@ func (s *Updater) putFile(
|
||||
return false, err
|
||||
}
|
||||
|
||||
infoMsg := "creating formula"
|
||||
infoMsg := "creating cask"
|
||||
|
||||
if !os.IsNotExist(err) {
|
||||
infoMsg = "updating formula"
|
||||
infoMsg = "updating cask"
|
||||
if bytes.Equal(existingContent, content) {
|
||||
s.logger.Info(
|
||||
"skip update: no change to cask formula content",
|
||||
"skip update: no change to cask content",
|
||||
"cask", chk.Cask, "file", filename,
|
||||
)
|
||||
|
||||
s.logger.Debug(
|
||||
"formula content",
|
||||
"cask content",
|
||||
"file", filename, "content", string(content),
|
||||
)
|
||||
|
||||
@@ -198,7 +199,7 @@ func (s *Updater) putFile(
|
||||
)
|
||||
|
||||
s.logger.Debug(
|
||||
"formula content",
|
||||
"cask content",
|
||||
"file", filename, "content", string(content),
|
||||
)
|
||||
|
||||
@@ -218,7 +219,7 @@ func (s *Updater) putRepoFile(
|
||||
filename string,
|
||||
content []byte,
|
||||
) (bool, error) {
|
||||
s.logger.Info("processing formula update",
|
||||
s.logger.Info("processing cask update",
|
||||
"tap-repo", repo.Source, "cask", chk.Cask, "file", filename,
|
||||
)
|
||||
repoContent, _, resp, err := s.gh.Repositories.GetContents(
|
||||
@@ -264,12 +265,12 @@ func (s *Updater) createRepoFile(
|
||||
diff := fmt.Sprint(gotextdiff.ToUnified(filename, filename, "", edits))
|
||||
|
||||
s.logger.Info(
|
||||
"creating formula",
|
||||
"creating cask",
|
||||
"cask", chk.Cask, "version", chk.Version.Latest, "file", filename,
|
||||
"diff", diff,
|
||||
)
|
||||
s.logger.Debug(
|
||||
"formula content",
|
||||
"cask content",
|
||||
"file", filename, "content", string(content),
|
||||
)
|
||||
contResp, _, err := s.gh.Repositories.CreateFile(
|
||||
@@ -307,7 +308,7 @@ func (s *Updater) updateRepoFile(
|
||||
|
||||
if existingContent == string(content) {
|
||||
s.logger.Info(
|
||||
"skip update: no change to formula content",
|
||||
"skip update: no change to cask content",
|
||||
"cask", chk.Cask, "file", filename,
|
||||
)
|
||||
|
||||
@@ -329,12 +330,12 @@ func (s *Updater) updateRepoFile(
|
||||
))
|
||||
|
||||
s.logger.Info(
|
||||
"updating formula",
|
||||
"updating cask",
|
||||
"cask", chk.Cask, "version", chk.Version.Latest, "file", filename,
|
||||
"diff", diff,
|
||||
)
|
||||
s.logger.Debug(
|
||||
"formula content",
|
||||
"cask content",
|
||||
"file", filename, "content", string(content),
|
||||
)
|
||||
|
||||
@@ -363,9 +364,14 @@ func (s *Updater) renderCask(
|
||||
ctx context.Context,
|
||||
chk *LiveCheck,
|
||||
) ([]byte, error) {
|
||||
releaseName := "Emacs." + chk.Version.Latest
|
||||
releaseName, err := release.VersionToName(chk.Version.Latest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.logger.Info("fetching release details", "release", releaseName)
|
||||
s.logger.Info("fetching release details",
|
||||
"release", releaseName, "repo", s.BuildsRepo.URL(),
|
||||
)
|
||||
release, resp, err := s.gh.Repositories.GetReleaseByTag(
|
||||
ctx, s.BuildsRepo.Owner(), s.BuildsRepo.Name(), releaseName,
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ func caskCmd() *cli2.Command {
|
||||
|
||||
return &cli2.Command{
|
||||
Name: "cask",
|
||||
Usage: "manage Homebrew Cask formula",
|
||||
Usage: "manage Homebrew Casks",
|
||||
Flags: []cli2.Flag{
|
||||
&cli2.StringFlag{
|
||||
Name: "builds-repository",
|
||||
@@ -101,7 +101,7 @@ func caskUpdateCmd() *cli2.Command {
|
||||
Name: "force",
|
||||
Aliases: []string{"f"},
|
||||
Usage: "force update file even if livecheck has it marked " +
|
||||
"as not outdated (does not force update if formula " +
|
||||
"as not outdated (does not force update if cask " +
|
||||
"content is unchanged)",
|
||||
Value: false,
|
||||
},
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/commit"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/gh"
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -64,15 +65,17 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
releaseName := fmt.Sprintf(
|
||||
"Emacs.%s.%s.%s",
|
||||
version := fmt.Sprintf(
|
||||
"%s.%s.%s",
|
||||
commitInfo.DateString(),
|
||||
commitInfo.ShortSHA(),
|
||||
sanitizeString(opts.Ref),
|
||||
)
|
||||
|
||||
releaseName := fmt.Sprintf("Emacs.%s", version)
|
||||
buildName := fmt.Sprintf(
|
||||
"%s.%s.%s",
|
||||
releaseName,
|
||||
"Emacs.%s.%s.%s",
|
||||
version,
|
||||
sanitizeString(osInfo.Name+"-"+osInfo.MajorMinor()),
|
||||
sanitizeString(osInfo.Arch),
|
||||
)
|
||||
@@ -92,7 +95,8 @@ func Create(ctx context.Context, opts *Options) (*Plan, error) {
|
||||
},
|
||||
OS: osInfo,
|
||||
Release: &Release{
|
||||
Name: releaseName,
|
||||
Name: releaseName,
|
||||
Prerelease: true,
|
||||
},
|
||||
Output: &Output{
|
||||
Directory: opts.OutputDir,
|
||||
@@ -100,6 +104,16 @@ 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)
|
||||
|
||||
|
||||
42
pkg/release/version.go
Normal file
42
pkg/release/version.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package release
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Errors
|
||||
var (
|
||||
Err = errors.New("release")
|
||||
ErrInvalidName = fmt.Errorf("%w: invalid name", Err)
|
||||
ErrEmptyVersion = fmt.Errorf("%w: empty version", Err)
|
||||
ErrNotStableRef = fmt.Errorf(
|
||||
"%w: git ref is not stable tagged release", Err,
|
||||
)
|
||||
)
|
||||
|
||||
var (
|
||||
stableVersion = regexp.MustCompile(`^\d+\.\d+(?:[a-z]+)?$`)
|
||||
stableGetRef = regexp.MustCompile(`^emacs-(\d+\.\d+(?:[a-z]+)?)$`)
|
||||
)
|
||||
|
||||
func VersionToName(version string) (string, error) {
|
||||
if version == "" {
|
||||
return "", ErrEmptyVersion
|
||||
}
|
||||
|
||||
if stableVersion.MatchString(version) {
|
||||
return "Emacs-" + version, nil
|
||||
}
|
||||
|
||||
return "Emacs." + version, nil
|
||||
}
|
||||
|
||||
func GitRefToStableVersion(ref string) (string, error) {
|
||||
if m := stableGetRef.FindStringSubmatch(ref); len(m) > 1 {
|
||||
return m[1], nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("%w: \"%s\"", ErrNotStableRef, ref)
|
||||
}
|
||||
138
pkg/release/version_test.go
Normal file
138
pkg/release/version_test.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package release
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestVersionToName(t *testing.T) {
|
||||
type args struct {
|
||||
version string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
args: args{
|
||||
version: "",
|
||||
},
|
||||
wantErr: "release: empty version",
|
||||
},
|
||||
{
|
||||
name: "nightly",
|
||||
args: args{
|
||||
version: "2021-07-01.1b88404.master",
|
||||
},
|
||||
want: "Emacs.2021-07-01.1b88404.master",
|
||||
},
|
||||
{
|
||||
name: "stable",
|
||||
args: args{
|
||||
version: "27.2",
|
||||
},
|
||||
want: "Emacs-27.2",
|
||||
},
|
||||
{
|
||||
name: "stable with letter",
|
||||
args: args{
|
||||
version: "23.3b",
|
||||
},
|
||||
want: "Emacs-23.3b",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := VersionToName(tt.args.version)
|
||||
|
||||
assert.Equal(t, tt.want, got)
|
||||
|
||||
if tt.wantErr != "" {
|
||||
assert.EqualError(t, err, tt.wantErr)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGitRefToStableVersion(t *testing.T) {
|
||||
type args struct {
|
||||
version string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
args: args{
|
||||
version: "",
|
||||
},
|
||||
wantErr: "release: git ref is not stable tagged release: \"\"",
|
||||
},
|
||||
{
|
||||
name: "master",
|
||||
args: args{
|
||||
version: "master",
|
||||
},
|
||||
wantErr: "release: git ref is not stable tagged release: " +
|
||||
"\"master\"",
|
||||
},
|
||||
{
|
||||
name: "feature",
|
||||
args: args{
|
||||
version: "feature/native-comp",
|
||||
},
|
||||
wantErr: "release: git ref is not stable tagged release: " +
|
||||
"\"feature/native-comp\"",
|
||||
},
|
||||
{
|
||||
name: "stable",
|
||||
args: args{
|
||||
version: "emacs-27.2",
|
||||
},
|
||||
want: "27.2",
|
||||
},
|
||||
{
|
||||
name: "stable with letter",
|
||||
args: args{
|
||||
version: "emacs-23.3b",
|
||||
},
|
||||
want: "23.3b",
|
||||
},
|
||||
{
|
||||
name: "future stable",
|
||||
args: args{
|
||||
version: "emacs-239.33",
|
||||
},
|
||||
want: "239.33",
|
||||
},
|
||||
{
|
||||
name: "future stable with letter",
|
||||
args: args{
|
||||
version: "emacs-239.33c",
|
||||
},
|
||||
want: "239.33c",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GitRefToStableVersion(tt.args.version)
|
||||
|
||||
assert.Equal(t, tt.want, got)
|
||||
|
||||
if tt.wantErr != "" {
|
||||
assert.EqualError(t, err, tt.wantErr)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user