mirror of
https://github.com/jimeh/build-emacs-for-macos.git
synced 2026-02-19 13:06:38 +00:00
Specifically support latest changes in master which places *.eln files within the .app bundle in "Contents/Frameworks".
142 lines
3.4 KiB
Go
142 lines
3.4 KiB
Go
package sign
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/go-hclog"
|
|
)
|
|
|
|
// Emacs signs a Emacs.app application bundle with Apple's codesign utility,
|
|
// using correct default entitlements, and also pre-signing any *.eln files
|
|
// which are in the bundle, as codesign will not detect them as requiring
|
|
// signing even with the --deep flag.
|
|
func Emacs(ctx context.Context, appBundle string, opts *Options) error {
|
|
if !strings.HasSuffix(appBundle, ".app") {
|
|
return fmt.Errorf("%s is not a .app application bundle", appBundle)
|
|
}
|
|
|
|
appBundle, err := filepath.Abs(appBundle)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = os.Stat(appBundle)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
logger := hclog.FromContext(ctx).Named("sign")
|
|
logger.Info("preparing to sign Emacs.app", "app", appBundle)
|
|
|
|
newOpts := *opts
|
|
|
|
if newOpts.EntitlementsFile == "" {
|
|
if newOpts.Entitlements == nil {
|
|
e := Entitlements(DefaultEmacsEntitlements)
|
|
newOpts.Entitlements = &e
|
|
}
|
|
|
|
f, err2 := newOpts.Entitlements.TempFile()
|
|
if err2 != nil {
|
|
return err2
|
|
}
|
|
defer os.Remove(f)
|
|
|
|
newOpts.EntitlementsFile = f
|
|
newOpts.Entitlements = nil
|
|
}
|
|
|
|
err = signElnFiles(ctx, appBundle, &newOpts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = signCLIHelper(ctx, appBundle, &newOpts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Ensure app bundle is signed last, as modifications to the bundle after
|
|
// signing will invalidate the signature. Hence anything within it that
|
|
// needs to be separately signed, has to happen before signing the whole
|
|
// application bundle.
|
|
return Files(ctx, []string{appBundle}, &newOpts)
|
|
}
|
|
|
|
func signElnFiles(ctx context.Context, appBundle string, opts *Options) error {
|
|
logger := hclog.FromContext(ctx).Named("sign")
|
|
|
|
elnFiles, err := elnFiles(appBundle)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(elnFiles) == 0 {
|
|
return nil
|
|
}
|
|
|
|
logger.Info(fmt.Sprintf(
|
|
"found %d native-lisp *.eln files in %s to sign",
|
|
len(elnFiles), filepath.Base(appBundle),
|
|
))
|
|
for _, file := range elnFiles {
|
|
err := Files(ctx, []string{file}, opts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func signCLIHelper(ctx context.Context, appBundle string, opts *Options) error {
|
|
logger := hclog.FromContext(ctx).Named("sign")
|
|
|
|
cliHelper := filepath.Join(appBundle, "Contents", "MacOS", "bin", "emacs")
|
|
fi, err := os.Stat(cliHelper)
|
|
if err != nil && !os.IsNotExist(err) {
|
|
return err
|
|
} else if err == nil && fi.Mode().IsRegular() {
|
|
logger.Info(fmt.Sprintf(
|
|
"found Contents/MacOS/bin/emacs CLI helper script in %s to sign",
|
|
filepath.Base(appBundle),
|
|
))
|
|
|
|
err = Files(ctx, []string{cliHelper}, opts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// elnFiles finds all native-compilation *.eln files within a Emacs.app bundle,
|
|
// excluding any *.eln which should be automatically located by codesign when
|
|
// signing the Emacs.app bundle itself with the --deep flag. Essentially this
|
|
// only returns *.eln files which must be individually signed before signing the
|
|
// app bundle itself.
|
|
func elnFiles(emacsApp string) ([]string, error) {
|
|
var files []string
|
|
walkDirFunc := func(path string, d fs.DirEntry, _err error) error {
|
|
if d.Type().IsRegular() && strings.HasSuffix(path, ".eln") &&
|
|
!strings.Contains(path, ".app/Contents/Frameworks/") {
|
|
files = append(files, path)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
err := filepath.WalkDir(filepath.Join(emacsApp, "Contents"), walkDirFunc)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return files, nil
|
|
}
|