aboutsummaryrefslogtreecommitdiff
path: root/scripts/build-homebrew-formula.py
blob: 852b4b640bcaa91fe717dec67b85279230e9b489 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3

# Yes, this is a Python program writing a Ruby program.

import argparse
import hashlib
import sys
import os

parser = argparse.ArgumentParser()
parser.add_argument("--url-base",  default = "https://brew.cryptech.is/tarballs/")
parser.add_argument("--tarball",   required = True)
parser.add_argument("--package",   required = True)
parser.add_argument("--version",   required = True)
parser.add_argument("--formula",   type = argparse.FileType("w"), nargs = "?", default = sys.stdout)
parser.add_argument("--conflicts", default = "")
args = parser.parse_args()

template = '''\
# This Homebrew forumula was automatically generated by a script.
# You might not want to edit it manually.
#
# Installation is a bit complex due to the way Homebrew handles Python
# library dependencies and due to our stuff being a mixture of Python
# and C.  It's also painfully slow, because we're not using bottles,
# due to lack of a MacOS build farm.  Sorry.
#
# Per Homebrew expectations, we install copies of external Python
# libraries ("resources") in our own private library directory, using
# Homebrew's hack to run our executable Python scripts with PYTHONPATH
# pointing to our private library directory.  Our own Python library
# code, however, is what Homebrew considers "bindings", so we install
# those where user scripts as well as our own can find them...then we
# add a symlink so that our scripts can find our bindings regardless
# of which copy of Python Homebrew decides we should use this week.
#
# We have to build our own software before installing our Python code,
# because at least one of the Python modules we install
# (cryptech.py11.attribute_map) is generated during the build.
#
# Reference for all the documented Python Homebrew voodoo:
#
# http://docs.brew.sh/Python-for-Formula-Authors.html
#
# Reference for undocumented Python Homebrew voodoo:
#
# /usr/local/Homebrew/Library/Homebrew/language/python.rb

class {classname} < Formula

  desc     "Software for working with Cryptech Alpha board HSM"
  homepage "https://cryptech.is/"
  version  "{version}"
  url      "{url}"
  sha256   "{sha256}"

  depends_on "python@3.8"

{conflicts}

  resource "pyserial" do
    url    "https://pypi.python.org/packages/3c/d8/a9fa247ca60b02b3bebbd61766b4f321393b57b13c53b18f6f62cf172c08/pyserial-3.1.1.tar.gz"
    sha256 "d657051249ce3cbd0446bcfb2be07a435e1029da4d63f53ed9b4cdde7373364c"
  end

  resource "PyYAML" do
    url    "http://pyyaml.org/download/pyyaml/PyYAML-3.11.tar.gz"
    sha256 "c36c938a872e5ff494938b33b14aaa156cb439ec67548fcab3535bb78b0846e8"
  end

  resource "tornado" do
    url    "https://files.pythonhosted.org/packages/source/t/tornado/tornado-4.4.3.tar.gz"
    sha256 "f267acc96d5cf3df0fd8a7bfb5a91c2eb4ec81d5962d1a7386ceb34c655634a8"
  end

  resource "singledispatch" do
    url    "https://pypi.python.org/packages/source/s/singledispatch/singledispatch-3.4.0.3.tar.gz"
    sha256 "5b06af87df13818d14f08a028e42f566640aef80805c3b50c5056b086e3c2b9c"
  end

  resource "backports_abc" do
    url    "https://files.pythonhosted.org/packages/source/b/backports_abc/backports_abc-0.5.tar.gz"
    sha256 "033be54514a03e255df75c5aee8f9e672f663f93abb723444caec8fe43437bde"
  end

  resource "pycrypto" do
    url    "https://pypi.python.org/packages/source/p/pycrypto/pycrypto-2.6.1.tar.gz"
    sha256 "f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c"
  end

  def install

    xy = Language::Python.major_minor_version "python3"

    ENV.prepend_create_path "PYTHONPATH", libexec/"vendor/lib/python#{xy}/site-packages"

    resources.each do |r|
      r.stage do
        system "python3", *Language::Python.setup_install_args(libexec/"vendor")
      end
    end

    ohai "Building PKCS #11 code (including crypto and bignum libraries) from source, this is slow, please be patient..."
    ENV.deparallelize
    system "make", "-C", "sw/pkcs11"

    system "python", *Language::Python.setup_install_args(prefix)
    bin.env_script_all_files(libexec/"bin", :PYTHONPATH => ENV["PYTHONPATH"])

    ln_s lib/"python#{xy}/site-packages/cryptech", libexec/"vendor/lib/python#{xy}/site-packages/cryptech"

    share.install "cryptech-alpha-firmware.tar.gz"
    lib.install   "sw/pkcs11/libcryptech-pkcs11.dylib"

  end

end
'''

with open(args.tarball, "rb") as f:
    digest = hashlib.sha256(f.read()).hexdigest()

classname = "".join(word.capitalize() for word in args.package.split("-"))

conflicts = "".join("  conflicts_with \"{}\", :because => \"HSM firmware and PKCS #11 library must match\"\n".format(conflict)
                    for conflict in args.conflicts.split())

url = os.path.join(args.url_base, os.path.basename(args.tarball))

args.formula.write(template.format(
    version   = args.version,
    url       = url,
    sha256    = digest,
    classname = classname,
    conflicts = conflicts))