]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/arrow/dev/archery/archery/utils/maven.py
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / dev / archery / archery / utils / maven.py
diff --git a/ceph/src/arrow/dev/archery/archery/utils/maven.py b/ceph/src/arrow/dev/archery/archery/utils/maven.py
new file mode 100644 (file)
index 0000000..96a3bf5
--- /dev/null
@@ -0,0 +1,204 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import os
+
+from .command import Command, default_bin
+
+
+class Maven(Command):
+    def __init__(self, maven_bin=None):
+        self.bin = default_bin(maven_bin, "mvn")
+
+
+maven = Maven()
+
+
+class MavenDefinition:
+    """ MavenDefinition captures the maven invocation arguments.
+
+    It allows creating build directories with the same definition, e.g.
+    ```
+    build_1 = maven_def.build("/tmp/build-1")
+    build_2 = maven_def.build("/tmp/build-2")
+
+    ...
+
+    build1.install()
+    build2.install()
+    """
+
+    def __init__(self, source, build_definitions=None,
+                 benchmark_definitions=None, env=None):
+        """ Initialize a MavenDefinition
+
+        Parameters
+        ----------
+        source : str
+                 Source directory where the top-level pom.xml is
+                 located. This is usually the root of the project.
+        build_definitions: list(str), optional
+        benchmark_definitions: list(str), optional
+        """
+        self.source = os.path.abspath(source)
+        self.build_definitions = build_definitions if build_definitions else []
+        self.benchmark_definitions =\
+            benchmark_definitions if benchmark_definitions else []
+        self.env = env
+
+    @property
+    def build_arguments(self):
+        """" Return the arguments to maven invocation for build. """
+        arguments = self.build_definitions + [
+            "-B", "-DskipTests", "-Drat.skip=true",
+            "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer."
+            "Slf4jMavenTransferListener=warn",
+            "-T", "2C", "install"
+        ]
+        return arguments
+
+    def build(self, build_dir, force=False, cmd_kwargs=None, **kwargs):
+        """ Invoke maven into a build directory.
+
+        Parameters
+        ----------
+        build_dir : str
+                    Directory in which the Maven build will be instantiated.
+        force : bool
+                not used now
+        """
+        if os.path.exists(build_dir):
+            # Extra safety to ensure we're deleting a build folder.
+            if not MavenBuild.is_build_dir(build_dir):
+                raise FileExistsError(
+                    "{} is not a maven build".format(build_dir)
+                )
+
+        cmd_kwargs = cmd_kwargs if cmd_kwargs else {}
+        assert MavenBuild.is_build_dir(build_dir)
+        maven(*self.build_arguments, cwd=build_dir, env=self.env, **cmd_kwargs)
+        return MavenBuild(build_dir, definition=self, **kwargs)
+
+    @property
+    def list_arguments(self):
+        """" Return the arguments to maven invocation for list """
+        arguments = [
+            "-Dskip.perf.benchmarks=false", "-Dbenchmark.list=-lp", "install"
+        ]
+        return arguments
+
+    @property
+    def benchmark_arguments(self):
+        """" Return the arguments to maven invocation for benchmark """
+        arguments = self.benchmark_definitions + [
+            "-Dskip.perf.benchmarks=false", "-Dbenchmark.fork=1",
+            "-Dbenchmark.jvmargs=\"-Darrow.enable_null_check_for_get=false "
+            "-Darrow.enable_unsafe_memory_access=true\"",
+            "install"
+        ]
+        return arguments
+
+    def __repr__(self):
+        return "MavenDefinition[source={}]".format(self.source)
+
+
+class MavenBuild(Maven):
+    """ MavenBuild represents a build directory initialized by maven.
+
+    The build instance can be used to build/test/install. It alleviates the
+    user to know which generator is used.
+    """
+
+    def __init__(self, build_dir, definition=None):
+        """ Initialize a MavenBuild.
+
+        The caller must ensure that maven was invoked in the build directory.
+
+        Parameters
+        ----------
+        definition : MavenDefinition
+                     The definition to build from.
+        build_dir : str
+                    The build directory to setup into.
+        """
+        assert MavenBuild.is_build_dir(build_dir)
+        super().__init__()
+        self.build_dir = os.path.abspath(build_dir)
+        self.definition = definition
+
+    @property
+    def binaries_dir(self):
+        return self.build_dir
+
+    def run(self, *argv, verbose=False, cwd=None, **kwargs):
+        extra = []
+        if verbose:
+            extra.append("-X")
+        if cwd is None:
+            cwd = self.build_dir
+        # Commands must be ran under the directory where pom.xml exists
+        return super().run(*extra, *argv, **kwargs, cwd=cwd)
+
+    def build(self, *argv, verbose=False, **kwargs):
+        definition_args = self.definition.build_arguments
+        cwd = self.binaries_dir
+        return self.run(*argv, *definition_args, verbose=verbose, cwd=cwd,
+                        env=self.definition.env, **kwargs)
+
+    def list(self, *argv, verbose=False, **kwargs):
+        definition_args = self.definition.list_arguments
+        cwd = self.binaries_dir + "/performance"
+        return self.run(*argv, *definition_args, verbose=verbose, cwd=cwd,
+                        env=self.definition.env, **kwargs)
+
+    def benchmark(self, *argv, verbose=False, **kwargs):
+        definition_args = self.definition.benchmark_arguments
+        cwd = self.binaries_dir + "/performance"
+        return self.run(*argv, *definition_args, verbose=verbose, cwd=cwd,
+                        env=self.definition.env, **kwargs)
+
+    @staticmethod
+    def is_build_dir(path):
+        """ Indicate if a path is Maven top directory.
+
+        This method only checks for the existence of paths and does not do any
+        validation whatsoever.
+        """
+        pom_xml = os.path.join(path, "pom.xml")
+        performance_dir = os.path.join(path, "performance")
+        return os.path.exists(pom_xml) and os.path.isdir(performance_dir)
+
+    @staticmethod
+    def from_path(path):
+        """ Instantiate a Maven from a path.
+
+        This is used to recover from an existing physical directory (created
+        with or without Maven).
+
+        Note that this method is not idempotent as the original definition will
+        be lost.
+        """
+        if not MavenBuild.is_build_dir(path):
+            raise ValueError("Not a valid MavenBuild path: {}".format(path))
+
+        return MavenBuild(path, definition=None)
+
+    def __repr__(self):
+        return ("MavenBuild["
+                "build = {},"
+                "definition = {}]".format(self.build_dir,
+                                          self.definition))