Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  make-source-package.py   Sprache: Python

 
#!/usr/bin/env -S python3 -B
# 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 enum
import logging
import os
import shutil
import subprocess
import sys
from pathlib import Path

logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.INFO)


def find_command(names):
    """Search for command in `names`, and returns the first one that exists."""

    for name in names:
        path = shutil.which(name)
        if path is not None:
            return name

    return None


def assert_command(env_var, name):
    """Assert that the command is not empty
    The command name comes from either environment variable or find_command.
    """
    if not name:
        logging.error("{} command not found".format(env_var))
        sys.exit(1)


def parse_version(topsrc_dir):
    """Parse milestone.txt and return the entire milestone and major version."""
    milestone_file = topsrc_dir / "config" / "milestone.txt"
    if not milestone_file.is_file():
        return ("""""")

    with milestone_file.open("r"as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            if line.startswith("#"):
                continue

            v = line.split(".")
            return tuple((v + [""""])[:3])

    return ("""""")


tmp_dir = Path("/tmp")

tar = os.environ.get("TAR", find_command(["tar"]))
assert_command("TAR", tar)

rsync = os.environ.get("RSYNC", find_command(["rsync"]))
assert_command("RSYNC", rsync)

m4 = os.environ.get("M4", find_command(["m4"]))
assert_command("M4", m4)

awk = os.environ.get("AWK", find_command(["awk"]))
assert_command("AWK", awk)

src_dir = Path(os.environ.get("SRC_DIR", Path(__file__).parent.absolute()))
mozjs_name = os.environ.get("MOZJS_NAME""mozjs")
staging_dir = Path(os.environ.get("STAGING", tmp_dir / "mozjs-src-pkg"))
dist_dir = Path(os.environ.get("DIST", tmp_dir))
topsrc_dir = src_dir.parent.parent.absolute()

parsed_major_version, parsed_minor_version, parsed_patch_version = parse_version(
    topsrc_dir
)

major_version = os.environ.get("MOZJS_MAJOR_VERSION", parsed_major_version)
minor_version = os.environ.get("MOZJS_MINOR_VERSION", parsed_minor_version)
patch_version = os.environ.get("MOZJS_PATCH_VERSION", parsed_patch_version)
alpha = os.environ.get("MOZJS_ALPHA""")

version = "{}-{}.{}.{}".format(
    mozjs_name, major_version, minor_version, patch_version or alpha or "0"
)
target_dir = staging_dir / version
package_name = "{}.tar.xz".format(version)
package_file = dist_dir / package_name
tar_opts = ["-Jcf"]

# Given there might be some external program that reads the following output,
# use raw `print`, instead of logging.
print("Environment:")
print(" TAR = {}".format(tar))
print(" RSYNC = {}".format(rsync))
print(" M4 = {}".format(m4))
print(" AWK = {}".format(awk))
print(" STAGING = {}".format(staging_dir))
print(" DIST = {}".format(dist_dir))
print(" SRC_DIR = {}".format(src_dir))
print(" MOZJS_NAME = {}".format(mozjs_name))
print(" MOZJS_MAJOR_VERSION = {}".format(major_version))
print(" MOZJS_MINOR_VERSION = {}".format(minor_version))
print(" MOZJS_PATCH_VERSION = {}".format(patch_version))
print(" MOZJS_ALPHA = {}".format(alpha))
print("")

rsync_filter_list = """
# Top-level config and build files

+ /aclocal.m4
+ /client.mk
+ /configure.py
+ /LICENSE
+ /mach
+ /Makefile.in
+ /moz.build
+ /moz.configure
+ /test.mozbuild
+ /.babel-eslint.rc.js
+ /.eslintrc*.js
+ /.flake8
+ /.gitignore
+ /.hgignore
+ /.lldbinit
+ /.prettierignore
+ /.prettierrc
+ /.ycm_extra_conf.py

# Additional libraries (optionally) used by SpiderMonkey

+ /mfbt/**
+ /nsprpub/**

+ /intl/bidi/**

- /intl/icu/source/data
- /intl/icu/source/test
- /intl/icu/source/tools
+ /intl/icu/**

+ /intl/icu_capi/**
+ /intl/icu_segmenter_data/**

- /intl/components/gtest
+ /intl/components/**

+ /memory/replace/dmd/dmd.py
+ /memory/build/**
+ /memory/moz.build
+ /memory/mozalloc/**

+ /modules/fdlibm/**
+ /modules/zlib/**

+ /mozglue/baseprofiler/**
+ /mozglue/build/**
+ /mozglue/interposers/**
+ /mozglue/misc/**
+ /mozglue/moz.build
+ /mozglue/static/**

+ /tools/rb/fix_stacks.py
+ /tools/fuzzing/moz.build
+ /tools/fuzzing/interface/**
+ /tools/fuzzing/registry/**
+ /tools/fuzzing/libfuzzer/**
+ /tools/fuzzing/*.mozbuild

# Build system and dependencies

+ /Cargo.lock
+ /build/**
+ /config/**
+ /python/**

+ /.cargo/config.toml.in

+ /third_party/fmt/**
+ /third_party/function2/**
- /third_party/python/gyp
+ /third_party/python/**
+ /third_party/rust/**
+ /third_party/gemmology/**
+ /third_party/xsimd/**
+ /layout/tools/reftest/reftest/**

+ /testing/mach_commands.py
+ /testing/moz.build
+ /testing/mozbase/**
+ /testing/mozharness/**
+ /testing/performance/**
+ /testing/test/**
+ /testing/web-platform/*.ini
+ /testing/web-platform/*.py
+ /testing/web-platform/meta/streams/**
+ /testing/web-platform/mozilla/**
+ /testing/web-platform/tests/resources/**
+ /testing/web-platform/tests/streams/**
+ /testing/web-platform/tests/tools/**

+ /toolkit/crashreporter/tools/symbolstore.py
+ /toolkit/mozapps/installer/package-name.mk

+ /xpcom/geckoprocesstypes_generator/**

# List of prefs.
+ /modules/libpref/init/StaticPrefList.yaml

# SpiderMonkey itself

+ /js/src/**
+ /js/app.mozbuild
+ /js/*.configure
+ /js/examples/**
+ /js/public/**

+ */
- /**
"""

INSTALL_CONTENT = """\
Documentation for SpiderMonkey is available at:

  https://spidermonkey.dev/

In particular, it points to build documentation at

  https://firefox-source-docs.mozilla.org/js/build.html

Note that the libraries produced by the build system include symbols,
causing the binaries to be extremely large. It is highly suggested that `strip`
be run over the binaries before deploying them.

Building with default options may be performed as follows:

  ./mach build

This will produce a debug build (much more suitable for developing against the
SpiderMonkey JSAPI). To produce an optimized build:

  export MOZCONFIG=$(pwd)/mozconfig.opt
  ./mach build

You may edit the mozconfig and mozconfig.opt files to configure your own build
appropriately.
"""

MOZCONFIG_DEBUG_CONTENT = """\
# Much slower when running, but adds assertions that are much better for
# developing against the JSAPI.
ac_add_options --enable-debug

# Much faster when running, worse for debugging.
ac_add_options --enable-optimize

mk_add_options MOZ_OBJDIR=obj-debug
"""

MOZCONFIG_OPT_CONTENT = """\
# Much faster when running, but very error-prone to develop against because
# this will skip all the assertions critical to using the JSAPI properly.
ac_add_options --disable-debug

# Much faster when running, worse for debugging.
ac_add_options --enable-optimize

mk_add_options MOZ_OBJDIR=obj-opt
"""

README_CONTENT = """\
This directory contains SpiderMonkey {major_version}.

This release is based on a revision of Mozilla {major_version}:
  https://hg.mozilla.org/releases/
The changes in the patches/ directory were applied.

See https://spidermonkey.dev/ for documentation, examples, and release notes.
""".format(
    major_version=major_version
)


def is_mozjs_cargo_member(line):
    """Checks if the line in workspace.members is mozjs-related"""

    return '"js/' in line


def is_mozjs_crates_io_local_patch(line):
    """Checks if the line in patch.crates-io is mozjs-related"""

    return any(
        f'path = "{p}' in line for p in ("js""build""third_party/rust""intl")
    )


def clean():
    """Remove temporary directory and package file."""
    logging.info("Cleaning {} and {} ...".format(package_file, target_dir))
    if package_file.exists():
        package_file.unlink()
    if target_dir.exists():
        shutil.rmtree(str(target_dir))


def assert_clean():
    """Assert that target directory does not contain generated files."""
    makefile_file = target_dir / "js" / "src" / "Makefile"
    if makefile_file.exists():
        logging.error("found js/src/Makefile. Please clean before packaging.")
        sys.exit(1)


def create_target_dir():
    if target_dir.exists():
        logging.warning("dist tree {} already exists!".format(target_dir))
    else:
        target_dir.mkdir(parents=True)


def sync_files():
    # Output of the command should directly go to stdout/stderr.
    p = subprocess.Popen(
        [
            str(rsync),
            "--delete-excluded",
            "--prune-empty-dirs",
            "--quiet",
            "--recursive",
            "{}/".format(topsrc_dir),
            "{}/".format(target_dir),
            "--filter=. -",
        ],
        stdin=subprocess.PIPE,
    )

    p.communicate(rsync_filter_list.encode())

    if p.returncode != 0:
        sys.exit(p.returncode)


def copy_cargo_toml():
    cargo_toml_file = topsrc_dir / "Cargo.toml"
    target_cargo_toml_file = target_dir / "Cargo.toml"

    with cargo_toml_file.open("r"as f:

        class State(enum.Enum):
            BEFORE_MEMBER = 1
            INSIDE_MEMBER = 2
            AFTER_MEMBER = 3
            INSIDE_PATCH = 4
            AFTER_PATCH = 5

        content = ""
        state = State.BEFORE_MEMBER
        for line in f:
            if state == State.BEFORE_MEMBER:
                if line.strip() == "members = [":
                    state = State.INSIDE_MEMBER
            elif state == State.INSIDE_MEMBER:
                if line.strip() == "]":
                    state = State.AFTER_MEMBER
                elif not is_mozjs_cargo_member(line):
                    continue
            elif state == State.AFTER_MEMBER:
                if line.strip() == "[patch.crates-io]":
                    state = State.INSIDE_PATCH
            elif state == State.INSIDE_PATCH:
                if line.startswith("["):
                    state = State.AFTER_PATCH
                if "path = " in line:
                    if not is_mozjs_crates_io_local_patch(line):
                        continue

            content += line

    with target_cargo_toml_file.open("w"as f:
        f.write(content)


def generate_configure():
    """Generate configure files to avoid build dependency on autoconf-2.13"""

    src_old_configure_in_file = topsrc_dir / "js" / "src" / "old-configure.in"
    dest_old_configure_file = target_dir / "js" / "src" / "old-configure"

    js_src_dir = topsrc_dir / "js" / "src"

    env = os.environ.copy()
    env["M4"] = m4
    env["AWK"] = awk
    env["AC_MACRODIR"] = topsrc_dir / "build" / "autoconf"

    with dest_old_configure_file.open("w"as f:
        subprocess.run(
            [
                "sh",
                str(topsrc_dir / "build" / "autoconf" / "autoconf.sh"),
                "--localdir={}".format(js_src_dir),
                str(src_old_configure_in_file),
            ],
            stdout=f,
            check=True,
            env=env,
        )


def copy_file(filename, content):
    """Copy an existing file from the staging area, or create a new file
    with the given contents if it does not exist."""

    staging_file = staging_dir / filename
    target_file = target_dir / filename

    if staging_file.exists():
        shutil.copy2(str(staging_file), str(target_file))
    else:
        with target_file.open("w"as f:
            f.write(content)


def copy_patches():
    """Copy patches dir, if it exists."""

    staging_patches_dir = staging_dir / "patches"
    top_patches_dir = topsrc_dir / "patches"
    target_patches_dir = target_dir / "patches"

    if staging_patches_dir.is_dir():
        shutil.copytree(str(staging_patches_dir), str(target_patches_dir))
    elif top_patches_dir.is_dir():
        shutil.copytree(str(top_patches_dir), str(target_patches_dir))


def remove_python_cache():
    """Remove *.pyc and *.pyo files if any."""
    for f in target_dir.glob("**/*.pyc"):
        f.unlink()
    for f in target_dir.glob("**/*.pyo"):
        f.unlink()


def stage():
    """Stage source tarball content."""
    logging.info("Staging source tarball in {}...".format(target_dir))

    create_target_dir()
    sync_files()
    copy_cargo_toml()
    generate_configure()
    copy_file("INSTALL", INSTALL_CONTENT)
    copy_file("README", README_CONTENT)
    copy_file("mozconfig", MOZCONFIG_DEBUG_CONTENT)
    copy_file("mozconfig.opt", MOZCONFIG_OPT_CONTENT)
    copy_patches()
    remove_python_cache()


def create_tar():
    """Roll the tarball."""

    logging.info("Packaging source tarball at {}...".format(package_file))

    subprocess.run(
        [str(tar)] + tar_opts + [str(package_file), "-C", str(staging_dir), version],
        check=True,
    )


def build():
    assert_clean()
    stage()
    create_tar()


parser = argparse.ArgumentParser(description="Make SpiderMonkey source package")
subparsers = parser.add_subparsers(dest="COMMAND")
subparser_update = subparsers.add_parser("clean", help="")
subparser_update = subparsers.add_parser("build", help="")
args = parser.parse_args()

if args.COMMAND == "clean":
    clean()
elif not args.COMMAND or args.COMMAND == "build":
    build()

Messung V0.5
C=97 H=86 G=91

¤ Dauer der Verarbeitung: 0.26 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge