Title: [224410] trunk
Revision
224410
Author
[email protected]
Date
2017-11-03 11:42:55 -0700 (Fri, 03 Nov 2017)

Log Message

[WPE][GTK] Avoid duplicating code for dist and distcheck targets
https://bugs.webkit.org/show_bug.cgi?id=179154

Reviewed by Carlos Garcia Campos.

.:

This commit just reduces some CMake code duplication between GTK and WPE.

* Source/PlatformGTK.cmake:
* Source/PlatformWPE.cmake:
* Source/cmake/WebKitDist.cmake: Added.

Tools:

Move the script out of Tools/gtk because it is already used by WPE. Also, drop the .py
prefix because it is executable.

* Scripts/make-dist: Renamed from Tools/gtk/make-dist.py.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/ChangeLog (224409 => 224410)


--- trunk/ChangeLog	2017-11-03 18:32:19 UTC (rev 224409)
+++ trunk/ChangeLog	2017-11-03 18:42:55 UTC (rev 224410)
@@ -1,3 +1,16 @@
+2017-11-03  Michael Catanzaro  <[email protected]>
+
+        [WPE][GTK] Avoid duplicating code for dist and distcheck targets
+        https://bugs.webkit.org/show_bug.cgi?id=179154
+
+        Reviewed by Carlos Garcia Campos.
+
+        This commit just reduces some CMake code duplication between GTK and WPE.
+
+        * Source/PlatformGTK.cmake:
+        * Source/PlatformWPE.cmake:
+        * Source/cmake/WebKitDist.cmake: Added.
+
 2017-11-02  Tim Horton  <[email protected]>
 
         Reduce duplication in the toplevel Makefile

Modified: trunk/Source/PlatformGTK.cmake (224409 => 224410)


--- trunk/Source/PlatformGTK.cmake	2017-11-03 18:32:19 UTC (rev 224409)
+++ trunk/Source/PlatformGTK.cmake	2017-11-03 18:42:55 UTC (rev 224410)
@@ -1,3 +1,5 @@
+include(WebKitDist)
+
 add_subdirectory(${WEBCORE_DIR}/platform/gtk/po)
 
 # This allows exposing a 'gir' target which builds all GObject introspection files.
@@ -52,45 +54,6 @@
 )
 
 if (DEVELOPER_MODE)
-    configure_file(
-        ${TOOLS_DIR}/gtk/manifest.txt.in
-        ${CMAKE_BINARY_DIR}/manifest.txt
-    )
-
-    add_custom_command(
-        OUTPUT ${CMAKE_BINARY_DIR}/webkitgtk-${PROJECT_VERSION}.tar
-        DEPENDS ${TOOLS_DIR}/gtk/make-dist.py
-        DEPENDS ${CMAKE_BINARY_DIR}/manifest.txt
-        DEPENDS WebKit
-        DEPENDS gtkdoc
-        COMMAND ${TOOLS_DIR}/gtk/make-dist.py
-                --source-dir=${CMAKE_SOURCE_DIR}
-                --build-dir=${CMAKE_BINARY_DIR}
-                --version=${PROJECT_VERSION}
-                ${CMAKE_BINARY_DIR}/manifest.txt
-    )
-
-    add_custom_command(
-        OUTPUT ${CMAKE_BINARY_DIR}/webkitgtk-${PROJECT_VERSION}.tar.xz
-        DEPENDS ${CMAKE_BINARY_DIR}/webkitgtk-${PROJECT_VERSION}.tar
-        COMMAND xz -f ${CMAKE_BINARY_DIR}/webkitgtk-${PROJECT_VERSION}.tar
-    )
-
-    add_custom_target(dist
-        DEPENDS ${CMAKE_BINARY_DIR}/webkitgtk-${PROJECT_VERSION}.tar.xz
-    )
-
-    add_custom_target(distcheck
-        DEPENDS ${TOOLS_DIR}/gtk/make-dist.py
-        DEPENDS ${CMAKE_BINARY_DIR}/manifest.txt
-        DEPENDS WebKit
-        DEPENDS gtkdoc
-        COMMAND ${TOOLS_DIR}/gtk/make-dist.py
-                --check
-                --source-dir=${CMAKE_SOURCE_DIR}
-                --build-dir=${CMAKE_BINARY_DIR}
-                --version=${PROJECT_VERSION}
-                ${CMAKE_BINARY_DIR}/manifest.txt
-        COMMAND xz -f ${CMAKE_BINARY_DIR}/webkitgtk-${PROJECT_VERSION}.tar
-    )
+    add_custom_target(Documentation DEPENDS gtkdoc)
+    WEBKIT_DECLARE_DIST_TARGETS(GTK webkitgtk ${TOOLS_DIR}/gtk/manifest.txt.in)
 endif ()

Modified: trunk/Source/PlatformWPE.cmake (224409 => 224410)


--- trunk/Source/PlatformWPE.cmake	2017-11-03 18:32:19 UTC (rev 224409)
+++ trunk/Source/PlatformWPE.cmake	2017-11-03 18:42:55 UTC (rev 224410)
@@ -1,44 +1,7 @@
+include(WebKitDist)
+
 if (DEVELOPER_MODE)
-    find_package(Xz REQUIRED)
-
-    configure_file(
-        ${TOOLS_DIR}/wpe/manifest.txt.in
-        ${CMAKE_BINARY_DIR}/manifest.txt
-    )
-
-    add_custom_target(distcheck
-        COMMENT "Checking release tarball: wpewebkit-${PROJECT_VERSION}.tar"
-        DEPENDS "${CMAKE_BINARY_DIR}/manifest.txt"
-                "${TOOLS_DIR}/gtk/make-dist.py"
-        COMMAND "${TOOLS_DIR}/gtk/make-dist.py"
-                "--check" "--port=WPE"
-                "--tarball-name=wpewebkit"
-                "--source-dir=${CMAKE_SOURCE_DIR}"
-                "--build-dir=${CMAKE_BINARY_DIR}"
-                "--version=${PROJECT_VERSION}"
-                "${CMAKE_BINARY_DIR}/manifest.txt"
-        COMMAND "${XZ_EXECUTABLE}" "-evfQ"
-                "${CMAKE_BINARY_DIR}/wpewebkit-${PROJECT_VERSION}.tar"
-        USES_TERMINAL
-    )
-
-    add_custom_command(
-        COMMENT "Creating release tarball: wpewebkit-${PROJECT_VERSION}.tar.xz"
-        OUTPUT "${CMAKE_BINARY_DIR}/wpewebkit-${PROJECT_VERSION}.tar.xz"
-        MAIN_DEPENDENCY "${CMAKE_BINARY_DIR}/manifest.txt"
-        DEPENDS "${TOOLS_DIR}/gtk/make-dist.py"
-        COMMAND "${TOOLS_DIR}/gtk/make-dist.py"
-                "--tarball-name=wpewebkit"
-                "--source-dir=${CMAKE_SOURCE_DIR}"
-                "--build-dir=${CMAKE_BINARY_DIR}"
-                "--version=${PROJECT_VERSION}"
-                "${CMAKE_BINARY_DIR}/manifest.txt"
-        COMMAND "${XZ_EXECUTABLE}" "-evfQ"
-                "${CMAKE_BINARY_DIR}/wpewebkit-${PROJECT_VERSION}.tar"
-        USES_TERMINAL
-    )
-
-    add_custom_target(dist
-        DEPENDS "${CMAKE_BINARY_DIR}/wpewebkit-${PROJECT_VERSION}.tar.xz"
-    )
+    # FIXME: This should depend on a gtkdoc target
+    add_custom_target(Documentation)
+    WEBKIT_DECLARE_DIST_TARGETS(WPE wpewebkit ${TOOLS_DIR}/wpe/manifest.txt.in)
 endif ()

Added: trunk/Source/cmake/WebKitDist.cmake (0 => 224410)


--- trunk/Source/cmake/WebKitDist.cmake	                        (rev 0)
+++ trunk/Source/cmake/WebKitDist.cmake	2017-11-03 18:42:55 UTC (rev 224410)
@@ -0,0 +1,48 @@
+macro(WEBKIT_DECLARE_DIST_TARGETS _port _tarball_prefix _manifest)
+    find_package(Xz REQUIRED)
+
+    configure_file(
+        ${_manifest}
+        ${CMAKE_BINARY_DIR}/manifest.txt
+    )
+
+    add_custom_target(distcheck
+        COMMENT "Checking release tarball: ${_tarball_prefix}-${PROJECT_VERSION}.tar"
+        DEPENDS ${CMAKE_BINARY_DIR}/manifest.txt
+        DEPENDS WebKit
+        DEPENDS Documentation
+        COMMAND ${TOOLS_DIR}/Scripts/make-dist
+                --check --port=${_port}
+                --tarball-name=${_tarball_prefix}
+                --source-dir=${CMAKE_SOURCE_DIR}
+                --build-dir=${CMAKE_BINARY_DIR}
+                --version=${PROJECT_VERSION}
+                ${CMAKE_BINARY_DIR}/manifest.txt
+        COMMAND ${XZ_EXECUTABLE} -evfQ
+                ${CMAKE_BINARY_DIR}/${_tarball_prefix}-${PROJECT_VERSION}.tar
+        USES_TERMINAL
+        VERBATIM
+    )
+
+    add_custom_command(
+        COMMENT "Creating release tarball: ${_tarball_prefix}-${PROJECT_VERSION}.tar.xz"
+        OUTPUT ${CMAKE_BINARY_DIR}/${_tarball_prefix}-${PROJECT_VERSION}.tar.xz
+        MAIN_DEPENDENCY ${CMAKE_BINARY_DIR}/manifest.txt
+        COMMAND ${TOOLS_DIR}/Scripts/make-dist
+                --tarball-name=${_tarball_prefix}
+                --source-dir=${CMAKE_SOURCE_DIR}
+                --build-dir=${CMAKE_BINARY_DIR}
+                --version=${PROJECT_VERSION}
+                ${CMAKE_BINARY_DIR}/manifest.txt
+        COMMAND ${XZ_EXECUTABLE} -evfQ
+                ${CMAKE_BINARY_DIR}/${_tarball_prefix}-${PROJECT_VERSION}.tar
+        USES_TERMINAL
+        VERBATIM
+    )
+
+    add_custom_target(dist
+        DEPENDS ${CMAKE_BINARY_DIR}/${_tarball_prefix}-${PROJECT_VERSION}.tar.xz
+        DEPENDS WebKit
+        DEPENDS Documentation
+    )
+endmacro()

Modified: trunk/Tools/ChangeLog (224409 => 224410)


--- trunk/Tools/ChangeLog	2017-11-03 18:32:19 UTC (rev 224409)
+++ trunk/Tools/ChangeLog	2017-11-03 18:42:55 UTC (rev 224410)
@@ -1,3 +1,15 @@
+2017-11-03  Michael Catanzaro  <[email protected]>
+
+        [WPE][GTK] Avoid duplicating code for dist and distcheck targets
+        https://bugs.webkit.org/show_bug.cgi?id=179154
+
+        Reviewed by Carlos Garcia Campos.
+
+        Move the script out of Tools/gtk because it is already used by WPE. Also, drop the .py
+        prefix because it is executable.
+
+        * Scripts/make-dist: Renamed from Tools/gtk/make-dist.py.
+
 2017-11-03  Jonathan Bedard  <[email protected]>
 
         TestController platformAdjustContext should use provided WKContext for Mac

Copied: trunk/Tools/Scripts/make-dist (from rev 224409, trunk/Tools/gtk/make-dist.py) (0 => 224410)


--- trunk/Tools/Scripts/make-dist	                        (rev 0)
+++ trunk/Tools/Scripts/make-dist	2017-11-03 18:42:55 UTC (rev 224410)
@@ -0,0 +1,333 @@
+#!/usr/bin/env python
+# Copyright (C) 2014 Igalia S.L.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+from __future__ import print_function
+from contextlib import closing
+
+import argparse
+import errno
+import multiprocessing
+import os
+import re
+import shutil
+import subprocess
+import tarfile
+
+
+def enum(**enums):
+    return type('Enum', (), enums)
+
+
+class Rule(object):
+    Result = enum(INCLUDE=1, EXCLUDE=2, NO_MATCH=3)
+
+    def __init__(self, type, pattern):
+        self.type = type
+        self.original_pattern = pattern
+        self.pattern = re.compile(pattern)
+
+    def test(self, file):
+        if not(self.pattern.search(file)):
+            return Rule.Result.NO_MATCH
+        return self.type
+
+
+class Ruleset(object):
+    _global_rules = None
+
+    def __init__(self):
+        # By default, accept all files.
+        self.rules = [Rule(Rule.Result.INCLUDE, '.*')]
+
+    @classmethod
+    def global_rules(cls):
+        if not cls._global_rules:
+            cls._global_rules = Ruleset()
+        return cls._global_rules
+
+    @classmethod
+    def add_global_rule(cls, rule):
+        cls.global_rules().add_rule(rule)
+
+    def add_rule(self, rule):
+        self.rules.append(rule)
+
+    def passes(self, file):
+        allowed = False
+        for rule in self.rules:
+            result = rule.test(file)
+            if result == Rule.Result.NO_MATCH:
+                continue
+            allowed = Rule.Result.INCLUDE == result
+        return allowed
+
+
+class File(object):
+    def __init__(self, source_root, tarball_root):
+        self.source_root = source_root
+        self.tarball_root = tarball_root
+
+    def should_skip_file(self, path):
+        # Do not skip files explicitly added from the manifest.
+        return False
+
+    def get_files(self):
+        yield (self.source_root, self.tarball_root)
+
+
+class Directory(object):
+    def __init__(self, source_root, tarball_root):
+        self.source_root = source_root
+        self.tarball_root = tarball_root
+        self.rules = Ruleset()
+
+        self.files_in_version_control = self.list_files_in_version_control()
+
+    def add_rule(self, rule):
+        self.rules.add_rule(rule)
+
+    def get_tarball_path(self, filename):
+        return filename.replace(self.source_root, self.tarball_root, 1)
+
+    def list_files_in_version_control(self):
+        # FIXME: Only git is supported for now.
+        p = subprocess.Popen(['git', 'ls-tree', '-r', '--name-only', 'HEAD', self.source_root], stdout=subprocess.PIPE)
+        out = p.communicate()[0]
+        if not out:
+            return []
+        return out.rstrip('\n').split('\n')
+
+    def should_skip_file(self, path):
+        return path not in self.files_in_version_control
+
+    def get_files(self):
+        for root, dirs, files in os.walk(self.source_root):
+
+            def passes_all_rules(entry):
+                return Ruleset.global_rules().passes(entry) and self.rules.passes(entry)
+
+            to_keep = filter(passes_all_rules, dirs)
+            del dirs[:]
+            dirs.extend(to_keep)
+
+            for file in files:
+                file = os.path.join(root, file)
+                if not passes_all_rules(file):
+                    continue
+                yield (file, self.get_tarball_path(file))
+
+
+class Manifest(object):
+    def __init__(self, manifest_filename, source_root, build_root, tarball_root='/'):
+        self.current_directory = None
+        self.directories = []
+        self.tarball_root = tarball_root
+        self.source_root = source_root
+        self.build_root = build_root
+
+        # Normalize the tarball root so that it starts and ends with a slash.
+        if not self.tarball_root.endswith('/'):
+            self.tarball_root = self.tarball_root + '/'
+        if not self.tarball_root.startswith('/'):
+            self.tarball_root = '/' + self.tarball_root
+
+        with open(manifest_filename, 'r') as file:
+            for line in file.readlines():
+                self.process_line(line)
+
+    def add_rule(self, rule):
+        if self.current_directory is not None:
+            self.current_directory.add_rule(rule)
+        else:
+            Ruleset.add_global_rule(rule)
+
+    def add_directory(self, directory):
+        self.current_directory = directory
+        self.directories.append(directory)
+
+    def get_full_source_path(self, source_path):
+        if not os.path.exists(source_path):
+            source_path = os.path.join(self.source_root, source_path)
+        if not os.path.exists(source_path):
+            raise Exception('Could not find directory %s' % source_path)
+        return source_path
+
+    def get_full_tarball_path(self, path):
+        return self.tarball_root + path
+
+    def get_source_and_tarball_paths_from_parts(self, parts):
+        full_source_path = self.get_full_source_path(parts[1])
+        if len(parts) > 2:
+            full_tarball_path = self.get_full_tarball_path(parts[2])
+        else:
+            full_tarball_path = self.get_full_tarball_path(parts[1])
+        return (full_source_path, full_tarball_path)
+
+    def process_line(self, line):
+        parts = line.split()
+        if not parts:
+            return
+        if parts[0].startswith("#"):
+            return
+
+        if parts[0] == "directory" and len(parts) > 1:
+            self.add_directory(Directory(*self.get_source_and_tarball_paths_from_parts(parts)))
+        elif parts[0] == "file" and len(parts) > 1:
+            self.add_directory(File(*self.get_source_and_tarball_paths_from_parts(parts)))
+        elif parts[0] == "exclude" and len(parts) > 1:
+            self.add_rule(Rule(Rule.Result.EXCLUDE, parts[1]))
+        elif parts[0] == "include" and len(parts) > 1:
+            self.add_rule(Rule(Rule.Result.INCLUDE, parts[1]))
+        else:
+            raise Exception('Line does not begin with a correct rule:\n\t' + line)
+
+    def should_skip_file(self, directory, filename):
+        # Only allow files that are not in version control when they are explicitly included in the manifest from the build dir.
+        if filename.startswith(self.build_root):
+            return False
+
+        return directory.should_skip_file(filename)
+
+    def get_files(self):
+        for directory in self.directories:
+            for file_tuple in directory.get_files():
+                if self.should_skip_file(directory, file_tuple[0]):
+                    continue
+                yield file_tuple
+
+    def create_tarfile(self, output):
+        count = 0
+        for file_tuple in self.get_files():
+            count = count + 1
+
+        with closing(tarfile.open(output, 'w')) as tarball:
+            for i, (file_path, tarball_path) in enumerate(self.get_files(), start=1):
+                print('Tarring file {0} of {1}'.format(i, count).ljust(40), end='\r')
+                tarball.add(file_path, tarball_path)
+        print("Wrote {0}".format(output).ljust(40))
+
+
+class Distcheck(object):
+    BUILD_DIRECTORY_NAME = "_build"
+    INSTALL_DIRECTORY_NAME = "_install"
+
+    def __init__(self, source_root, build_root):
+        self.source_root = source_root
+        self.build_root = build_root
+
+    def extract_tarball(self, tarball_path):
+        with closing(tarfile.open(tarball_path, 'r')) as tarball:
+            tarball.extractall(self.build_root)
+
+    def configure(self, dist_dir, build_dir, install_dir, port):
+        def create_dir(directory, directory_type):
+            try:
+                os.mkdir(directory)
+            except OSError, e:
+                if e.errno != errno.EEXIST or not os.path.isdir(directory):
+                    raise Exception("Could not create %s dir at %s: %s" % (directory_type, directory, str(e)))
+
+        create_dir(build_dir, "build")
+        create_dir(install_dir, "install")
+
+        command = ['cmake', '-DPORT=%s' % port, '-DCMAKE_INSTALL_PREFIX=%s' % install_dir, '-DCMAKE_BUILD_TYPE=Release', dist_dir]
+        subprocess.check_call(command, cwd=build_dir)
+
+    def build(self, build_dir):
+        command = ['make']
+        make_args = os.getenv('MAKE_ARGS')
+        if make_args:
+            command.extend(make_args.split(' '))
+        else:
+            command.append('-j%d' % multiprocessing.cpu_count())
+        subprocess.check_call(command, cwd=build_dir)
+
+    def install(self, build_dir):
+        subprocess.check_call(['make', 'install'], cwd=build_dir)
+
+    def clean(self, dist_dir):
+        shutil.rmtree(dist_dir)
+
+    def check(self, tarball, port):
+        tarball_name, ext = os.path.splitext(os.path.basename(tarball))
+        dist_dir = os.path.join(self.build_root, tarball_name)
+        build_dir = os.path.join(dist_dir, self.BUILD_DIRECTORY_NAME)
+        install_dir = os.path.join(dist_dir, self.INSTALL_DIRECTORY_NAME)
+
+        self.extract_tarball(tarball)
+        self.configure(dist_dir, build_dir, install_dir, port)
+        self.build(build_dir)
+        self.install(build_dir)
+        self.clean(dist_dir)
+
+if __name__ == "__main__":
+    class FilePathAction(argparse.Action):
+        def __call__(self, parser, namespace, values, option_string=None):
+            setattr(namespace, self.dest, os.path.abspath(values))
+
+    def ensure_version_if_possible(arguments):
+        if arguments.version is not None:
+            return
+
+        pkgconfig_file = os.path.join(arguments.build_dir, "Source/WebKit/webkit2gtk-4.0.pc")
+        if os.path.isfile(pkgconfig_file):
+            p = subprocess.Popen(['pkg-config', '--modversion', pkgconfig_file], stdout=subprocess.PIPE)
+            version = p.communicate()[0]
+            if version:
+                arguments.version = version.rstrip('\n')
+
+
+    def get_tarball_root_and_output_filename_from_arguments(arguments):
+        tarball_root = arguments.tarball_name
+        if arguments.version is not None:
+            tarball_root += '-' + arguments.version
+
+        output_filename = os.path.join(arguments.build_dir, tarball_root + ".tar")
+        return tarball_root, output_filename
+
+    parser = argparse.ArgumentParser(description='Build a distribution bundle.')
+    parser.add_argument('-c', '--check', action='',
+                        help='Check the tarball')
+    parser.add_argument('-s', '--source-dir', type=str, action="" default=os.getcwd(),
+                        help='The top-level directory of the source distribution. ' + \
+                              'Directory for relative paths. Defaults to current directory.')
+    parser.add_argument('--version', type=str, default=None,
+                        help='The version of the tarball to generate')
+    parser.add_argument('-b', '--build-dir', type=str, action="" default=os.getcwd(),
+                        help='The top-level path of directory of the build root. ' + \
+                              'By default is the current directory.')
+    parser.add_argument('-t', '--tarball-name', type=str, default='webkitgtk',
+                        help='Base name of tarball. Defaults to "webkitgtk".')
+    parser.add_argument('-p', '--port', type=str, default='GTK',
+                        help='Port to be built in tarball check. Defaults to "GTK".')
+    parser.add_argument('manifest_filename', metavar="manifest", type=str, action="" help='The path to the manifest file.')
+
+    arguments = parser.parse_args()
+
+    # Paths in the manifest are relative to the source directory, and this script assumes that
+    # current working directory is the source directory, so change the current working directory
+    # to be the source directory.
+    os.chdir(arguments.source_dir)
+
+    ensure_version_if_possible(arguments)
+    tarball_root, output_filename = get_tarball_root_and_output_filename_from_arguments(arguments)
+
+    manifest = Manifest(arguments.manifest_filename, arguments.source_dir, arguments.build_dir, tarball_root)
+    manifest.create_tarfile(output_filename)
+
+    if arguments.check:
+        Distcheck(arguments.source_dir, arguments.build_dir).check(output_filename, arguments.port)

Deleted: trunk/Tools/gtk/make-dist.py (224409 => 224410)


--- trunk/Tools/gtk/make-dist.py	2017-11-03 18:32:19 UTC (rev 224409)
+++ trunk/Tools/gtk/make-dist.py	2017-11-03 18:42:55 UTC (rev 224410)
@@ -1,333 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2014 Igalia S.L.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-from __future__ import print_function
-from contextlib import closing
-
-import argparse
-import errno
-import multiprocessing
-import os
-import re
-import shutil
-import subprocess
-import tarfile
-
-
-def enum(**enums):
-    return type('Enum', (), enums)
-
-
-class Rule(object):
-    Result = enum(INCLUDE=1, EXCLUDE=2, NO_MATCH=3)
-
-    def __init__(self, type, pattern):
-        self.type = type
-        self.original_pattern = pattern
-        self.pattern = re.compile(pattern)
-
-    def test(self, file):
-        if not(self.pattern.search(file)):
-            return Rule.Result.NO_MATCH
-        return self.type
-
-
-class Ruleset(object):
-    _global_rules = None
-
-    def __init__(self):
-        # By default, accept all files.
-        self.rules = [Rule(Rule.Result.INCLUDE, '.*')]
-
-    @classmethod
-    def global_rules(cls):
-        if not cls._global_rules:
-            cls._global_rules = Ruleset()
-        return cls._global_rules
-
-    @classmethod
-    def add_global_rule(cls, rule):
-        cls.global_rules().add_rule(rule)
-
-    def add_rule(self, rule):
-        self.rules.append(rule)
-
-    def passes(self, file):
-        allowed = False
-        for rule in self.rules:
-            result = rule.test(file)
-            if result == Rule.Result.NO_MATCH:
-                continue
-            allowed = Rule.Result.INCLUDE == result
-        return allowed
-
-
-class File(object):
-    def __init__(self, source_root, tarball_root):
-        self.source_root = source_root
-        self.tarball_root = tarball_root
-
-    def should_skip_file(self, path):
-        # Do not skip files explicitly added from the manifest.
-        return False
-
-    def get_files(self):
-        yield (self.source_root, self.tarball_root)
-
-
-class Directory(object):
-    def __init__(self, source_root, tarball_root):
-        self.source_root = source_root
-        self.tarball_root = tarball_root
-        self.rules = Ruleset()
-
-        self.files_in_version_control = self.list_files_in_version_control()
-
-    def add_rule(self, rule):
-        self.rules.add_rule(rule)
-
-    def get_tarball_path(self, filename):
-        return filename.replace(self.source_root, self.tarball_root, 1)
-
-    def list_files_in_version_control(self):
-        # FIXME: Only git is supported for now.
-        p = subprocess.Popen(['git', 'ls-tree', '-r', '--name-only', 'HEAD', self.source_root], stdout=subprocess.PIPE)
-        out = p.communicate()[0]
-        if not out:
-            return []
-        return out.rstrip('\n').split('\n')
-
-    def should_skip_file(self, path):
-        return path not in self.files_in_version_control
-
-    def get_files(self):
-        for root, dirs, files in os.walk(self.source_root):
-
-            def passes_all_rules(entry):
-                return Ruleset.global_rules().passes(entry) and self.rules.passes(entry)
-
-            to_keep = filter(passes_all_rules, dirs)
-            del dirs[:]
-            dirs.extend(to_keep)
-
-            for file in files:
-                file = os.path.join(root, file)
-                if not passes_all_rules(file):
-                    continue
-                yield (file, self.get_tarball_path(file))
-
-
-class Manifest(object):
-    def __init__(self, manifest_filename, source_root, build_root, tarball_root='/'):
-        self.current_directory = None
-        self.directories = []
-        self.tarball_root = tarball_root
-        self.source_root = source_root
-        self.build_root = build_root
-
-        # Normalize the tarball root so that it starts and ends with a slash.
-        if not self.tarball_root.endswith('/'):
-            self.tarball_root = self.tarball_root + '/'
-        if not self.tarball_root.startswith('/'):
-            self.tarball_root = '/' + self.tarball_root
-
-        with open(manifest_filename, 'r') as file:
-            for line in file.readlines():
-                self.process_line(line)
-
-    def add_rule(self, rule):
-        if self.current_directory is not None:
-            self.current_directory.add_rule(rule)
-        else:
-            Ruleset.add_global_rule(rule)
-
-    def add_directory(self, directory):
-        self.current_directory = directory
-        self.directories.append(directory)
-
-    def get_full_source_path(self, source_path):
-        if not os.path.exists(source_path):
-            source_path = os.path.join(self.source_root, source_path)
-        if not os.path.exists(source_path):
-            raise Exception('Could not find directory %s' % source_path)
-        return source_path
-
-    def get_full_tarball_path(self, path):
-        return self.tarball_root + path
-
-    def get_source_and_tarball_paths_from_parts(self, parts):
-        full_source_path = self.get_full_source_path(parts[1])
-        if len(parts) > 2:
-            full_tarball_path = self.get_full_tarball_path(parts[2])
-        else:
-            full_tarball_path = self.get_full_tarball_path(parts[1])
-        return (full_source_path, full_tarball_path)
-
-    def process_line(self, line):
-        parts = line.split()
-        if not parts:
-            return
-        if parts[0].startswith("#"):
-            return
-
-        if parts[0] == "directory" and len(parts) > 1:
-            self.add_directory(Directory(*self.get_source_and_tarball_paths_from_parts(parts)))
-        elif parts[0] == "file" and len(parts) > 1:
-            self.add_directory(File(*self.get_source_and_tarball_paths_from_parts(parts)))
-        elif parts[0] == "exclude" and len(parts) > 1:
-            self.add_rule(Rule(Rule.Result.EXCLUDE, parts[1]))
-        elif parts[0] == "include" and len(parts) > 1:
-            self.add_rule(Rule(Rule.Result.INCLUDE, parts[1]))
-        else:
-            raise Exception('Line does not begin with a correct rule:\n\t' + line)
-
-    def should_skip_file(self, directory, filename):
-        # Only allow files that are not in version control when they are explicitly included in the manifest from the build dir.
-        if filename.startswith(self.build_root):
-            return False
-
-        return directory.should_skip_file(filename)
-
-    def get_files(self):
-        for directory in self.directories:
-            for file_tuple in directory.get_files():
-                if self.should_skip_file(directory, file_tuple[0]):
-                    continue
-                yield file_tuple
-
-    def create_tarfile(self, output):
-        count = 0
-        for file_tuple in self.get_files():
-            count = count + 1
-
-        with closing(tarfile.open(output, 'w')) as tarball:
-            for i, (file_path, tarball_path) in enumerate(self.get_files(), start=1):
-                print('Tarring file {0} of {1}'.format(i, count).ljust(40), end='\r')
-                tarball.add(file_path, tarball_path)
-        print("Wrote {0}".format(output).ljust(40))
-
-
-class Distcheck(object):
-    BUILD_DIRECTORY_NAME = "_build"
-    INSTALL_DIRECTORY_NAME = "_install"
-
-    def __init__(self, source_root, build_root):
-        self.source_root = source_root
-        self.build_root = build_root
-
-    def extract_tarball(self, tarball_path):
-        with closing(tarfile.open(tarball_path, 'r')) as tarball:
-            tarball.extractall(self.build_root)
-
-    def configure(self, dist_dir, build_dir, install_dir, port):
-        def create_dir(directory, directory_type):
-            try:
-                os.mkdir(directory)
-            except OSError, e:
-                if e.errno != errno.EEXIST or not os.path.isdir(directory):
-                    raise Exception("Could not create %s dir at %s: %s" % (directory_type, directory, str(e)))
-
-        create_dir(build_dir, "build")
-        create_dir(install_dir, "install")
-
-        command = ['cmake', '-DPORT=%s' % port, '-DCMAKE_INSTALL_PREFIX=%s' % install_dir, '-DCMAKE_BUILD_TYPE=Release', dist_dir]
-        subprocess.check_call(command, cwd=build_dir)
-
-    def build(self, build_dir):
-        command = ['make']
-        make_args = os.getenv('MAKE_ARGS')
-        if make_args:
-            command.extend(make_args.split(' '))
-        else:
-            command.append('-j%d' % multiprocessing.cpu_count())
-        subprocess.check_call(command, cwd=build_dir)
-
-    def install(self, build_dir):
-        subprocess.check_call(['make', 'install'], cwd=build_dir)
-
-    def clean(self, dist_dir):
-        shutil.rmtree(dist_dir)
-
-    def check(self, tarball, port):
-        tarball_name, ext = os.path.splitext(os.path.basename(tarball))
-        dist_dir = os.path.join(self.build_root, tarball_name)
-        build_dir = os.path.join(dist_dir, self.BUILD_DIRECTORY_NAME)
-        install_dir = os.path.join(dist_dir, self.INSTALL_DIRECTORY_NAME)
-
-        self.extract_tarball(tarball)
-        self.configure(dist_dir, build_dir, install_dir, port)
-        self.build(build_dir)
-        self.install(build_dir)
-        self.clean(dist_dir)
-
-if __name__ == "__main__":
-    class FilePathAction(argparse.Action):
-        def __call__(self, parser, namespace, values, option_string=None):
-            setattr(namespace, self.dest, os.path.abspath(values))
-
-    def ensure_version_if_possible(arguments):
-        if arguments.version is not None:
-            return
-
-        pkgconfig_file = os.path.join(arguments.build_dir, "Source/WebKit/webkit2gtk-4.0.pc")
-        if os.path.isfile(pkgconfig_file):
-            p = subprocess.Popen(['pkg-config', '--modversion', pkgconfig_file], stdout=subprocess.PIPE)
-            version = p.communicate()[0]
-            if version:
-                arguments.version = version.rstrip('\n')
-
-
-    def get_tarball_root_and_output_filename_from_arguments(arguments):
-        tarball_root = arguments.tarball_name
-        if arguments.version is not None:
-            tarball_root += '-' + arguments.version
-
-        output_filename = os.path.join(arguments.build_dir, tarball_root + ".tar")
-        return tarball_root, output_filename
-
-    parser = argparse.ArgumentParser(description='Build a distribution bundle.')
-    parser.add_argument('-c', '--check', action='',
-                        help='Check the tarball')
-    parser.add_argument('-s', '--source-dir', type=str, action="" default=os.getcwd(),
-                        help='The top-level directory of the source distribution. ' + \
-                              'Directory for relative paths. Defaults to current directory.')
-    parser.add_argument('--version', type=str, default=None,
-                        help='The version of the tarball to generate')
-    parser.add_argument('-b', '--build-dir', type=str, action="" default=os.getcwd(),
-                        help='The top-level path of directory of the build root. ' + \
-                              'By default is the current directory.')
-    parser.add_argument('-t', '--tarball-name', type=str, default='webkitgtk',
-                        help='Base name of tarball. Defaults to "webkitgtk".')
-    parser.add_argument('-p', '--port', type=str, default='GTK',
-                        help='Port to be built in tarball check. Defaults to "GTK".')
-    parser.add_argument('manifest_filename', metavar="manifest", type=str, action="" help='The path to the manifest file.')
-
-    arguments = parser.parse_args()
-
-    # Paths in the manifest are relative to the source directory, and this script assumes that
-    # current working directory is the source directory, so change the current working directory
-    # to be the source directory.
-    os.chdir(arguments.source_dir)
-
-    ensure_version_if_possible(arguments)
-    tarball_root, output_filename = get_tarball_root_and_output_filename_from_arguments(arguments)
-
-    manifest = Manifest(arguments.manifest_filename, arguments.source_dir, arguments.build_dir, tarball_root)
-    manifest.create_tarfile(output_filename)
-
-    if arguments.check:
-        Distcheck(arguments.source_dir, arguments.build_dir).check(output_filename, arguments.port)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to