summaryrefslogtreecommitdiffstats
path: root/comm/python/thirdroc/rnp_generated.py
blob: 9c3390e4b91655919a5ed406b6857659cee2a3af (plain)
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
#  This Source Code Form is subject to the terms of the Mozilla Public
#  License, v. 2.0. If a copy of the MPL was not distributed with this
#  file, You can obtain one at https://mozilla.org/MPL/2.0/.

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import argparse
import os
import sys

from packaging.version import parse

from mozbuild.preprocessor import Preprocessor
from mozbuild.util import FileAvoidWrite, ensureParentDir

from thirdroc.cmake_define_files import define_type, process_cmake_define_file


def rnp_version(version_file, thunderbird_version):
    """
    Update RNP source files: generate version.h
    :param string version_file:
    """
    with open(version_file) as fp:
        version_str = fp.readline(512).strip()

    version = parse(version_str)
    version_major = version.major
    version_minor = version.minor
    version_patch = version.micro

    version_full = f"{version_str}.MZLA.{thunderbird_version}"

    defines = dict(
        RNP_VERSION_MAJOR=version_major,
        RNP_VERSION_MINOR=version_minor,
        RNP_VERSION_PATCH=version_patch,
        RNP_VERSION=version_str,
        RNP_VERSION_FULL=version_full,
        # Follow upstream's example when commit info is unavailable
        RNP_VERSION_COMMIT_TIMESTAMP="0",
        PACKAGE_STRING=f'"rnp {version_full}"',
    )

    return defines


def rnp_preprocess(tmpl, dest, defines):
    """
    Generic preprocessing
    :param BinaryIO tmpl: open filehandle (read) input
    :param BinaryIO dest: open filehandle (write) output
    :param dict defines: result of get_defines()
    :return boolean:
    """
    pp = Preprocessor()
    pp.setMarker("%")
    pp.addDefines(defines)
    pp.do_filter("substitution")
    pp.out = dest
    pp.do_include(tmpl, True)
    return True


def generate_version_h(output, template, defines):
    """
    Generate version.h for rnp from a the template file, write the
    result to destination.
    :param string template: path to template file (version.h.in)
    :param string destination: path to write generated file (version.h)
    :param dict defines: result of get_defines()
    """
    with open(template) as tmpl:
        rnp_preprocess(tmpl, output, defines)


def main(output, *argv):
    parser = argparse.ArgumentParser(description="Preprocess RNP files.")

    parser.add_argument("version_h_in", help="version.h.in")
    parser.add_argument("config_h_in", help="config.h.in")
    parser.add_argument("-m", type=str, dest="thunderbird_version", help="Thunderbird version")
    parser.add_argument("-V", type=str, dest="version_file", help="Path to RNP version.txt")
    parser.add_argument(
        "-D",
        type=define_type,
        action="append",
        dest="extra_defines",
        default=[],
        help="Additional defines not set at configure time.",
    )

    args = parser.parse_args(argv)

    defines = rnp_version(args.version_file, args.thunderbird_version)

    # "output" is an open filedescriptor for version.h
    generate_version_h(output, args.version_h_in, defines)

    # We must create the remaining output files ourselves. This requires
    # creating the output directory directly if it doesn't already exist.
    ensureParentDir(output.name)
    parent_dir = os.path.dirname(output.name)

    # For config.h, include defines set for version.h and extra -D args
    config_h_defines = dict(args.extra_defines)
    config_h_defines.update(defines)

    with FileAvoidWrite(os.path.join(parent_dir, "config.h")) as fd:
        process_cmake_define_file(fd, args.config_h_in, config_h_defines)


if __name__ == "__main__":
    sys.exit(main(*sys.argv))