From 93e839377b75d532d2e493031f9a68f282b6fab5 Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Mon, 17 Jul 2017 14:16:02 -0600 Subject: [PATCH 01/13] Adding minifaction support for AngularJS, via ng-annotate. --- webmake/modules/minify.py | 21 ++++++++++++++++++++- webmake/package.json | 3 ++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/webmake/modules/minify.py b/webmake/modules/minify.py index 7552802..27ac321 100644 --- a/webmake/modules/minify.py +++ b/webmake/modules/minify.py @@ -4,10 +4,13 @@ def minify_js(input_files, output_file, release=False): assert isinstance(input_files, (list, tuple)) + concat.concatenate_input_files(input_files, output_file, release=release) + if not release: - concat.concatenate_input_files(input_files, output_file, release=release) return + annotate_angular_injections(output_file, output_file) + cmdline = [ utils.get_node_bin_path('uglify-js', 'bin', 'uglifyjs'), '--compress', @@ -25,6 +28,22 @@ def minify_js(input_files, output_file, release=False): raise +def annotate_angular_injections(input_file, output_file): + cmdline = [ + utils.get_node_bin_dir('ng-annotate'), + '--add', + '-o', + output_file, + ] + cmdline.extend([input_file]) + + try: + utils.run_command(cmdline, 'Failed to annotate Angular injections to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + raise + + def minify_css(input_files, output_file, release=False): assert isinstance(input_files, (list, tuple)) diff --git a/webmake/package.json b/webmake/package.json index 1f1d20c..bdb8c91 100644 --- a/webmake/package.json +++ b/webmake/package.json @@ -8,6 +8,7 @@ "react-tools": "0.x", "reactify": "1.x", "uglify-js": "2.x", - "bless": "3.x" + "bless": "3.x", + "ng-annotate": "1.x" } } From de0e2d6b0da49435f6e98f41c5b940f5443f57f0 Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Fri, 16 Mar 2018 13:41:03 -0600 Subject: [PATCH 02/13] - Updating node-sass package, older version wasn't compiling on Ubuntu 18.10 - Bugfix: the `--no-bin-links` flag for `npm install` causes the `.bin` directory to *not* be created. --- setup.py | 2 +- webmake/modules/bless.py | 2 +- webmake/modules/browserify.py | 2 +- webmake/modules/copyfiles.py | 9 ++------- webmake/modules/less.py | 2 +- webmake/modules/minify.py | 20 +++++++++++--------- webmake/modules/reactjs.py | 2 +- webmake/modules/sass.py | 2 +- webmake/modules/utils.py | 13 +++++++------ webmake/package.json | 2 +- 10 files changed, 27 insertions(+), 29 deletions(-) diff --git a/setup.py b/setup.py index 63ad28c..9961b29 100644 --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ def program_is_installed(msg, prog): def _post_install(dir): oldwd = os.getcwd() os.chdir(dir) - os.system('npm install --no-bin-links --color false --unicode false') + os.system('npm install --color false --unicode false') os.chdir(oldwd) diff --git a/webmake/modules/bless.py b/webmake/modules/bless.py index d3dd91c..dc51d77 100644 --- a/webmake/modules/bless.py +++ b/webmake/modules/bless.py @@ -5,7 +5,7 @@ def bless_css(input_file, output_file, release=False): assert isinstance(input_file, str) cmdline = [ - utils.get_node_bin_path('bless', 'bin', 'blessc'), + utils.get_node_bin_dir('blessc'), '--no-imports', ] cmdline.append(input_file) diff --git a/webmake/modules/browserify.py b/webmake/modules/browserify.py index 3111547..52df1f2 100644 --- a/webmake/modules/browserify.py +++ b/webmake/modules/browserify.py @@ -25,7 +25,7 @@ def browserify_basic_command(output_file, release, list_deps): sourcemap = '-d' if not release else '' cmdline = [ - utils.get_node_bin_path('browserify', 'bin', 'cmd.js'), + utils.get_node_bin_dir('browserify'), ] if list_deps: diff --git a/webmake/modules/copyfiles.py b/webmake/modules/copyfiles.py index dcbcd70..70b76ff 100644 --- a/webmake/modules/copyfiles.py +++ b/webmake/modules/copyfiles.py @@ -1,5 +1,4 @@ import os -import re import shutil from fnmatch import fnmatch from . import utils @@ -7,13 +6,9 @@ def list_files(src_dir, filespec, recursive=False): inputs = [] - filespecs = [filespec] if not isinstance(filespec, (list, tuple)) else filespec - - def match_file(f): - return any(fnmatch(f, s) for s in filespecs) for dir, _, files in os.walk(src_dir): - inputs.extend(os.path.join(dir, f) for f in files if match_file(f)) + inputs.extend(os.path.join(dir, f) for f in files if fnmatch(f, filespec)) if not recursive: break @@ -37,7 +32,7 @@ def copy_files(src_dir, dst_dir, filespec, recursive=False, release=None): utils.logv('>>> copy {} > {}'.format(input, output)) dirname = os.path.split(output)[0] if not os.path.exists(dirname): - os.makedirs(dirname) + os.mkdir(dirname) shutil.copy2(input, output) os.utime(dst_dir, None) diff --git a/webmake/modules/less.py b/webmake/modules/less.py index ce52688..ab682e8 100644 --- a/webmake/modules/less.py +++ b/webmake/modules/less.py @@ -42,7 +42,7 @@ def less_compile(input_file, output_file, release=False): if not release else '') cmdline = [ - utils.get_node_bin_path('less', 'bin', 'lessc'), + utils.get_node_bin_dir('lessc'), '--no-color', minify, sourcemap, diff --git a/webmake/modules/minify.py b/webmake/modules/minify.py index 27ac321..c7245fe 100644 --- a/webmake/modules/minify.py +++ b/webmake/modules/minify.py @@ -9,17 +9,21 @@ def minify_js(input_files, output_file, release=False): if not release: return - annotate_angular_injections(output_file, output_file) + try: + annotate_angular_injections(output_file, output_file) + except: + # utils.ensure_deleted(output_file) + raise cmdline = [ - utils.get_node_bin_path('uglify-js', 'bin', 'uglifyjs'), + utils.get_node_bin_dir('uglifyjs'), '--compress', '--mangle', '-o', output_file, '--', ] - cmdline.extend(input_files) + cmdline.extend([output_file]) try: utils.run_command(cmdline, 'Failed to minify JS to "{}"'.format(output_file)) @@ -27,7 +31,6 @@ def minify_js(input_files, output_file, release=False): utils.ensure_deleted(output_file) raise - def annotate_angular_injections(input_file, output_file): cmdline = [ utils.get_node_bin_dir('ng-annotate'), @@ -38,12 +41,11 @@ def annotate_angular_injections(input_file, output_file): cmdline.extend([input_file]) try: - utils.run_command(cmdline, 'Failed to annotate Angular injections to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) + utils.run_command(cmdline, 'Failed to annotate Annnngular injections to "{}"'.format(output_file)) + except Exception as e: + # utils.ensure_deleted(output_file) raise - def minify_css(input_files, output_file, release=False): assert isinstance(input_files, (list, tuple)) @@ -52,7 +54,7 @@ def minify_css(input_files, output_file, release=False): return cmdline = [ - utils.get_node_bin_path('cssmin', 'bin', 'cssmin'), + utils.get_node_bin_dir('cssmin'), ] cmdline.append(output_file) diff --git a/webmake/modules/reactjs.py b/webmake/modules/reactjs.py index d61076e..9efb403 100644 --- a/webmake/modules/reactjs.py +++ b/webmake/modules/reactjs.py @@ -13,7 +13,7 @@ def jsx_compile(input_files, output_file, release=False): sourcemap = '--source-map-inline' if not release else '' cmdline = [ - utils.get_node_bin_path('react-tools', 'bin', 'jsx'), + utils.get_node_bin_dir('jsx'), '--no-cache-dir', sourcemap, '--extension', diff --git a/webmake/modules/sass.py b/webmake/modules/sass.py index f624630..73bebd2 100644 --- a/webmake/modules/sass.py +++ b/webmake/modules/sass.py @@ -33,7 +33,7 @@ def sass_compile(input_file, output_file, release=False): source_map = '--source-comments --source-map-embed --source-map-contents --source-map {}'.format(map_file) if not release else '' cmdline = [ - utils.get_node_bin_path('node-sass', 'bin', 'node-sass'), + utils.get_node_bin_dir('node-sass'), '--output-style', output_style, source_map, diff --git a/webmake/modules/utils.py b/webmake/modules/utils.py index a16fa3a..0d1fb35 100644 --- a/webmake/modules/utils.py +++ b/webmake/modules/utils.py @@ -134,8 +134,12 @@ def get_node_modules_dir(module=None): return moduledir -def get_node_bin_path(*args): - return os.path.join(get_node_modules_dir(), *args) +def get_node_bin_dir(cmd=None): + bindir = get_node_modules_dir('.bin') + if cmd: + return os.path.join(bindir, cmd) + else: + return bindir def no_dependencies(input): @@ -145,7 +149,7 @@ def no_dependencies(input): return input -def run_command(cmd, errmsg, env=None, with_node=True): +def run_command(cmd, errmsg, env=None): if env is not None: newenv = os.environ.copy() newenv.update(env) @@ -154,9 +158,6 @@ def run_command(cmd, errmsg, env=None, with_node=True): if isinstance(cmd, (list, tuple)): cmd = ' '.join(c for c in cmd if c != '') - if with_node: - cmd = 'node ' + cmd - try: logv('>>> ' + cmd) return subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT, shell=True).decode('ascii', 'replace') diff --git a/webmake/package.json b/webmake/package.json index bdb8c91..e75fb1e 100644 --- a/webmake/package.json +++ b/webmake/package.json @@ -4,7 +4,7 @@ "browserify": "9.x", "cssmin": "0.x", "less": "2.x", - "node-sass": "3.x", + "node-sass": "4.11.0", "react-tools": "0.x", "reactify": "1.x", "uglify-js": "2.x", From e4ccd733e10b8bcd0a648e5551865a536fb2085e Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Mon, 18 Feb 2019 20:46:35 -0500 Subject: [PATCH 03/13] - Bumping `node-sass` version to 4.11 - Adding `annotate_angular` kwargs to `api.minify_js` - Adding same kwarg to `moduls.minify_js`, using it to conditionally implement the annotations --- webmake/api.py | 5 +++-- webmake/modules/minify.py | 15 ++++++++------- webmake/package.json | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/webmake/api.py b/webmake/api.py index 09ebdaf..363ec1c 100644 --- a/webmake/api.py +++ b/webmake/api.py @@ -57,7 +57,7 @@ def copy_files(src_dir, dst_dir, filespec='*', recursive=False): } -def minify_js(input_files, output_file): +def minify_js(input_files, output_file, annotate_angular=False): """ Minifies the input javascript files to the output file. @@ -66,6 +66,7 @@ def minify_js(input_files, output_file): In debug mode this function just concatenates the files without minifying. """ + from functools import partial from .modules import minify, utils if not isinstance(input_files, (list, tuple)): @@ -73,7 +74,7 @@ def minify_js(input_files, output_file): return { 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': minify.minify_js, + 'compiler_fn': partial(minify.minify_js, annotate_angular=annotate_angular), 'input': input_files, 'output': output_file, 'kwargs': {}, diff --git a/webmake/modules/minify.py b/webmake/modules/minify.py index 0357843..70d128b 100644 --- a/webmake/modules/minify.py +++ b/webmake/modules/minify.py @@ -2,7 +2,7 @@ from . import utils, concat -def minify_js(input_files, output_file, release=False): +def minify_js(input_files, output_file, release=False, annotate_angular=False): assert isinstance(input_files, (list, tuple)) concat.concatenate_input_files(input_files, output_file, release=release) @@ -10,17 +10,18 @@ def minify_js(input_files, output_file, release=False): if not release: return - try: - annotate_angular_injections(output_file, output_file) - except: - # utils.ensure_deleted(output_file) - raise + if annotate_angular: + try: + annotate_angular_injections(output_file, output_file) + except: + # utils.ensure_deleted(output_file) + raise if output_file: utils.ensure_path_exists(os.path.dirname(output_file)) cmdline = [ - utils.get_node_bin_path('uglify-es', 'bin', 'uglifyjs'), + utils.get_node_bin_dir('uglifyjs'), '--compress', '--mangle', '-o', diff --git a/webmake/package.json b/webmake/package.json index 07a5a25..9adf0a5 100644 --- a/webmake/package.json +++ b/webmake/package.json @@ -11,7 +11,7 @@ "cssmin": "^0.4.3", "less": "^2.7.3", "ng-annotate": "1.x", - "node-sass": "^3.13.1", + "node-sass": "^4.11.0", "uglify-es": "^3.3.9" } } From 5a33ad661237bc8593b700f688591d5e36e19728 Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Tue, 19 Mar 2019 23:21:05 -0400 Subject: [PATCH 04/13] Adding dedicated exception for runtime warning. --- webmake/django/middleware.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webmake/django/middleware.py b/webmake/django/middleware.py index 68aabef..84056d3 100644 --- a/webmake/django/middleware.py +++ b/webmake/django/middleware.py @@ -43,6 +43,10 @@ def pre_process(self, deployment_settings, *args, **kwargs): BINFILE = POSSIBLE_BINFILES[0] if POSSIBLE_BINFILES else WEBMAKE_BIN +class WebmakeRuntimeWarning(RuntimeWarning): + pass + + class WebmakeCompilerMiddleware: def __init__(self, get_response=None): self.get_response = get_response @@ -53,7 +57,7 @@ def __call__(self, request): def process_request(self, request): if not settings.DEBUG: - warnings.warn('WebmakeCompilerMiddleware should not be used in production!', RuntimeWarning) + warnings.warn('WebmakeCompilerMiddleware should not be used in production!', WebmakeRuntimeWarning) cmd = ' '.join([BINFILE, '-m', WEBMAKEFILE]) env = os.environ.copy() From 6911333494edfe5bd73d23d94fe6237c03b0c193 Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Fri, 12 Apr 2019 14:01:54 -0400 Subject: [PATCH 05/13] Py 2/3: when opening files, use encoding='utf-8' for Py 3. --- setup.py | 1 + webmake/modules/concat.py | 7 +++++-- webmake/modules/less.py | 5 +++-- webmake/modules/minify.py | 5 ++++- webmake/modules/sass.py | 5 +++-- webmake/modules/utils.py | 5 ++++- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index e31ca88..187a5e4 100644 --- a/setup.py +++ b/setup.py @@ -150,6 +150,7 @@ def run(self): # https://packaging.python.org/en/latest/requirements.html install_requires=[ 'watchdog>=0.8', + 'six', ], # List additional groups of dependencies here (e.g. development diff --git a/webmake/modules/concat.py b/webmake/modules/concat.py index 5938932..ed91217 100644 --- a/webmake/modules/concat.py +++ b/webmake/modules/concat.py @@ -1,6 +1,9 @@ import os +import six from . import utils +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + def _trimpath(path): comps = [] @@ -24,9 +27,9 @@ def concatenate_input_files(input_files, output_file, release=False): try: utils.logv('>>> concat {} > {}'.format(' '.join(input_files), output_file)) - with open(output_file, 'w') as output: + with open(output_file, 'w', **FILE_HANDLE_KWARGS) as output: for input_file in input_files: - with open(input_file, 'r') as input: + with open(input_file, 'r', **FILE_HANDLE_KWARGS) as input: output.write(input.read()) if not release: diff --git a/webmake/modules/less.py b/webmake/modules/less.py index ab682e8..b6fc638 100644 --- a/webmake/modules/less.py +++ b/webmake/modules/less.py @@ -1,14 +1,15 @@ import os import re +import six from . import utils - +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') LESS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.less)?)['"]\s*;""") def _read_less_imports(file): deps = [] - with open(file) as f: + with open(file, **FILE_HANDLE_KWARGS) as f: less = f.read() imports = LESS_IMPORT_RE.findall(less) less_dir = os.path.dirname(file) diff --git a/webmake/modules/minify.py b/webmake/modules/minify.py index 70d128b..82a3ade 100644 --- a/webmake/modules/minify.py +++ b/webmake/modules/minify.py @@ -1,6 +1,9 @@ import os +import six from . import utils, concat +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + def minify_js(input_files, output_file, release=False, annotate_angular=False): assert isinstance(input_files, (list, tuple)) @@ -70,7 +73,7 @@ def minify_css(input_files, output_file, release=False): raise try: - with open(output_file, 'w') as f: + with open(output_file, 'w', **FILE_HANDLE_KWARGS) as f: f.write(output) except IOError as e: utils.ensure_deleted(output_file) diff --git a/webmake/modules/sass.py b/webmake/modules/sass.py index 5154279..1f9bfb6 100644 --- a/webmake/modules/sass.py +++ b/webmake/modules/sass.py @@ -1,14 +1,15 @@ import os import re +import six from . import utils - +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') SASS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.s[ca]ss)?)['"]\s*;""") def _read_sass_imports(file): deps = [] - with open(file) as f: + with open(file, **FILE_HANDLE_KWARGS) as f: sassfile = f.read() imports = SASS_IMPORT_RE.findall(sassfile) sass_dir = os.path.dirname(file) diff --git a/webmake/modules/utils.py b/webmake/modules/utils.py index 52fe733..24b2f22 100644 --- a/webmake/modules/utils.py +++ b/webmake/modules/utils.py @@ -1,9 +1,12 @@ import re import os +import six import subprocess from subprocess import CalledProcessError from .. import settings +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + def log(msg, *args, **kwargs): """ @@ -182,7 +185,7 @@ def extract_line_num(output, regexp): def extract_lines_from_source(source, line_num): start = max(0, line_num - 5) - with open(source, 'r') as f: + with open(source, 'r', **FILE_HANDLE_KWARGS) as f: lines = f.readlines()[start:start + 10] ret = ['{}: {}'.format(i + start + 1, l) for (i, l) in enumerate(lines)] From 061792410f8fda5b5d4dc17b01720ff35b479a6a Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Wed, 12 Jun 2019 18:31:35 -0400 Subject: [PATCH 06/13] - Lists: adding migration to create/populate the ProductFieldDefinition objects. - Adminx: job details page, bulk import handler, view tests - Buyer order form (templates & js) - Buyer labels editor popup (templates & js) - Buyer job details - Various buyer form/view updates - Common: label update handler --- .../lib.linux-x86_64-2.7/webmake/__init__.py | 0 .../lib.linux-x86_64-2.7/webmake/__main__.py | 2 + build/lib.linux-x86_64-2.7/webmake/api.py | 259 ++++++++++++++++++ .../lib.linux-x86_64-2.7/webmake/compiler.py | 111 ++++++++ .../hooks/before_prepare/runwebmake.py | 9 + .../webmake/django/__init__.py | 0 .../webmake/django/middleware.py | 72 +++++ build/lib.linux-x86_64-2.7/webmake/main.py | 86 ++++++ .../webmake/modules/__init__.py | 0 .../webmake/modules/bless.py | 18 ++ .../webmake/modules/browserify.py | 161 +++++++++++ .../webmake/modules/concat.py | 46 ++++ .../webmake/modules/copyfiles.py | 42 +++ .../webmake/modules/less.py | 60 ++++ .../webmake/modules/minify.py | 80 ++++++ .../webmake/modules/reactjs.py | 40 +++ .../webmake/modules/sass.py | 52 ++++ .../webmake/modules/utils.py | 195 +++++++++++++ .../lib.linux-x86_64-2.7/webmake/package.json | 17 ++ .../lib.linux-x86_64-2.7/webmake/settings.py | 13 + build/lib.linux-x86_64-2.7/webmake/watcher.py | 54 ++++ build/lib/webmake/__init__.py | 0 build/lib/webmake/__main__.py | 2 + build/lib/webmake/api.py | 259 ++++++++++++++++++ build/lib/webmake/compiler.py | 111 ++++++++ .../hooks/before_prepare/runwebmake.py | 9 + build/lib/webmake/django/__init__.py | 0 build/lib/webmake/django/middleware.py | 72 +++++ build/lib/webmake/main.py | 86 ++++++ build/lib/webmake/modules/__init__.py | 0 build/lib/webmake/modules/bless.py | 18 ++ build/lib/webmake/modules/browserify.py | 161 +++++++++++ build/lib/webmake/modules/concat.py | 46 ++++ build/lib/webmake/modules/copyfiles.py | 42 +++ build/lib/webmake/modules/less.py | 60 ++++ build/lib/webmake/modules/minify.py | 80 ++++++ build/lib/webmake/modules/sass.py | 52 ++++ build/lib/webmake/modules/utils.py | 195 +++++++++++++ build/lib/webmake/package.json | 17 ++ build/lib/webmake/settings.py | 13 + build/lib/webmake/watcher.py | 54 ++++ 41 files changed, 2594 insertions(+) create mode 100644 build/lib.linux-x86_64-2.7/webmake/__init__.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/__main__.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/api.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/compiler.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/cordova/hooks/before_prepare/runwebmake.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/django/__init__.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/django/middleware.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/main.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/__init__.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/bless.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/browserify.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/concat.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/copyfiles.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/less.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/minify.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/reactjs.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/sass.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/utils.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/package.json create mode 100644 build/lib.linux-x86_64-2.7/webmake/settings.py create mode 100644 build/lib.linux-x86_64-2.7/webmake/watcher.py create mode 100644 build/lib/webmake/__init__.py create mode 100644 build/lib/webmake/__main__.py create mode 100644 build/lib/webmake/api.py create mode 100644 build/lib/webmake/compiler.py create mode 100644 build/lib/webmake/cordova/hooks/before_prepare/runwebmake.py create mode 100644 build/lib/webmake/django/__init__.py create mode 100644 build/lib/webmake/django/middleware.py create mode 100644 build/lib/webmake/main.py create mode 100644 build/lib/webmake/modules/__init__.py create mode 100644 build/lib/webmake/modules/bless.py create mode 100644 build/lib/webmake/modules/browserify.py create mode 100644 build/lib/webmake/modules/concat.py create mode 100644 build/lib/webmake/modules/copyfiles.py create mode 100644 build/lib/webmake/modules/less.py create mode 100644 build/lib/webmake/modules/minify.py create mode 100644 build/lib/webmake/modules/sass.py create mode 100644 build/lib/webmake/modules/utils.py create mode 100644 build/lib/webmake/package.json create mode 100644 build/lib/webmake/settings.py create mode 100644 build/lib/webmake/watcher.py diff --git a/build/lib.linux-x86_64-2.7/webmake/__init__.py b/build/lib.linux-x86_64-2.7/webmake/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/build/lib.linux-x86_64-2.7/webmake/__main__.py b/build/lib.linux-x86_64-2.7/webmake/__main__.py new file mode 100644 index 0000000..9dab16c --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/__main__.py @@ -0,0 +1,2 @@ +import webmake.main +webmake.main.main() diff --git a/build/lib.linux-x86_64-2.7/webmake/api.py b/build/lib.linux-x86_64-2.7/webmake/api.py new file mode 100644 index 0000000..363ec1c --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/api.py @@ -0,0 +1,259 @@ + + +def list_matching_files(dir, extensions=None, recursive=True): + """ + Returns a list of all files in the specified directory, + optionally recursively and/or with the specified extensions. + """ + from .modules import utils + return utils.list_matching_files(dir, extensions=extensions, recursive=recursive) + + +def concatenate(input_files, output_file): + """ + Concatenates the input files into the single output file. + + In debug mode this function adds a comment with the filename + before the contents of each file. + """ + from .modules import utils, concat + + if not isinstance(input_files, (list, tuple)): + raise RuntimeError('Concatenate takes a list of input files.') + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': concat.concatenate_input_files, + 'input': input_files, + 'output': output_file, + 'kwargs': {}, + } + + +def copy_files(src_dir, dst_dir, filespec='*', recursive=False): + """ + Copies any files matching filespec from src_dir into dst_dir. + + If `recursive` is `True`, also copies any matching directories. + """ + import os + from .modules import copyfiles + + if src_dir == dst_dir: + raise RuntimeError('copy_files() src and dst directories must be different.') + + if not os.path.isdir(src_dir): + raise RuntimeError('copy_files() src directory "{}" does not exist.'.format(src_dir)) + + return { + 'dependencies_fn': copyfiles.list_files, + 'compiler_fn': copyfiles.copy_files, + 'input': src_dir, + 'output': dst_dir, + 'kwargs': { + 'filespec': filespec, + 'recursive': recursive, + }, + } + + +def minify_js(input_files, output_file, annotate_angular=False): + """ + Minifies the input javascript files to the output file. + + Output file may be same as input to minify in place. + + In debug mode this function just concatenates the files + without minifying. + """ + from functools import partial + from .modules import minify, utils + + if not isinstance(input_files, (list, tuple)): + raise RuntimeError('JS minifier takes a list of input files.') + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': partial(minify.minify_js, annotate_angular=annotate_angular), + 'input': input_files, + 'output': output_file, + 'kwargs': {}, + } + + +def minify_css(input_files, output_file): + """ + Minifies the input CSS files to the output file. + + Output file may be same as input to minify in place. + + In debug mode this function just concatenates the files + without minifying. + """ + from .modules import minify, utils + + if not isinstance(input_files, (list, tuple)): + raise RuntimeError('CSS minifier takes a list of input files.') + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': minify.minify_css, + 'input': input_files, + 'output': output_file, + 'kwargs': {}, + } + + +def split_css_for_ie_selector_limit(input_file, output_file): + """ + Splits a large CSS file into several smaller files, each one + containing less than the IE 4096 selector limit. + """ + from .modules import bless, utils + + if not isinstance(input_file, str): + raise RuntimeError('CSS splitter takes only a single input file.') + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': bless.bless_css, + 'input': input_file, + 'output': output_file, + 'kwargs': {}, + } + + +def compile_less(input_file, output_file): + """ + Compile a LESS source file. Minifies the output in release mode. + """ + from .modules import less + + if not isinstance(input_file, str): + raise RuntimeError('LESS compiler takes only a single input file.') + + return { + 'dependencies_fn': less.less_dependencies, + 'compiler_fn': less.less_compile, + 'input': input_file, + 'output': output_file, + 'kwargs': {}, + } + + +def compile_sass(input_file, output_file): + """ + Compile a SASS source file. Minifies the output in release mode. + """ + from .modules import sass + + if not isinstance(input_file, str): + raise RuntimeError('SASS compiler takes only a single input file.') + + return { + 'dependencies_fn': sass.sass_dependencies, + 'compiler_fn': sass.sass_compile, + 'input': input_file, + 'output': output_file, + 'kwargs': {}, + } + + +def browserify_node_modules(module_name_list, output_file, babelify=False): + """ + Browserify a list of libraries from node_modules into a single + javascript file. Generates source maps in debug mode. Minifies the + output in release mode. + + Note you may also specify the relative path to the module + as ``./path/to/module`` or ``./path/to/module/file.js``. + """ + from .modules import browserify + + if not isinstance(module_name_list, (list, tuple)): + raise RuntimeError('Browserify Node Modules compiler takes a list of node module names as input.') + + return { + 'dependencies_fn': browserify.browserify_deps_node_modules, + 'compiler_fn': browserify.browserify_compile_node_modules, + 'input': module_name_list, + 'output': output_file, + 'kwargs': { + 'babelify': babelify, + }, + } + + +def browserify_libs(lib_dirs, output_file, babelify=False): + """ + Browserify one or more library directories into a single + javascript file. Generates source maps in debug mode. Minifies the + output in release mode. + + The final directory name in each of lib_dirs is the library name + for importing. Eg.:: + + lib_dirs = ['cordova_libs/jskit'] + + var MyClass = require('jskit/MyClass'); + """ + from .modules import browserify + + if not isinstance(lib_dirs, (list, tuple)): + raise RuntimeError('Browserify Libs compiler takes a list of library directories as input.') + + return { + 'dependencies_fn': browserify.browserify_deps_libs, + 'compiler_fn': browserify.browserify_compile_libs, + 'input': lib_dirs, + 'output': output_file, + 'kwargs': { + 'babelify': babelify, + }, + } + + +def browserify_file(entry_point, output_file, babelify=False, export_as=None): + """ + Browserify a single javascript entry point plus non-external + dependencies into a single javascript file. Generates source maps + in debug mode. Minifies the output in release mode. + + By default, it is not possible to ``require()`` any exports from the entry + point or included files. If ``export_as`` is specified, any module exports + in the specified entry point are exposed for ``require()`` with the + name specified by ``export_as``. + """ + from .modules import browserify + + if not isinstance(entry_point, str): + raise RuntimeError('Browserify File compiler takes a single entry point as input.') + + return { + 'dependencies_fn': browserify.browserify_deps_file, + 'compiler_fn': browserify.browserify_compile_file, + 'input': entry_point, + 'output': output_file, + 'kwargs': { + 'babelify': babelify, + 'export_as': export_as, + }, + } + + +def custom_function(func, input_files, output_file): + """ + Calls a custom function which must create the output file. + + The custom function takes 3 parameters: ``input_files``, + ``output_file`` and a boolean ``release``. + """ + from .modules import utils + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': func, + 'input': input_files, + 'output': output_file, + 'kwargs': {}, + } diff --git a/build/lib.linux-x86_64-2.7/webmake/compiler.py b/build/lib.linux-x86_64-2.7/webmake/compiler.py new file mode 100644 index 0000000..4ddd84e --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/compiler.py @@ -0,0 +1,111 @@ +import os +import json +from .modules.utils import log, logv, StaticCompilerError + + +def load_dependencies_for_target(target, makefilepath): + logv('\nFinding dependencies for: {}'.format(target['output'])) + try: + dependency_fn = target['dependencies_fn'] + target['dependencies'] = [makefilepath] + dependency_fn(target['input'], **target['kwargs']) + except (IOError, OSError) as e: + msg = '\nERROR: Failed loading dependencies for "{}":\n\nReceived error:\n{}'.format(target['output'], str(e)) + log(msg) + return False + except StaticCompilerError as e: + log(str(e)) + return False + + return True + + +def save_dependencies_to_cache(targets, makefilepath): + cachefile = makefilepath + '.depscache' + logv('\nWriting dependencies cache: {}'.format(cachefile)) + + cache = [{'output': t['output'], 'dependencies': t['dependencies']} + for t in targets if 'dependencies' in t] + + with open(cachefile, 'w') as f: + json.dump(cache, f, indent=4) + + +def load_dependencies_from_cache(targets, makefilepath): + cachefile = makefilepath + '.depscache' + try: + with open(cachefile, 'r') as f: + cache = json.load(f) + except IOError: + return + + for i, entry in enumerate(cache): + output = entry['output'] + deps = entry['dependencies'] + + if i >= len(targets): + break + + if targets[i]['output'] == output: + targets[i]['dependencies'] = deps + + +def dependencies_are_up_to_date(target): + output = target['output'] + deps = target.get('dependencies') + last_compiled_timestamp = os.path.getmtime(output) if os.path.exists(output) else -1 + + if not deps: + return False + + for file in deps: + try: + if os.path.getmtime(file) >= last_compiled_timestamp: + return False + except Exception: + return False + + return True + + +def compile_if_modified(targets, makefilepath, release): + modified = False + first_up_to_date = True + + for target in targets: + if dependencies_are_up_to_date(target): + if first_up_to_date: + logv('') + first_up_to_date = False + logv('Up-to-date: {}', target['output']) + else: + modified = True + first_up_to_date = True + if not compile_target(target, makefilepath, release=release): + return False + + if modified: + save_dependencies_to_cache(targets, makefilepath) + + return True + + +def compile_all(targets, makefilepath, release): + for target in targets: + if not compile_target(target, makefilepath, release=release): + return False + + save_dependencies_to_cache(targets, makefilepath) + return True + + +def compile_target(target, makefilepath, release): + try: + logv('\nCompiling: {}'.format(target['output'])) + compiler_fn = target['compiler_fn'] + compiler_fn(target['input'], target['output'], release=release, **target['kwargs']) + load_dependencies_for_target(target, makefilepath) + return True + except StaticCompilerError as e: + log(str(e)) + return False + diff --git a/build/lib.linux-x86_64-2.7/webmake/cordova/hooks/before_prepare/runwebmake.py b/build/lib.linux-x86_64-2.7/webmake/cordova/hooks/before_prepare/runwebmake.py new file mode 100644 index 0000000..2c8cff2 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/cordova/hooks/before_prepare/runwebmake.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +import os + +cmdline = 'webmk -v' +if '--release' in os.environ['CORDOVA_CMDLINE']: + cmdline += ' --force --release' + +print(cmdline) +os.system(cmdline) diff --git a/build/lib.linux-x86_64-2.7/webmake/django/__init__.py b/build/lib.linux-x86_64-2.7/webmake/django/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/build/lib.linux-x86_64-2.7/webmake/django/middleware.py b/build/lib.linux-x86_64-2.7/webmake/django/middleware.py new file mode 100644 index 0000000..84056d3 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/django/middleware.py @@ -0,0 +1,72 @@ +""" +Middleware class to watch dependencies and automatically +compile static files during development. + +Usage +----- + +1. Add the following to your local/development settings:: + + # Webmake Middleware + MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + ( + 'webmake.django.middleware.WebmakeCompilerMiddleware', + ) + +2. Create a ``webmakefile.py`` in your project root, and add the +files to compile. + +3. Call ``webmk -fr`` from your deployment process to create +release versions of all target files:: + + def pre_process(self, deployment_settings, *args, **kwargs): + with lcd(PROJECT_PATH): + local('webmk -fr') +""" +import re +import os +import sys +import subprocess +import warnings +from django.conf import settings # pylint: disable=import-error + + +SETTINGS_ROOT = os.path.dirname(os.path.abspath(os.path.join(sys.modules[settings.SETTINGS_MODULE].__file__))) +PROJECT_ROOT = os.path.abspath(os.path.join(re.sub(r'settings[/\\]?$', '', SETTINGS_ROOT), os.pardir)) +WEBMAKE_BIN = 'webmk' +WEBMAKEFILE = os.path.join(PROJECT_ROOT, 'webmakefile.py') + +POSSIBLE_BINFILES = [f for f in ( + os.path.join(os.path.dirname(sys.executable), WEBMAKE_BIN), + os.path.join(os.path.dirname(sys.executable), WEBMAKE_BIN + '.exe'), + ) if os.path.isfile(f)] + +BINFILE = POSSIBLE_BINFILES[0] if POSSIBLE_BINFILES else WEBMAKE_BIN + + +class WebmakeRuntimeWarning(RuntimeWarning): + pass + + +class WebmakeCompilerMiddleware: + def __init__(self, get_response=None): + self.get_response = get_response + + def __call__(self, request): + self.process_request(request) + return self.get_response(request) + + def process_request(self, request): + if not settings.DEBUG: + warnings.warn('WebmakeCompilerMiddleware should not be used in production!', WebmakeRuntimeWarning) + + cmd = ' '.join([BINFILE, '-m', WEBMAKEFILE]) + env = os.environ.copy() + env.pop('PYTHONPATH', None) + + try: + subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True, env=env) + except subprocess.CalledProcessError as e: + output = e.output.decode('utf-8') if hasattr(e.output, 'decode') else str(e.output) + raise RuntimeError('WebmakeCompilerMiddleware:\n' + output) + + return None diff --git a/build/lib.linux-x86_64-2.7/webmake/main.py b/build/lib.linux-x86_64-2.7/webmake/main.py new file mode 100644 index 0000000..4affb99 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/main.py @@ -0,0 +1,86 @@ +import os +import sys +import argparse +import importlib +import functools +import traceback +from .modules import utils +from . import settings, compiler, watcher + + +def command_line_error(parser, makefile, message): + tb = sys.exc_info()[2] + lineinfo = '' + if tb: + try: + tb = [s for s in reversed(traceback.extract_tb(tb)) if s[0].endswith('webmakefile.py')][0] + lineinfo = 'webmakefile.py:{}: '.format(tb[1]) + except IndexError: + pass + + msg = '\nProcessing: {}\n\n{}{}'.format(makefile, lineinfo, message) + parser.error(msg) + + +def parse_command_line(): + default_webmakefile = os.path.join(os.getcwd(), 'webmakefile.py') + + parser = argparse.ArgumentParser(description='A simple pythonic build system for Web and Cordova projects (JS,Less,Sass...)') + parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output.') + parser.add_argument('-r', '--release', action='store_true', help='Release mode. Minify output and don\'t generate source maps.') + parser.add_argument('-f', '--force', action='store_true', help='Force recompilation of all source files, even if not modified.') + parser.add_argument('-m', '--makefile', default=default_webmakefile, help='Specify the webmakefile.py to use for compilation settings.') + parser.add_argument('-w', '--watch', action='store_true', help='Watch all input files for changes, and recompile automatically.') + + args = parser.parse_args() + error_fn = functools.partial(command_line_error, parser, args.makefile) + + if not args.makefile or not os.path.isfile(args.makefile): + error_fn('webmakefile.py does not exist, please create one in ' + 'your project root and run from there.') + + return (args, error_fn) + + +def main(): + args, error_fn = parse_command_line() + settings.VERBOSE = args.verbose + settings.RELEASE = args.release + settings.FORCE = args.force + settings.MAKEFILEPATH = args.makefile + + webmakefile_dir = os.path.abspath(os.path.expanduser(os.path.dirname(args.makefile))) + webmakefile_name = os.path.basename(args.makefile) + webmakefile_module = os.path.splitext(webmakefile_name)[0] + + os.chdir(webmakefile_dir) + sys.path.insert(0, webmakefile_dir) + + try: + makefile = importlib.import_module(webmakefile_module) + except RuntimeError as e: + error_fn(str(e)) + except Exception as e: # pylint: disable=broad-except + error_fn('Unable to parse webmakefile.py.\n\n{}'.format(str(e))) + + try: + settings.MAKEFILE = makefile.MAKEFILE + except AttributeError: + error_fn('MAKEFILE variable missing in webmakefile.py.') + + utils.logv('WEBMAKEFILE = {}', os.path.join(webmakefile_dir, webmakefile_name)) + utils.logv('RELEASE MODE = {}', ('On' if settings.RELEASE else 'Off')) + utils.logv('FORCE COMPILATION = {}', ('On' if settings.FORCE else 'Off')) + + # Load any cached dependencies + compiler.load_dependencies_from_cache(settings.MAKEFILE, settings.MAKEFILEPATH) + + if settings.FORCE: + if not compiler.compile_all(settings.MAKEFILE, settings.MAKEFILEPATH, settings.RELEASE): + sys.exit(1) + else: + if not compiler.compile_if_modified(settings.MAKEFILE, settings.MAKEFILEPATH, release=settings.RELEASE): + sys.exit(1) + + if args.watch: + watcher.start_watching() diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/__init__.py b/build/lib.linux-x86_64-2.7/webmake/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/bless.py b/build/lib.linux-x86_64-2.7/webmake/modules/bless.py new file mode 100644 index 0000000..dc51d77 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/modules/bless.py @@ -0,0 +1,18 @@ +from . import utils + + +def bless_css(input_file, output_file, release=False): + assert isinstance(input_file, str) + + cmdline = [ + utils.get_node_bin_dir('blessc'), + '--no-imports', + ] + cmdline.append(input_file) + cmdline.append(output_file) + + try: + utils.run_command(cmdline, 'Failed to split CSS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + raise diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/browserify.py b/build/lib.linux-x86_64-2.7/webmake/modules/browserify.py new file mode 100644 index 0000000..25950aa --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/modules/browserify.py @@ -0,0 +1,161 @@ +import os +from . import utils, minify + + +def get_extensions_and_params(babelify=False): + extensions = ['.js'] + params = [] + + if babelify: + babelify = utils.get_node_modules_dir('babelify') + preset_es2015 = utils.get_node_modules_dir('babel-preset-es2015') + preset_react = utils.get_node_modules_dir('babel-preset-react') + extensions.extend(['.jsx']) + params.extend(['-t', '[', babelify, '--presets', '[', preset_es2015, preset_react, ']', ']']) + + return (extensions, params) + + +def browserify_basic_error(func_name, output_file, list_deps): + if list_deps: + return 'Failed to list dependencies in {}()'.format(func_name) + else: + return 'Error compiling with {}() to "{}"'.format(func_name, output_file) + + +def browserify_basic_command(output_file, release, list_deps): + sourcemap = '-d' if not release else '' + + cmdline = [ + utils.get_node_bin_dir('browserify'), + ] + + if list_deps: + cmdline.extend([ + '--list', + '--fast', + ]) + else: + cmdline.extend([ + sourcemap, + '-o', + output_file, + ]) + + return cmdline + + +def browserify_run(cmdline, errmsg, output_file, release, list_deps): + env = {'NODE_ENV': 'production'} if release else None + + try: + if output_file: + utils.ensure_path_exists(os.path.dirname(output_file)) + + output = utils.run_command(cmdline, errmsg, env=env) + if list_deps: + return [os.path.abspath(p) if os.path.exists(p) else p for p in output.splitlines()] + elif release: + minify.minify_js([output_file], output_file, release=release) + except: + if output_file: + utils.ensure_deleted(output_file) + raise + + +def browserify_node_modules(module_list, output_file=None, release=False, list_deps=False, babelify=False): + (_, params) = get_extensions_and_params(babelify=babelify) + errmsg = browserify_basic_error('browserify_node_modules', output_file, list_deps) + + # No source maps for vendor libs, load time is too slow + cmdline = browserify_basic_command(output_file, release=True, list_deps=list_deps) + cmdline.extend(params) + + for m in module_list: + if m.startswith('./'): + cmdline.extend(['-r', m + ':' + os.path.basename(m).rsplit('.', maxsplit=1)[0]]) + else: + cmdline.extend(['-r', m]) + + result = browserify_run(cmdline, errmsg, output_file, release, list_deps) + + if list_deps: + def fix_node_modules_path(path): + newpath = os.path.abspath(os.path.join('node_modules', path)) + return newpath if not os.path.exists(path) and os.path.exists(newpath) else path + result = [fix_node_modules_path(p) for p in result] + + return result + + +def browserify_libs(lib_dirs, output_file=None, release=False, list_deps=False, babelify=False): + (exts, params) = get_extensions_and_params(babelify=babelify) + errmsg = browserify_basic_error('browserify_libs', output_file, list_deps) + + cmdline = browserify_basic_command(output_file, release, list_deps) + cmdline.append('--no-bundle-external') + cmdline.extend(params) + + for dir in lib_dirs: + files = utils.list_matching_files(dir, extensions=exts, recursive=True, linux_style_paths=True) + dir = dir.replace('\\', '/') + libname = os.path.basename(dir.rstrip('/\\')) + + for f in files: + assert f.startswith(dir) + newname = libname + os.path.splitext(f[len(dir):])[0] + if not os.path.isabs(f): + f = './' + f + cmdline.extend(['-r', '{}:{}'.format(f, newname)]) + + return browserify_run(cmdline, errmsg, output_file, release, list_deps) + + +def browserify_file(entry_point, output_file=None, release=False, list_deps=False, babelify=False, export_as=None): + (_, params) = get_extensions_and_params(babelify=babelify) + errmsg = browserify_basic_error('browserify_file', output_file, list_deps) + + cmdline = browserify_basic_command(output_file, release, list_deps) + cmdline.append('--no-bundle-external') + cmdline.extend(params) + + if not export_as: + cmdline.extend([ + '-e', + entry_point, + ]) + else: + f = entry_point.replace('\\', '/') + if not os.path.isabs(f): + f = './' + f + + cmdline.extend([ + '-r', + '{}:{}'.format(f, export_as) + ]) + + return browserify_run(cmdline, errmsg, output_file, release, list_deps) + + +def browserify_deps_node_modules(module_list, babelify=False): + return browserify_node_modules(module_list, list_deps=True, babelify=babelify) + + +def browserify_compile_node_modules(module_list, output_file, release=False, babelify=False): + browserify_node_modules(module_list, output_file, release=release, babelify=babelify) + + +def browserify_deps_libs(lib_dirs, babelify=False): + return browserify_libs(lib_dirs, list_deps=True, babelify=babelify) + + +def browserify_compile_libs(lib_dirs, output_file, release=False, babelify=False): + browserify_libs(lib_dirs, output_file, release=release, babelify=babelify) + + +def browserify_deps_file(entry_point, babelify=False, export_as=None): + return browserify_file(entry_point, list_deps=True, babelify=babelify, export_as=export_as) + + +def browserify_compile_file(entry_point, output_file, release=False, babelify=False, export_as=None): + browserify_file(entry_point, output_file, release=release, babelify=babelify, export_as=export_as) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/concat.py b/build/lib.linux-x86_64-2.7/webmake/modules/concat.py new file mode 100644 index 0000000..ed91217 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/modules/concat.py @@ -0,0 +1,46 @@ +import os +import six +from . import utils + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + + +def _trimpath(path): + comps = [] + for _ in range(3): + path, c = os.path.split(path) + comps.append(c) + return os.path.join(*reversed(comps)).replace('\\', '/') + + +def concatenate_input_files(input_files, output_file, release=False): + assert isinstance(input_files, (list, tuple)) + + if len(input_files) == 1 and input_files[0] == output_file: + return + + for f in input_files: + assert f != output_file, 'Concatenate input file is same as output.' + + if output_file: + utils.ensure_path_exists(os.path.dirname(output_file)) + + try: + utils.logv('>>> concat {} > {}'.format(' '.join(input_files), output_file)) + with open(output_file, 'w', **FILE_HANDLE_KWARGS) as output: + for input_file in input_files: + with open(input_file, 'r', **FILE_HANDLE_KWARGS) as input: + output.write(input.read()) + + if not release: + path = _trimpath(input_file) + output.write('\n\n' + '/*\n' + ' * {caret}\n' + ' * {path} \n' + ' * {caret}\n' + ' */\n\n\n'.format(path=path, caret='^' * len(path))) + + except IOError as e: + utils.ensure_deleted(output_file) + raise utils.StaticCompilerError('Failed to concatenate to {}'.format(output_file), error=str(e)) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/copyfiles.py b/build/lib.linux-x86_64-2.7/webmake/modules/copyfiles.py new file mode 100644 index 0000000..e7a53b1 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/modules/copyfiles.py @@ -0,0 +1,42 @@ +import os +import shutil +from fnmatch import fnmatch +from . import utils + + +def list_files(src_dir, filespec, recursive=False, include_dirs=True): + inputs = [] + + for dir, _, files in os.walk(src_dir): + if include_dirs: + inputs.append(dir) + + inputs.extend(os.path.join(dir, f) for f in files if match_file(f)) + + if not recursive: + break + + return inputs + + +def copy_files(src_dir, dst_dir, filespec, recursive=False, release=None): + assert src_dir != dst_dir, 'Source and destination directories are the same.' + assert os.path.isdir(src_dir), 'Source directory "{}" does not exist.'.format(src_dir) + + if not os.path.isdir(dst_dir): + try: + os.mkdir(dst_dir) + except OSError as e: + raise utils.StaticCompilerError('Failed to create destination dir "{}"'.format(dst_dir), error=str(e)) + + input_files = list_files(src_dir, filespec, recursive, include_dirs=False) + output_files = [os.path.join(dst_dir, os.path.relpath(p, src_dir)) for p in input_files] + + for input, output in zip(input_files, output_files): + utils.logv('>>> copy {} > {}'.format(input, output)) + dirname = os.path.split(output)[0] + if not os.path.exists(dirname): + os.mkdir(dirname) + shutil.copy2(input, output) + + os.utime(dst_dir, None) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/less.py b/build/lib.linux-x86_64-2.7/webmake/modules/less.py new file mode 100644 index 0000000..b6fc638 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/modules/less.py @@ -0,0 +1,60 @@ +import os +import re +import six +from . import utils + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') +LESS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.less)?)['"]\s*;""") + + +def _read_less_imports(file): + deps = [] + with open(file, **FILE_HANDLE_KWARGS) as f: + less = f.read() + imports = LESS_IMPORT_RE.findall(less) + less_dir = os.path.dirname(file) + + for imp in imports: + dep = utils.resolve_possible_paths(imp, less_dir, ['.less']) + if dep: + deps.append(dep) + else: + raise ValueError('Invalid LESS import in {}: {}'.format(file, imp)) + + return deps + + +def less_dependencies(input_file): + return utils.breadth_first_search(_read_less_imports, input_file) + + +def less_compile(input_file, output_file, release=False): + map_file = output_file + '.map' + input_abs = os.path.abspath(os.path.dirname(input_file)) + output_abs = os.path.abspath(os.path.dirname(output_file)) + map_url = os.path.basename(map_file) + map_base = os.path.commonprefix([input_abs, output_abs]).replace('\\', '/') + map_rel = os.path.dirname(output_abs[len(map_base):]).replace('\\', '/') + map_root = '/'.join([os.pardir] * len(map_rel.split('/'))) + + minify = '-x' if release else '' + sourcemap = ('-source-map-rootpath={rp} --source-map-basepath={bp} --source-map-url={url} --source-map={map}' + .format(rp=map_root, bp=map_base, url=map_url, map=map_file) + if not release else '') + + cmdline = [ + utils.get_node_bin_dir('lessc'), + '--no-color', + minify, + sourcemap, + input_file, + output_file, + ] + + try: + utils.ensure_deleted(map_file) + utils.run_command(cmdline, 'Failed to compile LESS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + utils.ensure_deleted(map_file) + raise diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/minify.py b/build/lib.linux-x86_64-2.7/webmake/modules/minify.py new file mode 100644 index 0000000..82a3ade --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/modules/minify.py @@ -0,0 +1,80 @@ +import os +import six +from . import utils, concat + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + + +def minify_js(input_files, output_file, release=False, annotate_angular=False): + assert isinstance(input_files, (list, tuple)) + + concat.concatenate_input_files(input_files, output_file, release=release) + + if not release: + return + + if annotate_angular: + try: + annotate_angular_injections(output_file, output_file) + except: + # utils.ensure_deleted(output_file) + raise + + if output_file: + utils.ensure_path_exists(os.path.dirname(output_file)) + + cmdline = [ + utils.get_node_bin_dir('uglifyjs'), + '--compress', + '--mangle', + '-o', + output_file, + '--', + ] + cmdline.extend([output_file]) + + try: + utils.run_command(cmdline, 'Failed to minify JS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + raise + +def annotate_angular_injections(input_file, output_file): + cmdline = [ + utils.get_node_bin_dir('ng-annotate'), + '--add', + '-o', + output_file, + ] + cmdline.extend([input_file]) + + try: + utils.run_command(cmdline, 'Failed to annotate Annnngular injections to "{}"'.format(output_file)) + except Exception as e: + # utils.ensure_deleted(output_file) + raise + +def minify_css(input_files, output_file, release=False): + assert isinstance(input_files, (list, tuple)) + + concat.concatenate_input_files(input_files, output_file, release=release) + if not release: + return + + cmdline = [ + utils.get_node_bin_dir('cssmin'), + ] + cmdline.append(output_file) + + try: + output = utils.run_command(cmdline, 'Failed to minify CSS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + raise + + try: + with open(output_file, 'w', **FILE_HANDLE_KWARGS) as f: + f.write(output) + except IOError as e: + utils.ensure_deleted(output_file) + raise utils.StaticCompilerError('Failed to minify CSS to "{}"'.format(output_file), str(e)) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/reactjs.py b/build/lib.linux-x86_64-2.7/webmake/modules/reactjs.py new file mode 100644 index 0000000..9efb403 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/modules/reactjs.py @@ -0,0 +1,40 @@ +import os +from . import utils, concat, minify + + +def jsx_compile(input_files, output_file, release=False): + utils.ensure_deleted(output_file) + + output_dir = os.path.dirname(output_file) + output_base = os.path.splitext(os.path.basename(output_file))[0] + tmp_file = os.path.join(output_dir, output_base + '.tmpjsx') + concat.concatenate_input_files(input_files, tmp_file, release=release) + + sourcemap = '--source-map-inline' if not release else '' + + cmdline = [ + utils.get_node_bin_dir('jsx'), + '--no-cache-dir', + sourcemap, + '--extension', + 'tmpjsx', + output_dir, + output_dir, + output_base, + ] + + try: + utils.run_command(cmdline, 'Failed to compile React JSX to "{}"'.format(output_file)) + except: + utils.ensure_deleted(tmp_file) + utils.ensure_deleted(output_base + '.js') + raise + + utils.ensure_deleted(tmp_file) + generated = os.path.abspath(os.path.join(output_dir, output_base + '.js')) + output = os.path.abspath(output_file) + if generated != output: + utils.rename(generated, output) + + if release: + minify.minify_js([output_file], output_file, release=release) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/sass.py b/build/lib.linux-x86_64-2.7/webmake/modules/sass.py new file mode 100644 index 0000000..1f9bfb6 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/modules/sass.py @@ -0,0 +1,52 @@ +import os +import re +import six +from . import utils + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') +SASS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.s[ca]ss)?)['"]\s*;""") + + +def _read_sass_imports(file): + deps = [] + with open(file, **FILE_HANDLE_KWARGS) as f: + sassfile = f.read() + imports = SASS_IMPORT_RE.findall(sassfile) + sass_dir = os.path.dirname(file) + + for imp in imports: + dep = utils.resolve_possible_paths(imp, sass_dir, ['.scss', '.sass'], leading_underscore=True) + if dep: + deps.append(dep) + else: + raise ValueError('Invalid SASS import in {}: {}'.format(file, imp)) + + return deps + + +def sass_dependencies(input_file): + return utils.breadth_first_search(_read_sass_imports, input_file) + + +def sass_compile(input_file, output_file, release=False): + map_file = output_file + '.map' + output_style = 'compressed' if release else 'expanded' + source_map = '--source-comments --source-map-embed --source-map-contents --source-map {}'.format(map_file) if not release else '' + + cmdline = [ + utils.get_node_bin_dir('node-sass'), + '--output-style', + output_style, + source_map, + input_file, + output_file, + ] + + try: + utils.ensure_deleted(map_file) + utils.run_command(cmdline, 'Failed to compile SASS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + raise + finally: + utils.ensure_deleted(map_file) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/utils.py b/build/lib.linux-x86_64-2.7/webmake/modules/utils.py new file mode 100644 index 0000000..24b2f22 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/modules/utils.py @@ -0,0 +1,195 @@ +import re +import os +import six +import subprocess +from subprocess import CalledProcessError +from .. import settings + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + + +def log(msg, *args, **kwargs): + """ + Print out a log message. + """ + if len(args) == 0 and len(kwargs) == 0: + print(msg) + else: + print(msg.format(*args, **kwargs)) + + +def logv(msg, *args, **kwargs): + """ + Print out a log message, only if verbose mode. + """ + if settings.VERBOSE: + log(msg, *args, **kwargs) + + +class StaticCompilerError(Exception): + def __init__(self, message, error=None, output=None, source=None): + super(StaticCompilerError, self).__init__() + self.message = message + self.error = error or '' + self.output = output or '' + self.source = source or '' + + def __str__(self): + err = [ + '\nERROR: ', + self.message, + '\n\nReceived error:\n', + self.error, + ] + + if self.output: + err.extend(['\n\nOutput:\n', self.output]) + + if self.source: + err.extend(['\n\nSource:\n', self.source]) + + return ''.join(err) + + +def breadth_first_search(get_deps_fn, root_file): + root_file = os.path.abspath(root_file) + queue = [root_file] + deps = [root_file] + + while len(queue) > 0: + cur_file = queue.pop(0) + new_deps = get_deps_fn(cur_file) + queue.extend(new_deps) + deps.extend(new_deps) + + return deps + + +def list_matching_files(path, extensions=None, recursive=True, linux_style_paths=False): + if isinstance(extensions, list): + extensions = tuple(extensions) + + result = [] + + if recursive: + it = os.walk(path) + else: + it = [(path, (), (f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))))] + + for (dir, _, files) in it: + if extensions: + files = [f for f in files if f.endswith(extensions)] + + for f in files: + f = os.path.join(dir, f) + if linux_style_paths: + f = f.replace('\\', '/') + result.append(f) + + return result + + +def ensure_path_exists(path): + path = os.path.abspath(path) + if not os.path.exists(path): + os.makedirs(path) + + +def ensure_deleted(*args): + for file in args: + try: + os.unlink(file) + except Exception: # pylint: disable=broad-except + pass + + +def rename(old, new): + ensure_deleted(new) + os.rename(old, new) + + +def resolve_possible_paths(path, relative_prefix, possible_extensions=None, leading_underscore=False): + """ + Attempts to resolve the given absolute or relative ``path``. If it + doesn't exist as is, tries to create an absolute path using the + ``relative_prefix``. If that fails, tries relative/absolute versions + with each of ``possible_extensions``. + + :returns: The absolute path, or ``None`` if no such file can be found. + """ + possible_extensions = [''] + list(possible_extensions) if possible_extensions else [''] + possible_paths = [path + e if os.path.isabs(path + e) else os.path.join(relative_prefix, path + e) + for e in possible_extensions] + + if leading_underscore and not os.path.basename(path).startswith('_'): + extra_paths = [os.path.join(os.path.dirname(p), '_' + os.path.basename(p)) + for p in possible_paths] + possible_paths = possible_paths + extra_paths + + for p in possible_paths: + p = os.path.normpath(p) + if os.path.isfile(p): + return p + + return None + + +def get_node_modules_dir(module=None): + moduledir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'node_modules')) + if module: + return os.path.join(moduledir, module) + else: + return moduledir + + +def get_node_bin_dir(cmd=None): + bindir = get_node_modules_dir('.bin') + if cmd: + return os.path.join(bindir, cmd) + else: + return bindir + + +def no_dependencies(input): + if not isinstance(input, (list, tuple)): + return [input] + else: + return input + + +def run_command(cmd, errmsg, env=None): + if env is not None: + newenv = os.environ.copy() + newenv.update(env) + env = newenv + + if isinstance(cmd, (list, tuple)): + cmd = ' '.join(c for c in cmd if c != '') + + try: + logv('>>> ' + cmd) + return subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT, shell=True).decode('ascii', 'replace') + except CalledProcessError as e: + raise StaticCompilerError(errmsg, str(e), e.output.decode('ascii', 'replace')) + + +def extract_line_num(output, regexp): + m = re.search(regexp, output) + if m: + try: + return int(m.group(1)) + except ValueError: + pass + return None + + +def extract_lines_from_source(source, line_num): + start = max(0, line_num - 5) + with open(source, 'r', **FILE_HANDLE_KWARGS) as f: + lines = f.readlines()[start:start + 10] + + ret = ['{}: {}'.format(i + start + 1, l) for (i, l) in enumerate(lines)] + ret[3] = ret[3].rstrip() + ' <<<<<<\n' + return ''.join(ret) + + diff --git a/build/lib.linux-x86_64-2.7/webmake/package.json b/build/lib.linux-x86_64-2.7/webmake/package.json new file mode 100644 index 0000000..9adf0a5 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/package.json @@ -0,0 +1,17 @@ +{ + "private": true, + "dependencies": { + "babel-cli": "^6.26.0", + "babel-core": "^6.26.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-react": "^6.24.1", + "babelify": "^8.0.0", + "bless": "^3.0.3", + "browserify": "^9.0.8", + "cssmin": "^0.4.3", + "less": "^2.7.3", + "ng-annotate": "1.x", + "node-sass": "^4.11.0", + "uglify-es": "^3.3.9" + } +} diff --git a/build/lib.linux-x86_64-2.7/webmake/settings.py b/build/lib.linux-x86_64-2.7/webmake/settings.py new file mode 100644 index 0000000..8c0f903 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/settings.py @@ -0,0 +1,13 @@ + +# Whether to show verbose log messages +VERBOSE = False + +# Whether to minify/exclude source maps for production +RELEASE = False + +# Whether to force compilation of all files, rather than compiling modified +FORCE = False + +# The makefile contents & path, and dependencies map +MAKEFILE = None +MAKEFILEPATH = None diff --git a/build/lib.linux-x86_64-2.7/webmake/watcher.py b/build/lib.linux-x86_64-2.7/webmake/watcher.py new file mode 100644 index 0000000..232d8d8 --- /dev/null +++ b/build/lib.linux-x86_64-2.7/webmake/watcher.py @@ -0,0 +1,54 @@ +import os +import time +import itertools +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +from .modules.utils import log +from . import settings, compiler + + +FORCE_EXIT = False + + +class WatchdogEventHandler(FileSystemEventHandler): + def on_any_event(self, event): + if event.is_directory or event.src_path.endswith('.depscache'): + return + + if os.path.abspath(event.src_path) == os.path.abspath(settings.MAKEFILEPATH): + log('Detected change to makefile {}, please restart the watcher.\n'.format(settings.MAKEFILEPATH)) + global FORCE_EXIT # pylint: disable=global-statement + FORCE_EXIT = True + return + + what = 'directory' if event.is_directory else 'file' + log('{} {} {}'.format(event.event_type.title(), what, event.src_path)) + + compiler.compile_if_modified(settings.MAKEFILE, settings.MAKEFILEPATH, settings.RELEASE) + log('') + + +def start_watching(): + log('\nWatching for filesystem changes, Ctrl-C to exit...\n') + settings.VERBOSE = True + + paths = itertools.chain.from_iterable(d['dependencies'] for d in settings.MAKEFILE) + paths = set(os.path.abspath(os.path.dirname(p)) for p in paths) + +# import pprint +# pprint.pprint(paths, indent=4) + + observer = Observer() + for path in paths: + observer.schedule(WatchdogEventHandler(), path, recursive=False) + observer.start() + + try: + while not FORCE_EXIT: + time.sleep(1) + raise KeyboardInterrupt() + except KeyboardInterrupt: + log('Shutting down...') + observer.stop() + + observer.join() diff --git a/build/lib/webmake/__init__.py b/build/lib/webmake/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/build/lib/webmake/__main__.py b/build/lib/webmake/__main__.py new file mode 100644 index 0000000..9dab16c --- /dev/null +++ b/build/lib/webmake/__main__.py @@ -0,0 +1,2 @@ +import webmake.main +webmake.main.main() diff --git a/build/lib/webmake/api.py b/build/lib/webmake/api.py new file mode 100644 index 0000000..363ec1c --- /dev/null +++ b/build/lib/webmake/api.py @@ -0,0 +1,259 @@ + + +def list_matching_files(dir, extensions=None, recursive=True): + """ + Returns a list of all files in the specified directory, + optionally recursively and/or with the specified extensions. + """ + from .modules import utils + return utils.list_matching_files(dir, extensions=extensions, recursive=recursive) + + +def concatenate(input_files, output_file): + """ + Concatenates the input files into the single output file. + + In debug mode this function adds a comment with the filename + before the contents of each file. + """ + from .modules import utils, concat + + if not isinstance(input_files, (list, tuple)): + raise RuntimeError('Concatenate takes a list of input files.') + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': concat.concatenate_input_files, + 'input': input_files, + 'output': output_file, + 'kwargs': {}, + } + + +def copy_files(src_dir, dst_dir, filespec='*', recursive=False): + """ + Copies any files matching filespec from src_dir into dst_dir. + + If `recursive` is `True`, also copies any matching directories. + """ + import os + from .modules import copyfiles + + if src_dir == dst_dir: + raise RuntimeError('copy_files() src and dst directories must be different.') + + if not os.path.isdir(src_dir): + raise RuntimeError('copy_files() src directory "{}" does not exist.'.format(src_dir)) + + return { + 'dependencies_fn': copyfiles.list_files, + 'compiler_fn': copyfiles.copy_files, + 'input': src_dir, + 'output': dst_dir, + 'kwargs': { + 'filespec': filespec, + 'recursive': recursive, + }, + } + + +def minify_js(input_files, output_file, annotate_angular=False): + """ + Minifies the input javascript files to the output file. + + Output file may be same as input to minify in place. + + In debug mode this function just concatenates the files + without minifying. + """ + from functools import partial + from .modules import minify, utils + + if not isinstance(input_files, (list, tuple)): + raise RuntimeError('JS minifier takes a list of input files.') + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': partial(minify.minify_js, annotate_angular=annotate_angular), + 'input': input_files, + 'output': output_file, + 'kwargs': {}, + } + + +def minify_css(input_files, output_file): + """ + Minifies the input CSS files to the output file. + + Output file may be same as input to minify in place. + + In debug mode this function just concatenates the files + without minifying. + """ + from .modules import minify, utils + + if not isinstance(input_files, (list, tuple)): + raise RuntimeError('CSS minifier takes a list of input files.') + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': minify.minify_css, + 'input': input_files, + 'output': output_file, + 'kwargs': {}, + } + + +def split_css_for_ie_selector_limit(input_file, output_file): + """ + Splits a large CSS file into several smaller files, each one + containing less than the IE 4096 selector limit. + """ + from .modules import bless, utils + + if not isinstance(input_file, str): + raise RuntimeError('CSS splitter takes only a single input file.') + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': bless.bless_css, + 'input': input_file, + 'output': output_file, + 'kwargs': {}, + } + + +def compile_less(input_file, output_file): + """ + Compile a LESS source file. Minifies the output in release mode. + """ + from .modules import less + + if not isinstance(input_file, str): + raise RuntimeError('LESS compiler takes only a single input file.') + + return { + 'dependencies_fn': less.less_dependencies, + 'compiler_fn': less.less_compile, + 'input': input_file, + 'output': output_file, + 'kwargs': {}, + } + + +def compile_sass(input_file, output_file): + """ + Compile a SASS source file. Minifies the output in release mode. + """ + from .modules import sass + + if not isinstance(input_file, str): + raise RuntimeError('SASS compiler takes only a single input file.') + + return { + 'dependencies_fn': sass.sass_dependencies, + 'compiler_fn': sass.sass_compile, + 'input': input_file, + 'output': output_file, + 'kwargs': {}, + } + + +def browserify_node_modules(module_name_list, output_file, babelify=False): + """ + Browserify a list of libraries from node_modules into a single + javascript file. Generates source maps in debug mode. Minifies the + output in release mode. + + Note you may also specify the relative path to the module + as ``./path/to/module`` or ``./path/to/module/file.js``. + """ + from .modules import browserify + + if not isinstance(module_name_list, (list, tuple)): + raise RuntimeError('Browserify Node Modules compiler takes a list of node module names as input.') + + return { + 'dependencies_fn': browserify.browserify_deps_node_modules, + 'compiler_fn': browserify.browserify_compile_node_modules, + 'input': module_name_list, + 'output': output_file, + 'kwargs': { + 'babelify': babelify, + }, + } + + +def browserify_libs(lib_dirs, output_file, babelify=False): + """ + Browserify one or more library directories into a single + javascript file. Generates source maps in debug mode. Minifies the + output in release mode. + + The final directory name in each of lib_dirs is the library name + for importing. Eg.:: + + lib_dirs = ['cordova_libs/jskit'] + + var MyClass = require('jskit/MyClass'); + """ + from .modules import browserify + + if not isinstance(lib_dirs, (list, tuple)): + raise RuntimeError('Browserify Libs compiler takes a list of library directories as input.') + + return { + 'dependencies_fn': browserify.browserify_deps_libs, + 'compiler_fn': browserify.browserify_compile_libs, + 'input': lib_dirs, + 'output': output_file, + 'kwargs': { + 'babelify': babelify, + }, + } + + +def browserify_file(entry_point, output_file, babelify=False, export_as=None): + """ + Browserify a single javascript entry point plus non-external + dependencies into a single javascript file. Generates source maps + in debug mode. Minifies the output in release mode. + + By default, it is not possible to ``require()`` any exports from the entry + point or included files. If ``export_as`` is specified, any module exports + in the specified entry point are exposed for ``require()`` with the + name specified by ``export_as``. + """ + from .modules import browserify + + if not isinstance(entry_point, str): + raise RuntimeError('Browserify File compiler takes a single entry point as input.') + + return { + 'dependencies_fn': browserify.browserify_deps_file, + 'compiler_fn': browserify.browserify_compile_file, + 'input': entry_point, + 'output': output_file, + 'kwargs': { + 'babelify': babelify, + 'export_as': export_as, + }, + } + + +def custom_function(func, input_files, output_file): + """ + Calls a custom function which must create the output file. + + The custom function takes 3 parameters: ``input_files``, + ``output_file`` and a boolean ``release``. + """ + from .modules import utils + + return { + 'dependencies_fn': utils.no_dependencies, + 'compiler_fn': func, + 'input': input_files, + 'output': output_file, + 'kwargs': {}, + } diff --git a/build/lib/webmake/compiler.py b/build/lib/webmake/compiler.py new file mode 100644 index 0000000..4ddd84e --- /dev/null +++ b/build/lib/webmake/compiler.py @@ -0,0 +1,111 @@ +import os +import json +from .modules.utils import log, logv, StaticCompilerError + + +def load_dependencies_for_target(target, makefilepath): + logv('\nFinding dependencies for: {}'.format(target['output'])) + try: + dependency_fn = target['dependencies_fn'] + target['dependencies'] = [makefilepath] + dependency_fn(target['input'], **target['kwargs']) + except (IOError, OSError) as e: + msg = '\nERROR: Failed loading dependencies for "{}":\n\nReceived error:\n{}'.format(target['output'], str(e)) + log(msg) + return False + except StaticCompilerError as e: + log(str(e)) + return False + + return True + + +def save_dependencies_to_cache(targets, makefilepath): + cachefile = makefilepath + '.depscache' + logv('\nWriting dependencies cache: {}'.format(cachefile)) + + cache = [{'output': t['output'], 'dependencies': t['dependencies']} + for t in targets if 'dependencies' in t] + + with open(cachefile, 'w') as f: + json.dump(cache, f, indent=4) + + +def load_dependencies_from_cache(targets, makefilepath): + cachefile = makefilepath + '.depscache' + try: + with open(cachefile, 'r') as f: + cache = json.load(f) + except IOError: + return + + for i, entry in enumerate(cache): + output = entry['output'] + deps = entry['dependencies'] + + if i >= len(targets): + break + + if targets[i]['output'] == output: + targets[i]['dependencies'] = deps + + +def dependencies_are_up_to_date(target): + output = target['output'] + deps = target.get('dependencies') + last_compiled_timestamp = os.path.getmtime(output) if os.path.exists(output) else -1 + + if not deps: + return False + + for file in deps: + try: + if os.path.getmtime(file) >= last_compiled_timestamp: + return False + except Exception: + return False + + return True + + +def compile_if_modified(targets, makefilepath, release): + modified = False + first_up_to_date = True + + for target in targets: + if dependencies_are_up_to_date(target): + if first_up_to_date: + logv('') + first_up_to_date = False + logv('Up-to-date: {}', target['output']) + else: + modified = True + first_up_to_date = True + if not compile_target(target, makefilepath, release=release): + return False + + if modified: + save_dependencies_to_cache(targets, makefilepath) + + return True + + +def compile_all(targets, makefilepath, release): + for target in targets: + if not compile_target(target, makefilepath, release=release): + return False + + save_dependencies_to_cache(targets, makefilepath) + return True + + +def compile_target(target, makefilepath, release): + try: + logv('\nCompiling: {}'.format(target['output'])) + compiler_fn = target['compiler_fn'] + compiler_fn(target['input'], target['output'], release=release, **target['kwargs']) + load_dependencies_for_target(target, makefilepath) + return True + except StaticCompilerError as e: + log(str(e)) + return False + diff --git a/build/lib/webmake/cordova/hooks/before_prepare/runwebmake.py b/build/lib/webmake/cordova/hooks/before_prepare/runwebmake.py new file mode 100644 index 0000000..2c8cff2 --- /dev/null +++ b/build/lib/webmake/cordova/hooks/before_prepare/runwebmake.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +import os + +cmdline = 'webmk -v' +if '--release' in os.environ['CORDOVA_CMDLINE']: + cmdline += ' --force --release' + +print(cmdline) +os.system(cmdline) diff --git a/build/lib/webmake/django/__init__.py b/build/lib/webmake/django/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/build/lib/webmake/django/middleware.py b/build/lib/webmake/django/middleware.py new file mode 100644 index 0000000..84056d3 --- /dev/null +++ b/build/lib/webmake/django/middleware.py @@ -0,0 +1,72 @@ +""" +Middleware class to watch dependencies and automatically +compile static files during development. + +Usage +----- + +1. Add the following to your local/development settings:: + + # Webmake Middleware + MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + ( + 'webmake.django.middleware.WebmakeCompilerMiddleware', + ) + +2. Create a ``webmakefile.py`` in your project root, and add the +files to compile. + +3. Call ``webmk -fr`` from your deployment process to create +release versions of all target files:: + + def pre_process(self, deployment_settings, *args, **kwargs): + with lcd(PROJECT_PATH): + local('webmk -fr') +""" +import re +import os +import sys +import subprocess +import warnings +from django.conf import settings # pylint: disable=import-error + + +SETTINGS_ROOT = os.path.dirname(os.path.abspath(os.path.join(sys.modules[settings.SETTINGS_MODULE].__file__))) +PROJECT_ROOT = os.path.abspath(os.path.join(re.sub(r'settings[/\\]?$', '', SETTINGS_ROOT), os.pardir)) +WEBMAKE_BIN = 'webmk' +WEBMAKEFILE = os.path.join(PROJECT_ROOT, 'webmakefile.py') + +POSSIBLE_BINFILES = [f for f in ( + os.path.join(os.path.dirname(sys.executable), WEBMAKE_BIN), + os.path.join(os.path.dirname(sys.executable), WEBMAKE_BIN + '.exe'), + ) if os.path.isfile(f)] + +BINFILE = POSSIBLE_BINFILES[0] if POSSIBLE_BINFILES else WEBMAKE_BIN + + +class WebmakeRuntimeWarning(RuntimeWarning): + pass + + +class WebmakeCompilerMiddleware: + def __init__(self, get_response=None): + self.get_response = get_response + + def __call__(self, request): + self.process_request(request) + return self.get_response(request) + + def process_request(self, request): + if not settings.DEBUG: + warnings.warn('WebmakeCompilerMiddleware should not be used in production!', WebmakeRuntimeWarning) + + cmd = ' '.join([BINFILE, '-m', WEBMAKEFILE]) + env = os.environ.copy() + env.pop('PYTHONPATH', None) + + try: + subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True, env=env) + except subprocess.CalledProcessError as e: + output = e.output.decode('utf-8') if hasattr(e.output, 'decode') else str(e.output) + raise RuntimeError('WebmakeCompilerMiddleware:\n' + output) + + return None diff --git a/build/lib/webmake/main.py b/build/lib/webmake/main.py new file mode 100644 index 0000000..4affb99 --- /dev/null +++ b/build/lib/webmake/main.py @@ -0,0 +1,86 @@ +import os +import sys +import argparse +import importlib +import functools +import traceback +from .modules import utils +from . import settings, compiler, watcher + + +def command_line_error(parser, makefile, message): + tb = sys.exc_info()[2] + lineinfo = '' + if tb: + try: + tb = [s for s in reversed(traceback.extract_tb(tb)) if s[0].endswith('webmakefile.py')][0] + lineinfo = 'webmakefile.py:{}: '.format(tb[1]) + except IndexError: + pass + + msg = '\nProcessing: {}\n\n{}{}'.format(makefile, lineinfo, message) + parser.error(msg) + + +def parse_command_line(): + default_webmakefile = os.path.join(os.getcwd(), 'webmakefile.py') + + parser = argparse.ArgumentParser(description='A simple pythonic build system for Web and Cordova projects (JS,Less,Sass...)') + parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output.') + parser.add_argument('-r', '--release', action='store_true', help='Release mode. Minify output and don\'t generate source maps.') + parser.add_argument('-f', '--force', action='store_true', help='Force recompilation of all source files, even if not modified.') + parser.add_argument('-m', '--makefile', default=default_webmakefile, help='Specify the webmakefile.py to use for compilation settings.') + parser.add_argument('-w', '--watch', action='store_true', help='Watch all input files for changes, and recompile automatically.') + + args = parser.parse_args() + error_fn = functools.partial(command_line_error, parser, args.makefile) + + if not args.makefile or not os.path.isfile(args.makefile): + error_fn('webmakefile.py does not exist, please create one in ' + 'your project root and run from there.') + + return (args, error_fn) + + +def main(): + args, error_fn = parse_command_line() + settings.VERBOSE = args.verbose + settings.RELEASE = args.release + settings.FORCE = args.force + settings.MAKEFILEPATH = args.makefile + + webmakefile_dir = os.path.abspath(os.path.expanduser(os.path.dirname(args.makefile))) + webmakefile_name = os.path.basename(args.makefile) + webmakefile_module = os.path.splitext(webmakefile_name)[0] + + os.chdir(webmakefile_dir) + sys.path.insert(0, webmakefile_dir) + + try: + makefile = importlib.import_module(webmakefile_module) + except RuntimeError as e: + error_fn(str(e)) + except Exception as e: # pylint: disable=broad-except + error_fn('Unable to parse webmakefile.py.\n\n{}'.format(str(e))) + + try: + settings.MAKEFILE = makefile.MAKEFILE + except AttributeError: + error_fn('MAKEFILE variable missing in webmakefile.py.') + + utils.logv('WEBMAKEFILE = {}', os.path.join(webmakefile_dir, webmakefile_name)) + utils.logv('RELEASE MODE = {}', ('On' if settings.RELEASE else 'Off')) + utils.logv('FORCE COMPILATION = {}', ('On' if settings.FORCE else 'Off')) + + # Load any cached dependencies + compiler.load_dependencies_from_cache(settings.MAKEFILE, settings.MAKEFILEPATH) + + if settings.FORCE: + if not compiler.compile_all(settings.MAKEFILE, settings.MAKEFILEPATH, settings.RELEASE): + sys.exit(1) + else: + if not compiler.compile_if_modified(settings.MAKEFILE, settings.MAKEFILEPATH, release=settings.RELEASE): + sys.exit(1) + + if args.watch: + watcher.start_watching() diff --git a/build/lib/webmake/modules/__init__.py b/build/lib/webmake/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/build/lib/webmake/modules/bless.py b/build/lib/webmake/modules/bless.py new file mode 100644 index 0000000..dc51d77 --- /dev/null +++ b/build/lib/webmake/modules/bless.py @@ -0,0 +1,18 @@ +from . import utils + + +def bless_css(input_file, output_file, release=False): + assert isinstance(input_file, str) + + cmdline = [ + utils.get_node_bin_dir('blessc'), + '--no-imports', + ] + cmdline.append(input_file) + cmdline.append(output_file) + + try: + utils.run_command(cmdline, 'Failed to split CSS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + raise diff --git a/build/lib/webmake/modules/browserify.py b/build/lib/webmake/modules/browserify.py new file mode 100644 index 0000000..25950aa --- /dev/null +++ b/build/lib/webmake/modules/browserify.py @@ -0,0 +1,161 @@ +import os +from . import utils, minify + + +def get_extensions_and_params(babelify=False): + extensions = ['.js'] + params = [] + + if babelify: + babelify = utils.get_node_modules_dir('babelify') + preset_es2015 = utils.get_node_modules_dir('babel-preset-es2015') + preset_react = utils.get_node_modules_dir('babel-preset-react') + extensions.extend(['.jsx']) + params.extend(['-t', '[', babelify, '--presets', '[', preset_es2015, preset_react, ']', ']']) + + return (extensions, params) + + +def browserify_basic_error(func_name, output_file, list_deps): + if list_deps: + return 'Failed to list dependencies in {}()'.format(func_name) + else: + return 'Error compiling with {}() to "{}"'.format(func_name, output_file) + + +def browserify_basic_command(output_file, release, list_deps): + sourcemap = '-d' if not release else '' + + cmdline = [ + utils.get_node_bin_dir('browserify'), + ] + + if list_deps: + cmdline.extend([ + '--list', + '--fast', + ]) + else: + cmdline.extend([ + sourcemap, + '-o', + output_file, + ]) + + return cmdline + + +def browserify_run(cmdline, errmsg, output_file, release, list_deps): + env = {'NODE_ENV': 'production'} if release else None + + try: + if output_file: + utils.ensure_path_exists(os.path.dirname(output_file)) + + output = utils.run_command(cmdline, errmsg, env=env) + if list_deps: + return [os.path.abspath(p) if os.path.exists(p) else p for p in output.splitlines()] + elif release: + minify.minify_js([output_file], output_file, release=release) + except: + if output_file: + utils.ensure_deleted(output_file) + raise + + +def browserify_node_modules(module_list, output_file=None, release=False, list_deps=False, babelify=False): + (_, params) = get_extensions_and_params(babelify=babelify) + errmsg = browserify_basic_error('browserify_node_modules', output_file, list_deps) + + # No source maps for vendor libs, load time is too slow + cmdline = browserify_basic_command(output_file, release=True, list_deps=list_deps) + cmdline.extend(params) + + for m in module_list: + if m.startswith('./'): + cmdline.extend(['-r', m + ':' + os.path.basename(m).rsplit('.', maxsplit=1)[0]]) + else: + cmdline.extend(['-r', m]) + + result = browserify_run(cmdline, errmsg, output_file, release, list_deps) + + if list_deps: + def fix_node_modules_path(path): + newpath = os.path.abspath(os.path.join('node_modules', path)) + return newpath if not os.path.exists(path) and os.path.exists(newpath) else path + result = [fix_node_modules_path(p) for p in result] + + return result + + +def browserify_libs(lib_dirs, output_file=None, release=False, list_deps=False, babelify=False): + (exts, params) = get_extensions_and_params(babelify=babelify) + errmsg = browserify_basic_error('browserify_libs', output_file, list_deps) + + cmdline = browserify_basic_command(output_file, release, list_deps) + cmdline.append('--no-bundle-external') + cmdline.extend(params) + + for dir in lib_dirs: + files = utils.list_matching_files(dir, extensions=exts, recursive=True, linux_style_paths=True) + dir = dir.replace('\\', '/') + libname = os.path.basename(dir.rstrip('/\\')) + + for f in files: + assert f.startswith(dir) + newname = libname + os.path.splitext(f[len(dir):])[0] + if not os.path.isabs(f): + f = './' + f + cmdline.extend(['-r', '{}:{}'.format(f, newname)]) + + return browserify_run(cmdline, errmsg, output_file, release, list_deps) + + +def browserify_file(entry_point, output_file=None, release=False, list_deps=False, babelify=False, export_as=None): + (_, params) = get_extensions_and_params(babelify=babelify) + errmsg = browserify_basic_error('browserify_file', output_file, list_deps) + + cmdline = browserify_basic_command(output_file, release, list_deps) + cmdline.append('--no-bundle-external') + cmdline.extend(params) + + if not export_as: + cmdline.extend([ + '-e', + entry_point, + ]) + else: + f = entry_point.replace('\\', '/') + if not os.path.isabs(f): + f = './' + f + + cmdline.extend([ + '-r', + '{}:{}'.format(f, export_as) + ]) + + return browserify_run(cmdline, errmsg, output_file, release, list_deps) + + +def browserify_deps_node_modules(module_list, babelify=False): + return browserify_node_modules(module_list, list_deps=True, babelify=babelify) + + +def browserify_compile_node_modules(module_list, output_file, release=False, babelify=False): + browserify_node_modules(module_list, output_file, release=release, babelify=babelify) + + +def browserify_deps_libs(lib_dirs, babelify=False): + return browserify_libs(lib_dirs, list_deps=True, babelify=babelify) + + +def browserify_compile_libs(lib_dirs, output_file, release=False, babelify=False): + browserify_libs(lib_dirs, output_file, release=release, babelify=babelify) + + +def browserify_deps_file(entry_point, babelify=False, export_as=None): + return browserify_file(entry_point, list_deps=True, babelify=babelify, export_as=export_as) + + +def browserify_compile_file(entry_point, output_file, release=False, babelify=False, export_as=None): + browserify_file(entry_point, output_file, release=release, babelify=babelify, export_as=export_as) diff --git a/build/lib/webmake/modules/concat.py b/build/lib/webmake/modules/concat.py new file mode 100644 index 0000000..ed91217 --- /dev/null +++ b/build/lib/webmake/modules/concat.py @@ -0,0 +1,46 @@ +import os +import six +from . import utils + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + + +def _trimpath(path): + comps = [] + for _ in range(3): + path, c = os.path.split(path) + comps.append(c) + return os.path.join(*reversed(comps)).replace('\\', '/') + + +def concatenate_input_files(input_files, output_file, release=False): + assert isinstance(input_files, (list, tuple)) + + if len(input_files) == 1 and input_files[0] == output_file: + return + + for f in input_files: + assert f != output_file, 'Concatenate input file is same as output.' + + if output_file: + utils.ensure_path_exists(os.path.dirname(output_file)) + + try: + utils.logv('>>> concat {} > {}'.format(' '.join(input_files), output_file)) + with open(output_file, 'w', **FILE_HANDLE_KWARGS) as output: + for input_file in input_files: + with open(input_file, 'r', **FILE_HANDLE_KWARGS) as input: + output.write(input.read()) + + if not release: + path = _trimpath(input_file) + output.write('\n\n' + '/*\n' + ' * {caret}\n' + ' * {path} \n' + ' * {caret}\n' + ' */\n\n\n'.format(path=path, caret='^' * len(path))) + + except IOError as e: + utils.ensure_deleted(output_file) + raise utils.StaticCompilerError('Failed to concatenate to {}'.format(output_file), error=str(e)) diff --git a/build/lib/webmake/modules/copyfiles.py b/build/lib/webmake/modules/copyfiles.py new file mode 100644 index 0000000..e7a53b1 --- /dev/null +++ b/build/lib/webmake/modules/copyfiles.py @@ -0,0 +1,42 @@ +import os +import shutil +from fnmatch import fnmatch +from . import utils + + +def list_files(src_dir, filespec, recursive=False, include_dirs=True): + inputs = [] + + for dir, _, files in os.walk(src_dir): + if include_dirs: + inputs.append(dir) + + inputs.extend(os.path.join(dir, f) for f in files if match_file(f)) + + if not recursive: + break + + return inputs + + +def copy_files(src_dir, dst_dir, filespec, recursive=False, release=None): + assert src_dir != dst_dir, 'Source and destination directories are the same.' + assert os.path.isdir(src_dir), 'Source directory "{}" does not exist.'.format(src_dir) + + if not os.path.isdir(dst_dir): + try: + os.mkdir(dst_dir) + except OSError as e: + raise utils.StaticCompilerError('Failed to create destination dir "{}"'.format(dst_dir), error=str(e)) + + input_files = list_files(src_dir, filespec, recursive, include_dirs=False) + output_files = [os.path.join(dst_dir, os.path.relpath(p, src_dir)) for p in input_files] + + for input, output in zip(input_files, output_files): + utils.logv('>>> copy {} > {}'.format(input, output)) + dirname = os.path.split(output)[0] + if not os.path.exists(dirname): + os.mkdir(dirname) + shutil.copy2(input, output) + + os.utime(dst_dir, None) diff --git a/build/lib/webmake/modules/less.py b/build/lib/webmake/modules/less.py new file mode 100644 index 0000000..b6fc638 --- /dev/null +++ b/build/lib/webmake/modules/less.py @@ -0,0 +1,60 @@ +import os +import re +import six +from . import utils + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') +LESS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.less)?)['"]\s*;""") + + +def _read_less_imports(file): + deps = [] + with open(file, **FILE_HANDLE_KWARGS) as f: + less = f.read() + imports = LESS_IMPORT_RE.findall(less) + less_dir = os.path.dirname(file) + + for imp in imports: + dep = utils.resolve_possible_paths(imp, less_dir, ['.less']) + if dep: + deps.append(dep) + else: + raise ValueError('Invalid LESS import in {}: {}'.format(file, imp)) + + return deps + + +def less_dependencies(input_file): + return utils.breadth_first_search(_read_less_imports, input_file) + + +def less_compile(input_file, output_file, release=False): + map_file = output_file + '.map' + input_abs = os.path.abspath(os.path.dirname(input_file)) + output_abs = os.path.abspath(os.path.dirname(output_file)) + map_url = os.path.basename(map_file) + map_base = os.path.commonprefix([input_abs, output_abs]).replace('\\', '/') + map_rel = os.path.dirname(output_abs[len(map_base):]).replace('\\', '/') + map_root = '/'.join([os.pardir] * len(map_rel.split('/'))) + + minify = '-x' if release else '' + sourcemap = ('-source-map-rootpath={rp} --source-map-basepath={bp} --source-map-url={url} --source-map={map}' + .format(rp=map_root, bp=map_base, url=map_url, map=map_file) + if not release else '') + + cmdline = [ + utils.get_node_bin_dir('lessc'), + '--no-color', + minify, + sourcemap, + input_file, + output_file, + ] + + try: + utils.ensure_deleted(map_file) + utils.run_command(cmdline, 'Failed to compile LESS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + utils.ensure_deleted(map_file) + raise diff --git a/build/lib/webmake/modules/minify.py b/build/lib/webmake/modules/minify.py new file mode 100644 index 0000000..82a3ade --- /dev/null +++ b/build/lib/webmake/modules/minify.py @@ -0,0 +1,80 @@ +import os +import six +from . import utils, concat + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + + +def minify_js(input_files, output_file, release=False, annotate_angular=False): + assert isinstance(input_files, (list, tuple)) + + concat.concatenate_input_files(input_files, output_file, release=release) + + if not release: + return + + if annotate_angular: + try: + annotate_angular_injections(output_file, output_file) + except: + # utils.ensure_deleted(output_file) + raise + + if output_file: + utils.ensure_path_exists(os.path.dirname(output_file)) + + cmdline = [ + utils.get_node_bin_dir('uglifyjs'), + '--compress', + '--mangle', + '-o', + output_file, + '--', + ] + cmdline.extend([output_file]) + + try: + utils.run_command(cmdline, 'Failed to minify JS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + raise + +def annotate_angular_injections(input_file, output_file): + cmdline = [ + utils.get_node_bin_dir('ng-annotate'), + '--add', + '-o', + output_file, + ] + cmdline.extend([input_file]) + + try: + utils.run_command(cmdline, 'Failed to annotate Annnngular injections to "{}"'.format(output_file)) + except Exception as e: + # utils.ensure_deleted(output_file) + raise + +def minify_css(input_files, output_file, release=False): + assert isinstance(input_files, (list, tuple)) + + concat.concatenate_input_files(input_files, output_file, release=release) + if not release: + return + + cmdline = [ + utils.get_node_bin_dir('cssmin'), + ] + cmdline.append(output_file) + + try: + output = utils.run_command(cmdline, 'Failed to minify CSS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + raise + + try: + with open(output_file, 'w', **FILE_HANDLE_KWARGS) as f: + f.write(output) + except IOError as e: + utils.ensure_deleted(output_file) + raise utils.StaticCompilerError('Failed to minify CSS to "{}"'.format(output_file), str(e)) diff --git a/build/lib/webmake/modules/sass.py b/build/lib/webmake/modules/sass.py new file mode 100644 index 0000000..1f9bfb6 --- /dev/null +++ b/build/lib/webmake/modules/sass.py @@ -0,0 +1,52 @@ +import os +import re +import six +from . import utils + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') +SASS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.s[ca]ss)?)['"]\s*;""") + + +def _read_sass_imports(file): + deps = [] + with open(file, **FILE_HANDLE_KWARGS) as f: + sassfile = f.read() + imports = SASS_IMPORT_RE.findall(sassfile) + sass_dir = os.path.dirname(file) + + for imp in imports: + dep = utils.resolve_possible_paths(imp, sass_dir, ['.scss', '.sass'], leading_underscore=True) + if dep: + deps.append(dep) + else: + raise ValueError('Invalid SASS import in {}: {}'.format(file, imp)) + + return deps + + +def sass_dependencies(input_file): + return utils.breadth_first_search(_read_sass_imports, input_file) + + +def sass_compile(input_file, output_file, release=False): + map_file = output_file + '.map' + output_style = 'compressed' if release else 'expanded' + source_map = '--source-comments --source-map-embed --source-map-contents --source-map {}'.format(map_file) if not release else '' + + cmdline = [ + utils.get_node_bin_dir('node-sass'), + '--output-style', + output_style, + source_map, + input_file, + output_file, + ] + + try: + utils.ensure_deleted(map_file) + utils.run_command(cmdline, 'Failed to compile SASS to "{}"'.format(output_file)) + except: + utils.ensure_deleted(output_file) + raise + finally: + utils.ensure_deleted(map_file) diff --git a/build/lib/webmake/modules/utils.py b/build/lib/webmake/modules/utils.py new file mode 100644 index 0000000..24b2f22 --- /dev/null +++ b/build/lib/webmake/modules/utils.py @@ -0,0 +1,195 @@ +import re +import os +import six +import subprocess +from subprocess import CalledProcessError +from .. import settings + +FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + + +def log(msg, *args, **kwargs): + """ + Print out a log message. + """ + if len(args) == 0 and len(kwargs) == 0: + print(msg) + else: + print(msg.format(*args, **kwargs)) + + +def logv(msg, *args, **kwargs): + """ + Print out a log message, only if verbose mode. + """ + if settings.VERBOSE: + log(msg, *args, **kwargs) + + +class StaticCompilerError(Exception): + def __init__(self, message, error=None, output=None, source=None): + super(StaticCompilerError, self).__init__() + self.message = message + self.error = error or '' + self.output = output or '' + self.source = source or '' + + def __str__(self): + err = [ + '\nERROR: ', + self.message, + '\n\nReceived error:\n', + self.error, + ] + + if self.output: + err.extend(['\n\nOutput:\n', self.output]) + + if self.source: + err.extend(['\n\nSource:\n', self.source]) + + return ''.join(err) + + +def breadth_first_search(get_deps_fn, root_file): + root_file = os.path.abspath(root_file) + queue = [root_file] + deps = [root_file] + + while len(queue) > 0: + cur_file = queue.pop(0) + new_deps = get_deps_fn(cur_file) + queue.extend(new_deps) + deps.extend(new_deps) + + return deps + + +def list_matching_files(path, extensions=None, recursive=True, linux_style_paths=False): + if isinstance(extensions, list): + extensions = tuple(extensions) + + result = [] + + if recursive: + it = os.walk(path) + else: + it = [(path, (), (f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))))] + + for (dir, _, files) in it: + if extensions: + files = [f for f in files if f.endswith(extensions)] + + for f in files: + f = os.path.join(dir, f) + if linux_style_paths: + f = f.replace('\\', '/') + result.append(f) + + return result + + +def ensure_path_exists(path): + path = os.path.abspath(path) + if not os.path.exists(path): + os.makedirs(path) + + +def ensure_deleted(*args): + for file in args: + try: + os.unlink(file) + except Exception: # pylint: disable=broad-except + pass + + +def rename(old, new): + ensure_deleted(new) + os.rename(old, new) + + +def resolve_possible_paths(path, relative_prefix, possible_extensions=None, leading_underscore=False): + """ + Attempts to resolve the given absolute or relative ``path``. If it + doesn't exist as is, tries to create an absolute path using the + ``relative_prefix``. If that fails, tries relative/absolute versions + with each of ``possible_extensions``. + + :returns: The absolute path, or ``None`` if no such file can be found. + """ + possible_extensions = [''] + list(possible_extensions) if possible_extensions else [''] + possible_paths = [path + e if os.path.isabs(path + e) else os.path.join(relative_prefix, path + e) + for e in possible_extensions] + + if leading_underscore and not os.path.basename(path).startswith('_'): + extra_paths = [os.path.join(os.path.dirname(p), '_' + os.path.basename(p)) + for p in possible_paths] + possible_paths = possible_paths + extra_paths + + for p in possible_paths: + p = os.path.normpath(p) + if os.path.isfile(p): + return p + + return None + + +def get_node_modules_dir(module=None): + moduledir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'node_modules')) + if module: + return os.path.join(moduledir, module) + else: + return moduledir + + +def get_node_bin_dir(cmd=None): + bindir = get_node_modules_dir('.bin') + if cmd: + return os.path.join(bindir, cmd) + else: + return bindir + + +def no_dependencies(input): + if not isinstance(input, (list, tuple)): + return [input] + else: + return input + + +def run_command(cmd, errmsg, env=None): + if env is not None: + newenv = os.environ.copy() + newenv.update(env) + env = newenv + + if isinstance(cmd, (list, tuple)): + cmd = ' '.join(c for c in cmd if c != '') + + try: + logv('>>> ' + cmd) + return subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT, shell=True).decode('ascii', 'replace') + except CalledProcessError as e: + raise StaticCompilerError(errmsg, str(e), e.output.decode('ascii', 'replace')) + + +def extract_line_num(output, regexp): + m = re.search(regexp, output) + if m: + try: + return int(m.group(1)) + except ValueError: + pass + return None + + +def extract_lines_from_source(source, line_num): + start = max(0, line_num - 5) + with open(source, 'r', **FILE_HANDLE_KWARGS) as f: + lines = f.readlines()[start:start + 10] + + ret = ['{}: {}'.format(i + start + 1, l) for (i, l) in enumerate(lines)] + ret[3] = ret[3].rstrip() + ' <<<<<<\n' + return ''.join(ret) + + diff --git a/build/lib/webmake/package.json b/build/lib/webmake/package.json new file mode 100644 index 0000000..9adf0a5 --- /dev/null +++ b/build/lib/webmake/package.json @@ -0,0 +1,17 @@ +{ + "private": true, + "dependencies": { + "babel-cli": "^6.26.0", + "babel-core": "^6.26.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-react": "^6.24.1", + "babelify": "^8.0.0", + "bless": "^3.0.3", + "browserify": "^9.0.8", + "cssmin": "^0.4.3", + "less": "^2.7.3", + "ng-annotate": "1.x", + "node-sass": "^4.11.0", + "uglify-es": "^3.3.9" + } +} diff --git a/build/lib/webmake/settings.py b/build/lib/webmake/settings.py new file mode 100644 index 0000000..8c0f903 --- /dev/null +++ b/build/lib/webmake/settings.py @@ -0,0 +1,13 @@ + +# Whether to show verbose log messages +VERBOSE = False + +# Whether to minify/exclude source maps for production +RELEASE = False + +# Whether to force compilation of all files, rather than compiling modified +FORCE = False + +# The makefile contents & path, and dependencies map +MAKEFILE = None +MAKEFILEPATH = None diff --git a/build/lib/webmake/watcher.py b/build/lib/webmake/watcher.py new file mode 100644 index 0000000..232d8d8 --- /dev/null +++ b/build/lib/webmake/watcher.py @@ -0,0 +1,54 @@ +import os +import time +import itertools +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +from .modules.utils import log +from . import settings, compiler + + +FORCE_EXIT = False + + +class WatchdogEventHandler(FileSystemEventHandler): + def on_any_event(self, event): + if event.is_directory or event.src_path.endswith('.depscache'): + return + + if os.path.abspath(event.src_path) == os.path.abspath(settings.MAKEFILEPATH): + log('Detected change to makefile {}, please restart the watcher.\n'.format(settings.MAKEFILEPATH)) + global FORCE_EXIT # pylint: disable=global-statement + FORCE_EXIT = True + return + + what = 'directory' if event.is_directory else 'file' + log('{} {} {}'.format(event.event_type.title(), what, event.src_path)) + + compiler.compile_if_modified(settings.MAKEFILE, settings.MAKEFILEPATH, settings.RELEASE) + log('') + + +def start_watching(): + log('\nWatching for filesystem changes, Ctrl-C to exit...\n') + settings.VERBOSE = True + + paths = itertools.chain.from_iterable(d['dependencies'] for d in settings.MAKEFILE) + paths = set(os.path.abspath(os.path.dirname(p)) for p in paths) + +# import pprint +# pprint.pprint(paths, indent=4) + + observer = Observer() + for path in paths: + observer.schedule(WatchdogEventHandler(), path, recursive=False) + observer.start() + + try: + while not FORCE_EXIT: + time.sleep(1) + raise KeyboardInterrupt() + except KeyboardInterrupt: + log('Shutting down...') + observer.stop() + + observer.join() From b0cd198a3b6645e1544efa967a6a0caeb5ed1163 Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Thu, 12 Nov 2020 14:19:34 -0500 Subject: [PATCH 07/13] Restoring these modules to reflect current master / removing my alterations. --- webmake/modules/bless.py | 2 +- webmake/modules/browserify.py | 2 +- webmake/modules/copyfiles.py | 6 +++++- webmake/modules/less.py | 7 +++---- webmake/modules/minify.py | 9 +++------ webmake/modules/sass.py | 7 +++---- webmake/modules/utils.py | 18 +++++++----------- 7 files changed, 23 insertions(+), 28 deletions(-) diff --git a/webmake/modules/bless.py b/webmake/modules/bless.py index dc51d77..d3dd91c 100644 --- a/webmake/modules/bless.py +++ b/webmake/modules/bless.py @@ -5,7 +5,7 @@ def bless_css(input_file, output_file, release=False): assert isinstance(input_file, str) cmdline = [ - utils.get_node_bin_dir('blessc'), + utils.get_node_bin_path('bless', 'bin', 'blessc'), '--no-imports', ] cmdline.append(input_file) diff --git a/webmake/modules/browserify.py b/webmake/modules/browserify.py index 25950aa..ec2a96d 100644 --- a/webmake/modules/browserify.py +++ b/webmake/modules/browserify.py @@ -27,7 +27,7 @@ def browserify_basic_command(output_file, release, list_deps): sourcemap = '-d' if not release else '' cmdline = [ - utils.get_node_bin_dir('browserify'), + utils.get_node_bin_path('browserify', 'bin', 'cmd.js'), ] if list_deps: diff --git a/webmake/modules/copyfiles.py b/webmake/modules/copyfiles.py index e7a53b1..5b33112 100644 --- a/webmake/modules/copyfiles.py +++ b/webmake/modules/copyfiles.py @@ -6,6 +6,10 @@ def list_files(src_dir, filespec, recursive=False, include_dirs=True): inputs = [] + filespecs = [filespec] if not isinstance(filespec, (list, tuple)) else filespec + + def match_file(f): + return any(fnmatch(f, s) for s in filespecs) for dir, _, files in os.walk(src_dir): if include_dirs: @@ -36,7 +40,7 @@ def copy_files(src_dir, dst_dir, filespec, recursive=False, release=None): utils.logv('>>> copy {} > {}'.format(input, output)) dirname = os.path.split(output)[0] if not os.path.exists(dirname): - os.mkdir(dirname) + os.makedirs(dirname) shutil.copy2(input, output) os.utime(dst_dir, None) diff --git a/webmake/modules/less.py b/webmake/modules/less.py index b6fc638..ce52688 100644 --- a/webmake/modules/less.py +++ b/webmake/modules/less.py @@ -1,15 +1,14 @@ import os import re -import six from . import utils -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + LESS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.less)?)['"]\s*;""") def _read_less_imports(file): deps = [] - with open(file, **FILE_HANDLE_KWARGS) as f: + with open(file) as f: less = f.read() imports = LESS_IMPORT_RE.findall(less) less_dir = os.path.dirname(file) @@ -43,7 +42,7 @@ def less_compile(input_file, output_file, release=False): if not release else '') cmdline = [ - utils.get_node_bin_dir('lessc'), + utils.get_node_bin_path('less', 'bin', 'lessc'), '--no-color', minify, sourcemap, diff --git a/webmake/modules/minify.py b/webmake/modules/minify.py index 82a3ade..4548620 100644 --- a/webmake/modules/minify.py +++ b/webmake/modules/minify.py @@ -1,9 +1,6 @@ import os -import six from . import utils, concat -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') - def minify_js(input_files, output_file, release=False, annotate_angular=False): assert isinstance(input_files, (list, tuple)) @@ -24,7 +21,7 @@ def minify_js(input_files, output_file, release=False, annotate_angular=False): utils.ensure_path_exists(os.path.dirname(output_file)) cmdline = [ - utils.get_node_bin_dir('uglifyjs'), + utils.get_node_bin_path('uglify-es', 'bin', 'uglifyjs'), '--compress', '--mangle', '-o', @@ -62,7 +59,7 @@ def minify_css(input_files, output_file, release=False): return cmdline = [ - utils.get_node_bin_dir('cssmin'), + utils.get_node_bin_path('cssmin', 'bin', 'cssmin'), ] cmdline.append(output_file) @@ -73,7 +70,7 @@ def minify_css(input_files, output_file, release=False): raise try: - with open(output_file, 'w', **FILE_HANDLE_KWARGS) as f: + with open(output_file, 'w') as f: f.write(output) except IOError as e: utils.ensure_deleted(output_file) diff --git a/webmake/modules/sass.py b/webmake/modules/sass.py index 417fe04..1a44db7 100644 --- a/webmake/modules/sass.py +++ b/webmake/modules/sass.py @@ -1,15 +1,14 @@ import os import re -import six from . import utils -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') + SASS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.s[ca]ss)?)['"]\s*;""") def _read_sass_imports(file): deps = [] - with open(file, **FILE_HANDLE_KWARGS) as f: + with open(file) as f: sassfile = f.read() imports = SASS_IMPORT_RE.findall(sassfile) sass_dir = os.path.dirname(file) @@ -35,7 +34,7 @@ def sass_compile(input_file, output_file, release=False): source_map = '--source-comments --source-map-embed --source-map-contents --source-map {}'.format(map_file) if not release else '' cmdline = [ - utils.get_node_bin_dir('node-sass'), + utils.get_node_bin_path('node-sass', 'bin', 'node-sass'), '--output-style', output_style, source_map, diff --git a/webmake/modules/utils.py b/webmake/modules/utils.py index 24b2f22..1ee6c75 100644 --- a/webmake/modules/utils.py +++ b/webmake/modules/utils.py @@ -1,12 +1,9 @@ import re import os -import six import subprocess from subprocess import CalledProcessError from .. import settings -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') - def log(msg, *args, **kwargs): """ @@ -142,12 +139,8 @@ def get_node_modules_dir(module=None): return moduledir -def get_node_bin_dir(cmd=None): - bindir = get_node_modules_dir('.bin') - if cmd: - return os.path.join(bindir, cmd) - else: - return bindir +def get_node_bin_path(*args): + return os.path.join(get_node_modules_dir(), *args) def no_dependencies(input): @@ -157,7 +150,7 @@ def no_dependencies(input): return input -def run_command(cmd, errmsg, env=None): +def run_command(cmd, errmsg, env=None, with_node=True): if env is not None: newenv = os.environ.copy() newenv.update(env) @@ -166,6 +159,9 @@ def run_command(cmd, errmsg, env=None): if isinstance(cmd, (list, tuple)): cmd = ' '.join(c for c in cmd if c != '') + if with_node: + cmd = 'node ' + cmd + try: logv('>>> ' + cmd) return subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT, shell=True).decode('ascii', 'replace') @@ -185,7 +181,7 @@ def extract_line_num(output, regexp): def extract_lines_from_source(source, line_num): start = max(0, line_num - 5) - with open(source, 'r', **FILE_HANDLE_KWARGS) as f: + with open(source, 'r') as f: lines = f.readlines()[start:start + 10] ret = ['{}: {}'.format(i + start + 1, l) for (i, l) in enumerate(lines)] From 9598e8dd0638a2e9ec1e9b9bca1f2302858e772a Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Thu, 12 Nov 2020 14:20:20 -0500 Subject: [PATCH 08/13] Fixing post-merge issues with Angular annotations functionality. --- webmake/modules/minify.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/webmake/modules/minify.py b/webmake/modules/minify.py index 4548620..a2955dc 100644 --- a/webmake/modules/minify.py +++ b/webmake/modules/minify.py @@ -5,16 +5,21 @@ def minify_js(input_files, output_file, release=False, annotate_angular=False): assert isinstance(input_files, (list, tuple)) - concat.concatenate_input_files(input_files, output_file, release=release) - if not release: + concat.concatenate_input_files(input_files, output_file, release=release) return if annotate_angular: + # Rather than annotate several individual files (and having to creating temp files as well), it's + # easier to just concatenate the input_files right now, and then perform the annotation upon that + # one file. We must then update the `input_files` value accordingly, so that it gets passed into + # uglify correctly. + concat.concatenate_input_files(input_files, output_file, release=release) + input_files = [output_file] try: annotate_angular_injections(output_file, output_file) except: - # utils.ensure_deleted(output_file) + utils.ensure_deleted(output_file) raise if output_file: @@ -28,7 +33,7 @@ def minify_js(input_files, output_file, release=False, annotate_angular=False): output_file, '--', ] - cmdline.extend([output_file]) + cmdline.extend(input_files) try: utils.run_command(cmdline, 'Failed to minify JS to "{}"'.format(output_file)) @@ -38,7 +43,7 @@ def minify_js(input_files, output_file, release=False, annotate_angular=False): def annotate_angular_injections(input_file, output_file): cmdline = [ - utils.get_node_bin_dir('ng-annotate'), + os.path.join(utils.get_node_bin_path('ng-annotate'), 'ng-annotate.js'), '--add', '-o', output_file, @@ -46,9 +51,9 @@ def annotate_angular_injections(input_file, output_file): cmdline.extend([input_file]) try: - utils.run_command(cmdline, 'Failed to annotate Annnngular injections to "{}"'.format(output_file)) + utils.run_command(cmdline, 'Failed to annotate Angular injections to "{}"'.format(output_file), with_node=True) except Exception as e: - # utils.ensure_deleted(output_file) + utils.ensure_deleted(output_file) raise def minify_css(input_files, output_file, release=False): From 05cd7cb02ff47d88c5d2ba3fca32fe2d304a2cb4 Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Thu, 12 Nov 2020 14:21:13 -0500 Subject: [PATCH 09/13] Adding an example/test file for the Angular annotations. --- tests/test_project/webmakefile.py | 3 +++ tests/test_project/www-dev/angular-1.x/module.js | 9 +++++++++ 2 files changed, 12 insertions(+) create mode 100644 tests/test_project/www-dev/angular-1.x/module.js diff --git a/tests/test_project/webmakefile.py b/tests/test_project/webmakefile.py index 9eb4b42..cf886b6 100644 --- a/tests/test_project/webmakefile.py +++ b/tests/test_project/webmakefile.py @@ -51,6 +51,9 @@ def custom_compiler(input_files, output_file, release): # Minify standalone JS. Concatenates in debug mode, minifies in release mode. api.minify_js(['www-dev/js/standalone.js'], 'www/js/standalone.js'), + # Minify AngularJS 1.x. Concatenates in debug mode, minifies and annotates Angular dependencies in release mode. + api.minify_js(['www-dev/angular-1.x/module.js'], 'www/angular-1.x/module.js', annotate_angular=True), + # Concatenate standalone files with no further processing. api.concatenate(['www-dev/js/standalone.js'] * 2, 'www/js/standalone-x2.js'), diff --git a/tests/test_project/www-dev/angular-1.x/module.js b/tests/test_project/www-dev/angular-1.x/module.js new file mode 100644 index 0000000..5705330 --- /dev/null +++ b/tests/test_project/www-dev/angular-1.x/module.js @@ -0,0 +1,9 @@ +angular.module("WebmakeTest", []) + .factory("TestFactory", function () { + this.foo = function () { + alert("foo") + } + }) + .controller("TestController", function (TestFactory) { + TestFactory.foo() + }); \ No newline at end of file From 338af82982c0e2d20e741a9a3ace57ba3d710111 Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Thu, 12 Nov 2020 16:52:53 -0500 Subject: [PATCH 10/13] Deleting the /build directory, was accidentally committed. --- .../lib.linux-x86_64-2.7/webmake/__init__.py | 0 .../lib.linux-x86_64-2.7/webmake/__main__.py | 2 - build/lib.linux-x86_64-2.7/webmake/api.py | 259 ------------------ .../lib.linux-x86_64-2.7/webmake/compiler.py | 111 -------- .../hooks/before_prepare/runwebmake.py | 9 - .../webmake/django/__init__.py | 0 .../webmake/django/middleware.py | 72 ----- build/lib.linux-x86_64-2.7/webmake/main.py | 86 ------ .../webmake/modules/__init__.py | 0 .../webmake/modules/bless.py | 18 -- .../webmake/modules/browserify.py | 161 ----------- .../webmake/modules/concat.py | 46 ---- .../webmake/modules/copyfiles.py | 42 --- .../webmake/modules/less.py | 60 ---- .../webmake/modules/minify.py | 80 ------ .../webmake/modules/reactjs.py | 40 --- .../webmake/modules/sass.py | 52 ---- .../webmake/modules/utils.py | 195 ------------- .../lib.linux-x86_64-2.7/webmake/package.json | 17 -- .../lib.linux-x86_64-2.7/webmake/settings.py | 13 - build/lib.linux-x86_64-2.7/webmake/watcher.py | 54 ---- build/lib/webmake/__init__.py | 0 build/lib/webmake/__main__.py | 2 - build/lib/webmake/api.py | 259 ------------------ build/lib/webmake/compiler.py | 111 -------- .../hooks/before_prepare/runwebmake.py | 9 - build/lib/webmake/django/__init__.py | 0 build/lib/webmake/django/middleware.py | 72 ----- build/lib/webmake/main.py | 86 ------ build/lib/webmake/modules/__init__.py | 0 build/lib/webmake/modules/bless.py | 18 -- build/lib/webmake/modules/browserify.py | 161 ----------- build/lib/webmake/modules/concat.py | 46 ---- build/lib/webmake/modules/copyfiles.py | 42 --- build/lib/webmake/modules/less.py | 60 ---- build/lib/webmake/modules/minify.py | 80 ------ build/lib/webmake/modules/sass.py | 52 ---- build/lib/webmake/modules/utils.py | 195 ------------- build/lib/webmake/package.json | 17 -- build/lib/webmake/settings.py | 13 - build/lib/webmake/watcher.py | 54 ---- 41 files changed, 2594 deletions(-) delete mode 100644 build/lib.linux-x86_64-2.7/webmake/__init__.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/__main__.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/api.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/compiler.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/cordova/hooks/before_prepare/runwebmake.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/django/__init__.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/django/middleware.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/main.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/__init__.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/bless.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/browserify.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/concat.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/copyfiles.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/less.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/minify.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/reactjs.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/sass.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/modules/utils.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/package.json delete mode 100644 build/lib.linux-x86_64-2.7/webmake/settings.py delete mode 100644 build/lib.linux-x86_64-2.7/webmake/watcher.py delete mode 100644 build/lib/webmake/__init__.py delete mode 100644 build/lib/webmake/__main__.py delete mode 100644 build/lib/webmake/api.py delete mode 100644 build/lib/webmake/compiler.py delete mode 100644 build/lib/webmake/cordova/hooks/before_prepare/runwebmake.py delete mode 100644 build/lib/webmake/django/__init__.py delete mode 100644 build/lib/webmake/django/middleware.py delete mode 100644 build/lib/webmake/main.py delete mode 100644 build/lib/webmake/modules/__init__.py delete mode 100644 build/lib/webmake/modules/bless.py delete mode 100644 build/lib/webmake/modules/browserify.py delete mode 100644 build/lib/webmake/modules/concat.py delete mode 100644 build/lib/webmake/modules/copyfiles.py delete mode 100644 build/lib/webmake/modules/less.py delete mode 100644 build/lib/webmake/modules/minify.py delete mode 100644 build/lib/webmake/modules/sass.py delete mode 100644 build/lib/webmake/modules/utils.py delete mode 100644 build/lib/webmake/package.json delete mode 100644 build/lib/webmake/settings.py delete mode 100644 build/lib/webmake/watcher.py diff --git a/build/lib.linux-x86_64-2.7/webmake/__init__.py b/build/lib.linux-x86_64-2.7/webmake/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib.linux-x86_64-2.7/webmake/__main__.py b/build/lib.linux-x86_64-2.7/webmake/__main__.py deleted file mode 100644 index 9dab16c..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/__main__.py +++ /dev/null @@ -1,2 +0,0 @@ -import webmake.main -webmake.main.main() diff --git a/build/lib.linux-x86_64-2.7/webmake/api.py b/build/lib.linux-x86_64-2.7/webmake/api.py deleted file mode 100644 index 363ec1c..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/api.py +++ /dev/null @@ -1,259 +0,0 @@ - - -def list_matching_files(dir, extensions=None, recursive=True): - """ - Returns a list of all files in the specified directory, - optionally recursively and/or with the specified extensions. - """ - from .modules import utils - return utils.list_matching_files(dir, extensions=extensions, recursive=recursive) - - -def concatenate(input_files, output_file): - """ - Concatenates the input files into the single output file. - - In debug mode this function adds a comment with the filename - before the contents of each file. - """ - from .modules import utils, concat - - if not isinstance(input_files, (list, tuple)): - raise RuntimeError('Concatenate takes a list of input files.') - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': concat.concatenate_input_files, - 'input': input_files, - 'output': output_file, - 'kwargs': {}, - } - - -def copy_files(src_dir, dst_dir, filespec='*', recursive=False): - """ - Copies any files matching filespec from src_dir into dst_dir. - - If `recursive` is `True`, also copies any matching directories. - """ - import os - from .modules import copyfiles - - if src_dir == dst_dir: - raise RuntimeError('copy_files() src and dst directories must be different.') - - if not os.path.isdir(src_dir): - raise RuntimeError('copy_files() src directory "{}" does not exist.'.format(src_dir)) - - return { - 'dependencies_fn': copyfiles.list_files, - 'compiler_fn': copyfiles.copy_files, - 'input': src_dir, - 'output': dst_dir, - 'kwargs': { - 'filespec': filespec, - 'recursive': recursive, - }, - } - - -def minify_js(input_files, output_file, annotate_angular=False): - """ - Minifies the input javascript files to the output file. - - Output file may be same as input to minify in place. - - In debug mode this function just concatenates the files - without minifying. - """ - from functools import partial - from .modules import minify, utils - - if not isinstance(input_files, (list, tuple)): - raise RuntimeError('JS minifier takes a list of input files.') - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': partial(minify.minify_js, annotate_angular=annotate_angular), - 'input': input_files, - 'output': output_file, - 'kwargs': {}, - } - - -def minify_css(input_files, output_file): - """ - Minifies the input CSS files to the output file. - - Output file may be same as input to minify in place. - - In debug mode this function just concatenates the files - without minifying. - """ - from .modules import minify, utils - - if not isinstance(input_files, (list, tuple)): - raise RuntimeError('CSS minifier takes a list of input files.') - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': minify.minify_css, - 'input': input_files, - 'output': output_file, - 'kwargs': {}, - } - - -def split_css_for_ie_selector_limit(input_file, output_file): - """ - Splits a large CSS file into several smaller files, each one - containing less than the IE 4096 selector limit. - """ - from .modules import bless, utils - - if not isinstance(input_file, str): - raise RuntimeError('CSS splitter takes only a single input file.') - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': bless.bless_css, - 'input': input_file, - 'output': output_file, - 'kwargs': {}, - } - - -def compile_less(input_file, output_file): - """ - Compile a LESS source file. Minifies the output in release mode. - """ - from .modules import less - - if not isinstance(input_file, str): - raise RuntimeError('LESS compiler takes only a single input file.') - - return { - 'dependencies_fn': less.less_dependencies, - 'compiler_fn': less.less_compile, - 'input': input_file, - 'output': output_file, - 'kwargs': {}, - } - - -def compile_sass(input_file, output_file): - """ - Compile a SASS source file. Minifies the output in release mode. - """ - from .modules import sass - - if not isinstance(input_file, str): - raise RuntimeError('SASS compiler takes only a single input file.') - - return { - 'dependencies_fn': sass.sass_dependencies, - 'compiler_fn': sass.sass_compile, - 'input': input_file, - 'output': output_file, - 'kwargs': {}, - } - - -def browserify_node_modules(module_name_list, output_file, babelify=False): - """ - Browserify a list of libraries from node_modules into a single - javascript file. Generates source maps in debug mode. Minifies the - output in release mode. - - Note you may also specify the relative path to the module - as ``./path/to/module`` or ``./path/to/module/file.js``. - """ - from .modules import browserify - - if not isinstance(module_name_list, (list, tuple)): - raise RuntimeError('Browserify Node Modules compiler takes a list of node module names as input.') - - return { - 'dependencies_fn': browserify.browserify_deps_node_modules, - 'compiler_fn': browserify.browserify_compile_node_modules, - 'input': module_name_list, - 'output': output_file, - 'kwargs': { - 'babelify': babelify, - }, - } - - -def browserify_libs(lib_dirs, output_file, babelify=False): - """ - Browserify one or more library directories into a single - javascript file. Generates source maps in debug mode. Minifies the - output in release mode. - - The final directory name in each of lib_dirs is the library name - for importing. Eg.:: - - lib_dirs = ['cordova_libs/jskit'] - - var MyClass = require('jskit/MyClass'); - """ - from .modules import browserify - - if not isinstance(lib_dirs, (list, tuple)): - raise RuntimeError('Browserify Libs compiler takes a list of library directories as input.') - - return { - 'dependencies_fn': browserify.browserify_deps_libs, - 'compiler_fn': browserify.browserify_compile_libs, - 'input': lib_dirs, - 'output': output_file, - 'kwargs': { - 'babelify': babelify, - }, - } - - -def browserify_file(entry_point, output_file, babelify=False, export_as=None): - """ - Browserify a single javascript entry point plus non-external - dependencies into a single javascript file. Generates source maps - in debug mode. Minifies the output in release mode. - - By default, it is not possible to ``require()`` any exports from the entry - point or included files. If ``export_as`` is specified, any module exports - in the specified entry point are exposed for ``require()`` with the - name specified by ``export_as``. - """ - from .modules import browserify - - if not isinstance(entry_point, str): - raise RuntimeError('Browserify File compiler takes a single entry point as input.') - - return { - 'dependencies_fn': browserify.browserify_deps_file, - 'compiler_fn': browserify.browserify_compile_file, - 'input': entry_point, - 'output': output_file, - 'kwargs': { - 'babelify': babelify, - 'export_as': export_as, - }, - } - - -def custom_function(func, input_files, output_file): - """ - Calls a custom function which must create the output file. - - The custom function takes 3 parameters: ``input_files``, - ``output_file`` and a boolean ``release``. - """ - from .modules import utils - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': func, - 'input': input_files, - 'output': output_file, - 'kwargs': {}, - } diff --git a/build/lib.linux-x86_64-2.7/webmake/compiler.py b/build/lib.linux-x86_64-2.7/webmake/compiler.py deleted file mode 100644 index 4ddd84e..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/compiler.py +++ /dev/null @@ -1,111 +0,0 @@ -import os -import json -from .modules.utils import log, logv, StaticCompilerError - - -def load_dependencies_for_target(target, makefilepath): - logv('\nFinding dependencies for: {}'.format(target['output'])) - try: - dependency_fn = target['dependencies_fn'] - target['dependencies'] = [makefilepath] + dependency_fn(target['input'], **target['kwargs']) - except (IOError, OSError) as e: - msg = '\nERROR: Failed loading dependencies for "{}":\n\nReceived error:\n{}'.format(target['output'], str(e)) - log(msg) - return False - except StaticCompilerError as e: - log(str(e)) - return False - - return True - - -def save_dependencies_to_cache(targets, makefilepath): - cachefile = makefilepath + '.depscache' - logv('\nWriting dependencies cache: {}'.format(cachefile)) - - cache = [{'output': t['output'], 'dependencies': t['dependencies']} - for t in targets if 'dependencies' in t] - - with open(cachefile, 'w') as f: - json.dump(cache, f, indent=4) - - -def load_dependencies_from_cache(targets, makefilepath): - cachefile = makefilepath + '.depscache' - try: - with open(cachefile, 'r') as f: - cache = json.load(f) - except IOError: - return - - for i, entry in enumerate(cache): - output = entry['output'] - deps = entry['dependencies'] - - if i >= len(targets): - break - - if targets[i]['output'] == output: - targets[i]['dependencies'] = deps - - -def dependencies_are_up_to_date(target): - output = target['output'] - deps = target.get('dependencies') - last_compiled_timestamp = os.path.getmtime(output) if os.path.exists(output) else -1 - - if not deps: - return False - - for file in deps: - try: - if os.path.getmtime(file) >= last_compiled_timestamp: - return False - except Exception: - return False - - return True - - -def compile_if_modified(targets, makefilepath, release): - modified = False - first_up_to_date = True - - for target in targets: - if dependencies_are_up_to_date(target): - if first_up_to_date: - logv('') - first_up_to_date = False - logv('Up-to-date: {}', target['output']) - else: - modified = True - first_up_to_date = True - if not compile_target(target, makefilepath, release=release): - return False - - if modified: - save_dependencies_to_cache(targets, makefilepath) - - return True - - -def compile_all(targets, makefilepath, release): - for target in targets: - if not compile_target(target, makefilepath, release=release): - return False - - save_dependencies_to_cache(targets, makefilepath) - return True - - -def compile_target(target, makefilepath, release): - try: - logv('\nCompiling: {}'.format(target['output'])) - compiler_fn = target['compiler_fn'] - compiler_fn(target['input'], target['output'], release=release, **target['kwargs']) - load_dependencies_for_target(target, makefilepath) - return True - except StaticCompilerError as e: - log(str(e)) - return False - diff --git a/build/lib.linux-x86_64-2.7/webmake/cordova/hooks/before_prepare/runwebmake.py b/build/lib.linux-x86_64-2.7/webmake/cordova/hooks/before_prepare/runwebmake.py deleted file mode 100644 index 2c8cff2..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/cordova/hooks/before_prepare/runwebmake.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python -import os - -cmdline = 'webmk -v' -if '--release' in os.environ['CORDOVA_CMDLINE']: - cmdline += ' --force --release' - -print(cmdline) -os.system(cmdline) diff --git a/build/lib.linux-x86_64-2.7/webmake/django/__init__.py b/build/lib.linux-x86_64-2.7/webmake/django/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib.linux-x86_64-2.7/webmake/django/middleware.py b/build/lib.linux-x86_64-2.7/webmake/django/middleware.py deleted file mode 100644 index 84056d3..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/django/middleware.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -Middleware class to watch dependencies and automatically -compile static files during development. - -Usage ------ - -1. Add the following to your local/development settings:: - - # Webmake Middleware - MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + ( - 'webmake.django.middleware.WebmakeCompilerMiddleware', - ) - -2. Create a ``webmakefile.py`` in your project root, and add the -files to compile. - -3. Call ``webmk -fr`` from your deployment process to create -release versions of all target files:: - - def pre_process(self, deployment_settings, *args, **kwargs): - with lcd(PROJECT_PATH): - local('webmk -fr') -""" -import re -import os -import sys -import subprocess -import warnings -from django.conf import settings # pylint: disable=import-error - - -SETTINGS_ROOT = os.path.dirname(os.path.abspath(os.path.join(sys.modules[settings.SETTINGS_MODULE].__file__))) -PROJECT_ROOT = os.path.abspath(os.path.join(re.sub(r'settings[/\\]?$', '', SETTINGS_ROOT), os.pardir)) -WEBMAKE_BIN = 'webmk' -WEBMAKEFILE = os.path.join(PROJECT_ROOT, 'webmakefile.py') - -POSSIBLE_BINFILES = [f for f in ( - os.path.join(os.path.dirname(sys.executable), WEBMAKE_BIN), - os.path.join(os.path.dirname(sys.executable), WEBMAKE_BIN + '.exe'), - ) if os.path.isfile(f)] - -BINFILE = POSSIBLE_BINFILES[0] if POSSIBLE_BINFILES else WEBMAKE_BIN - - -class WebmakeRuntimeWarning(RuntimeWarning): - pass - - -class WebmakeCompilerMiddleware: - def __init__(self, get_response=None): - self.get_response = get_response - - def __call__(self, request): - self.process_request(request) - return self.get_response(request) - - def process_request(self, request): - if not settings.DEBUG: - warnings.warn('WebmakeCompilerMiddleware should not be used in production!', WebmakeRuntimeWarning) - - cmd = ' '.join([BINFILE, '-m', WEBMAKEFILE]) - env = os.environ.copy() - env.pop('PYTHONPATH', None) - - try: - subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True, env=env) - except subprocess.CalledProcessError as e: - output = e.output.decode('utf-8') if hasattr(e.output, 'decode') else str(e.output) - raise RuntimeError('WebmakeCompilerMiddleware:\n' + output) - - return None diff --git a/build/lib.linux-x86_64-2.7/webmake/main.py b/build/lib.linux-x86_64-2.7/webmake/main.py deleted file mode 100644 index 4affb99..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/main.py +++ /dev/null @@ -1,86 +0,0 @@ -import os -import sys -import argparse -import importlib -import functools -import traceback -from .modules import utils -from . import settings, compiler, watcher - - -def command_line_error(parser, makefile, message): - tb = sys.exc_info()[2] - lineinfo = '' - if tb: - try: - tb = [s for s in reversed(traceback.extract_tb(tb)) if s[0].endswith('webmakefile.py')][0] - lineinfo = 'webmakefile.py:{}: '.format(tb[1]) - except IndexError: - pass - - msg = '\nProcessing: {}\n\n{}{}'.format(makefile, lineinfo, message) - parser.error(msg) - - -def parse_command_line(): - default_webmakefile = os.path.join(os.getcwd(), 'webmakefile.py') - - parser = argparse.ArgumentParser(description='A simple pythonic build system for Web and Cordova projects (JS,Less,Sass...)') - parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output.') - parser.add_argument('-r', '--release', action='store_true', help='Release mode. Minify output and don\'t generate source maps.') - parser.add_argument('-f', '--force', action='store_true', help='Force recompilation of all source files, even if not modified.') - parser.add_argument('-m', '--makefile', default=default_webmakefile, help='Specify the webmakefile.py to use for compilation settings.') - parser.add_argument('-w', '--watch', action='store_true', help='Watch all input files for changes, and recompile automatically.') - - args = parser.parse_args() - error_fn = functools.partial(command_line_error, parser, args.makefile) - - if not args.makefile or not os.path.isfile(args.makefile): - error_fn('webmakefile.py does not exist, please create one in ' - 'your project root and run from there.') - - return (args, error_fn) - - -def main(): - args, error_fn = parse_command_line() - settings.VERBOSE = args.verbose - settings.RELEASE = args.release - settings.FORCE = args.force - settings.MAKEFILEPATH = args.makefile - - webmakefile_dir = os.path.abspath(os.path.expanduser(os.path.dirname(args.makefile))) - webmakefile_name = os.path.basename(args.makefile) - webmakefile_module = os.path.splitext(webmakefile_name)[0] - - os.chdir(webmakefile_dir) - sys.path.insert(0, webmakefile_dir) - - try: - makefile = importlib.import_module(webmakefile_module) - except RuntimeError as e: - error_fn(str(e)) - except Exception as e: # pylint: disable=broad-except - error_fn('Unable to parse webmakefile.py.\n\n{}'.format(str(e))) - - try: - settings.MAKEFILE = makefile.MAKEFILE - except AttributeError: - error_fn('MAKEFILE variable missing in webmakefile.py.') - - utils.logv('WEBMAKEFILE = {}', os.path.join(webmakefile_dir, webmakefile_name)) - utils.logv('RELEASE MODE = {}', ('On' if settings.RELEASE else 'Off')) - utils.logv('FORCE COMPILATION = {}', ('On' if settings.FORCE else 'Off')) - - # Load any cached dependencies - compiler.load_dependencies_from_cache(settings.MAKEFILE, settings.MAKEFILEPATH) - - if settings.FORCE: - if not compiler.compile_all(settings.MAKEFILE, settings.MAKEFILEPATH, settings.RELEASE): - sys.exit(1) - else: - if not compiler.compile_if_modified(settings.MAKEFILE, settings.MAKEFILEPATH, release=settings.RELEASE): - sys.exit(1) - - if args.watch: - watcher.start_watching() diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/__init__.py b/build/lib.linux-x86_64-2.7/webmake/modules/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/bless.py b/build/lib.linux-x86_64-2.7/webmake/modules/bless.py deleted file mode 100644 index dc51d77..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/modules/bless.py +++ /dev/null @@ -1,18 +0,0 @@ -from . import utils - - -def bless_css(input_file, output_file, release=False): - assert isinstance(input_file, str) - - cmdline = [ - utils.get_node_bin_dir('blessc'), - '--no-imports', - ] - cmdline.append(input_file) - cmdline.append(output_file) - - try: - utils.run_command(cmdline, 'Failed to split CSS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - raise diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/browserify.py b/build/lib.linux-x86_64-2.7/webmake/modules/browserify.py deleted file mode 100644 index 25950aa..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/modules/browserify.py +++ /dev/null @@ -1,161 +0,0 @@ -import os -from . import utils, minify - - -def get_extensions_and_params(babelify=False): - extensions = ['.js'] - params = [] - - if babelify: - babelify = utils.get_node_modules_dir('babelify') - preset_es2015 = utils.get_node_modules_dir('babel-preset-es2015') - preset_react = utils.get_node_modules_dir('babel-preset-react') - extensions.extend(['.jsx']) - params.extend(['-t', '[', babelify, '--presets', '[', preset_es2015, preset_react, ']', ']']) - - return (extensions, params) - - -def browserify_basic_error(func_name, output_file, list_deps): - if list_deps: - return 'Failed to list dependencies in {}()'.format(func_name) - else: - return 'Error compiling with {}() to "{}"'.format(func_name, output_file) - - -def browserify_basic_command(output_file, release, list_deps): - sourcemap = '-d' if not release else '' - - cmdline = [ - utils.get_node_bin_dir('browserify'), - ] - - if list_deps: - cmdline.extend([ - '--list', - '--fast', - ]) - else: - cmdline.extend([ - sourcemap, - '-o', - output_file, - ]) - - return cmdline - - -def browserify_run(cmdline, errmsg, output_file, release, list_deps): - env = {'NODE_ENV': 'production'} if release else None - - try: - if output_file: - utils.ensure_path_exists(os.path.dirname(output_file)) - - output = utils.run_command(cmdline, errmsg, env=env) - if list_deps: - return [os.path.abspath(p) if os.path.exists(p) else p for p in output.splitlines()] - elif release: - minify.minify_js([output_file], output_file, release=release) - except: - if output_file: - utils.ensure_deleted(output_file) - raise - - -def browserify_node_modules(module_list, output_file=None, release=False, list_deps=False, babelify=False): - (_, params) = get_extensions_and_params(babelify=babelify) - errmsg = browserify_basic_error('browserify_node_modules', output_file, list_deps) - - # No source maps for vendor libs, load time is too slow - cmdline = browserify_basic_command(output_file, release=True, list_deps=list_deps) - cmdline.extend(params) - - for m in module_list: - if m.startswith('./'): - cmdline.extend(['-r', m + ':' + os.path.basename(m).rsplit('.', maxsplit=1)[0]]) - else: - cmdline.extend(['-r', m]) - - result = browserify_run(cmdline, errmsg, output_file, release, list_deps) - - if list_deps: - def fix_node_modules_path(path): - newpath = os.path.abspath(os.path.join('node_modules', path)) - return newpath if not os.path.exists(path) and os.path.exists(newpath) else path - result = [fix_node_modules_path(p) for p in result] - - return result - - -def browserify_libs(lib_dirs, output_file=None, release=False, list_deps=False, babelify=False): - (exts, params) = get_extensions_and_params(babelify=babelify) - errmsg = browserify_basic_error('browserify_libs', output_file, list_deps) - - cmdline = browserify_basic_command(output_file, release, list_deps) - cmdline.append('--no-bundle-external') - cmdline.extend(params) - - for dir in lib_dirs: - files = utils.list_matching_files(dir, extensions=exts, recursive=True, linux_style_paths=True) - dir = dir.replace('\\', '/') - libname = os.path.basename(dir.rstrip('/\\')) - - for f in files: - assert f.startswith(dir) - newname = libname + os.path.splitext(f[len(dir):])[0] - if not os.path.isabs(f): - f = './' + f - cmdline.extend(['-r', '{}:{}'.format(f, newname)]) - - return browserify_run(cmdline, errmsg, output_file, release, list_deps) - - -def browserify_file(entry_point, output_file=None, release=False, list_deps=False, babelify=False, export_as=None): - (_, params) = get_extensions_and_params(babelify=babelify) - errmsg = browserify_basic_error('browserify_file', output_file, list_deps) - - cmdline = browserify_basic_command(output_file, release, list_deps) - cmdline.append('--no-bundle-external') - cmdline.extend(params) - - if not export_as: - cmdline.extend([ - '-e', - entry_point, - ]) - else: - f = entry_point.replace('\\', '/') - if not os.path.isabs(f): - f = './' + f - - cmdline.extend([ - '-r', - '{}:{}'.format(f, export_as) - ]) - - return browserify_run(cmdline, errmsg, output_file, release, list_deps) - - -def browserify_deps_node_modules(module_list, babelify=False): - return browserify_node_modules(module_list, list_deps=True, babelify=babelify) - - -def browserify_compile_node_modules(module_list, output_file, release=False, babelify=False): - browserify_node_modules(module_list, output_file, release=release, babelify=babelify) - - -def browserify_deps_libs(lib_dirs, babelify=False): - return browserify_libs(lib_dirs, list_deps=True, babelify=babelify) - - -def browserify_compile_libs(lib_dirs, output_file, release=False, babelify=False): - browserify_libs(lib_dirs, output_file, release=release, babelify=babelify) - - -def browserify_deps_file(entry_point, babelify=False, export_as=None): - return browserify_file(entry_point, list_deps=True, babelify=babelify, export_as=export_as) - - -def browserify_compile_file(entry_point, output_file, release=False, babelify=False, export_as=None): - browserify_file(entry_point, output_file, release=release, babelify=babelify, export_as=export_as) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/concat.py b/build/lib.linux-x86_64-2.7/webmake/modules/concat.py deleted file mode 100644 index ed91217..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/modules/concat.py +++ /dev/null @@ -1,46 +0,0 @@ -import os -import six -from . import utils - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') - - -def _trimpath(path): - comps = [] - for _ in range(3): - path, c = os.path.split(path) - comps.append(c) - return os.path.join(*reversed(comps)).replace('\\', '/') - - -def concatenate_input_files(input_files, output_file, release=False): - assert isinstance(input_files, (list, tuple)) - - if len(input_files) == 1 and input_files[0] == output_file: - return - - for f in input_files: - assert f != output_file, 'Concatenate input file is same as output.' - - if output_file: - utils.ensure_path_exists(os.path.dirname(output_file)) - - try: - utils.logv('>>> concat {} > {}'.format(' '.join(input_files), output_file)) - with open(output_file, 'w', **FILE_HANDLE_KWARGS) as output: - for input_file in input_files: - with open(input_file, 'r', **FILE_HANDLE_KWARGS) as input: - output.write(input.read()) - - if not release: - path = _trimpath(input_file) - output.write('\n\n' - '/*\n' - ' * {caret}\n' - ' * {path} \n' - ' * {caret}\n' - ' */\n\n\n'.format(path=path, caret='^' * len(path))) - - except IOError as e: - utils.ensure_deleted(output_file) - raise utils.StaticCompilerError('Failed to concatenate to {}'.format(output_file), error=str(e)) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/copyfiles.py b/build/lib.linux-x86_64-2.7/webmake/modules/copyfiles.py deleted file mode 100644 index e7a53b1..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/modules/copyfiles.py +++ /dev/null @@ -1,42 +0,0 @@ -import os -import shutil -from fnmatch import fnmatch -from . import utils - - -def list_files(src_dir, filespec, recursive=False, include_dirs=True): - inputs = [] - - for dir, _, files in os.walk(src_dir): - if include_dirs: - inputs.append(dir) - - inputs.extend(os.path.join(dir, f) for f in files if match_file(f)) - - if not recursive: - break - - return inputs - - -def copy_files(src_dir, dst_dir, filespec, recursive=False, release=None): - assert src_dir != dst_dir, 'Source and destination directories are the same.' - assert os.path.isdir(src_dir), 'Source directory "{}" does not exist.'.format(src_dir) - - if not os.path.isdir(dst_dir): - try: - os.mkdir(dst_dir) - except OSError as e: - raise utils.StaticCompilerError('Failed to create destination dir "{}"'.format(dst_dir), error=str(e)) - - input_files = list_files(src_dir, filespec, recursive, include_dirs=False) - output_files = [os.path.join(dst_dir, os.path.relpath(p, src_dir)) for p in input_files] - - for input, output in zip(input_files, output_files): - utils.logv('>>> copy {} > {}'.format(input, output)) - dirname = os.path.split(output)[0] - if not os.path.exists(dirname): - os.mkdir(dirname) - shutil.copy2(input, output) - - os.utime(dst_dir, None) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/less.py b/build/lib.linux-x86_64-2.7/webmake/modules/less.py deleted file mode 100644 index b6fc638..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/modules/less.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import re -import six -from . import utils - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') -LESS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.less)?)['"]\s*;""") - - -def _read_less_imports(file): - deps = [] - with open(file, **FILE_HANDLE_KWARGS) as f: - less = f.read() - imports = LESS_IMPORT_RE.findall(less) - less_dir = os.path.dirname(file) - - for imp in imports: - dep = utils.resolve_possible_paths(imp, less_dir, ['.less']) - if dep: - deps.append(dep) - else: - raise ValueError('Invalid LESS import in {}: {}'.format(file, imp)) - - return deps - - -def less_dependencies(input_file): - return utils.breadth_first_search(_read_less_imports, input_file) - - -def less_compile(input_file, output_file, release=False): - map_file = output_file + '.map' - input_abs = os.path.abspath(os.path.dirname(input_file)) - output_abs = os.path.abspath(os.path.dirname(output_file)) - map_url = os.path.basename(map_file) - map_base = os.path.commonprefix([input_abs, output_abs]).replace('\\', '/') - map_rel = os.path.dirname(output_abs[len(map_base):]).replace('\\', '/') - map_root = '/'.join([os.pardir] * len(map_rel.split('/'))) - - minify = '-x' if release else '' - sourcemap = ('-source-map-rootpath={rp} --source-map-basepath={bp} --source-map-url={url} --source-map={map}' - .format(rp=map_root, bp=map_base, url=map_url, map=map_file) - if not release else '') - - cmdline = [ - utils.get_node_bin_dir('lessc'), - '--no-color', - minify, - sourcemap, - input_file, - output_file, - ] - - try: - utils.ensure_deleted(map_file) - utils.run_command(cmdline, 'Failed to compile LESS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - utils.ensure_deleted(map_file) - raise diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/minify.py b/build/lib.linux-x86_64-2.7/webmake/modules/minify.py deleted file mode 100644 index 82a3ade..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/modules/minify.py +++ /dev/null @@ -1,80 +0,0 @@ -import os -import six -from . import utils, concat - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') - - -def minify_js(input_files, output_file, release=False, annotate_angular=False): - assert isinstance(input_files, (list, tuple)) - - concat.concatenate_input_files(input_files, output_file, release=release) - - if not release: - return - - if annotate_angular: - try: - annotate_angular_injections(output_file, output_file) - except: - # utils.ensure_deleted(output_file) - raise - - if output_file: - utils.ensure_path_exists(os.path.dirname(output_file)) - - cmdline = [ - utils.get_node_bin_dir('uglifyjs'), - '--compress', - '--mangle', - '-o', - output_file, - '--', - ] - cmdline.extend([output_file]) - - try: - utils.run_command(cmdline, 'Failed to minify JS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - raise - -def annotate_angular_injections(input_file, output_file): - cmdline = [ - utils.get_node_bin_dir('ng-annotate'), - '--add', - '-o', - output_file, - ] - cmdline.extend([input_file]) - - try: - utils.run_command(cmdline, 'Failed to annotate Annnngular injections to "{}"'.format(output_file)) - except Exception as e: - # utils.ensure_deleted(output_file) - raise - -def minify_css(input_files, output_file, release=False): - assert isinstance(input_files, (list, tuple)) - - concat.concatenate_input_files(input_files, output_file, release=release) - if not release: - return - - cmdline = [ - utils.get_node_bin_dir('cssmin'), - ] - cmdline.append(output_file) - - try: - output = utils.run_command(cmdline, 'Failed to minify CSS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - raise - - try: - with open(output_file, 'w', **FILE_HANDLE_KWARGS) as f: - f.write(output) - except IOError as e: - utils.ensure_deleted(output_file) - raise utils.StaticCompilerError('Failed to minify CSS to "{}"'.format(output_file), str(e)) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/reactjs.py b/build/lib.linux-x86_64-2.7/webmake/modules/reactjs.py deleted file mode 100644 index 9efb403..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/modules/reactjs.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -from . import utils, concat, minify - - -def jsx_compile(input_files, output_file, release=False): - utils.ensure_deleted(output_file) - - output_dir = os.path.dirname(output_file) - output_base = os.path.splitext(os.path.basename(output_file))[0] - tmp_file = os.path.join(output_dir, output_base + '.tmpjsx') - concat.concatenate_input_files(input_files, tmp_file, release=release) - - sourcemap = '--source-map-inline' if not release else '' - - cmdline = [ - utils.get_node_bin_dir('jsx'), - '--no-cache-dir', - sourcemap, - '--extension', - 'tmpjsx', - output_dir, - output_dir, - output_base, - ] - - try: - utils.run_command(cmdline, 'Failed to compile React JSX to "{}"'.format(output_file)) - except: - utils.ensure_deleted(tmp_file) - utils.ensure_deleted(output_base + '.js') - raise - - utils.ensure_deleted(tmp_file) - generated = os.path.abspath(os.path.join(output_dir, output_base + '.js')) - output = os.path.abspath(output_file) - if generated != output: - utils.rename(generated, output) - - if release: - minify.minify_js([output_file], output_file, release=release) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/sass.py b/build/lib.linux-x86_64-2.7/webmake/modules/sass.py deleted file mode 100644 index 1f9bfb6..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/modules/sass.py +++ /dev/null @@ -1,52 +0,0 @@ -import os -import re -import six -from . import utils - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') -SASS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.s[ca]ss)?)['"]\s*;""") - - -def _read_sass_imports(file): - deps = [] - with open(file, **FILE_HANDLE_KWARGS) as f: - sassfile = f.read() - imports = SASS_IMPORT_RE.findall(sassfile) - sass_dir = os.path.dirname(file) - - for imp in imports: - dep = utils.resolve_possible_paths(imp, sass_dir, ['.scss', '.sass'], leading_underscore=True) - if dep: - deps.append(dep) - else: - raise ValueError('Invalid SASS import in {}: {}'.format(file, imp)) - - return deps - - -def sass_dependencies(input_file): - return utils.breadth_first_search(_read_sass_imports, input_file) - - -def sass_compile(input_file, output_file, release=False): - map_file = output_file + '.map' - output_style = 'compressed' if release else 'expanded' - source_map = '--source-comments --source-map-embed --source-map-contents --source-map {}'.format(map_file) if not release else '' - - cmdline = [ - utils.get_node_bin_dir('node-sass'), - '--output-style', - output_style, - source_map, - input_file, - output_file, - ] - - try: - utils.ensure_deleted(map_file) - utils.run_command(cmdline, 'Failed to compile SASS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - raise - finally: - utils.ensure_deleted(map_file) diff --git a/build/lib.linux-x86_64-2.7/webmake/modules/utils.py b/build/lib.linux-x86_64-2.7/webmake/modules/utils.py deleted file mode 100644 index 24b2f22..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/modules/utils.py +++ /dev/null @@ -1,195 +0,0 @@ -import re -import os -import six -import subprocess -from subprocess import CalledProcessError -from .. import settings - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') - - -def log(msg, *args, **kwargs): - """ - Print out a log message. - """ - if len(args) == 0 and len(kwargs) == 0: - print(msg) - else: - print(msg.format(*args, **kwargs)) - - -def logv(msg, *args, **kwargs): - """ - Print out a log message, only if verbose mode. - """ - if settings.VERBOSE: - log(msg, *args, **kwargs) - - -class StaticCompilerError(Exception): - def __init__(self, message, error=None, output=None, source=None): - super(StaticCompilerError, self).__init__() - self.message = message - self.error = error or '' - self.output = output or '' - self.source = source or '' - - def __str__(self): - err = [ - '\nERROR: ', - self.message, - '\n\nReceived error:\n', - self.error, - ] - - if self.output: - err.extend(['\n\nOutput:\n', self.output]) - - if self.source: - err.extend(['\n\nSource:\n', self.source]) - - return ''.join(err) - - -def breadth_first_search(get_deps_fn, root_file): - root_file = os.path.abspath(root_file) - queue = [root_file] - deps = [root_file] - - while len(queue) > 0: - cur_file = queue.pop(0) - new_deps = get_deps_fn(cur_file) - queue.extend(new_deps) - deps.extend(new_deps) - - return deps - - -def list_matching_files(path, extensions=None, recursive=True, linux_style_paths=False): - if isinstance(extensions, list): - extensions = tuple(extensions) - - result = [] - - if recursive: - it = os.walk(path) - else: - it = [(path, (), (f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))))] - - for (dir, _, files) in it: - if extensions: - files = [f for f in files if f.endswith(extensions)] - - for f in files: - f = os.path.join(dir, f) - if linux_style_paths: - f = f.replace('\\', '/') - result.append(f) - - return result - - -def ensure_path_exists(path): - path = os.path.abspath(path) - if not os.path.exists(path): - os.makedirs(path) - - -def ensure_deleted(*args): - for file in args: - try: - os.unlink(file) - except Exception: # pylint: disable=broad-except - pass - - -def rename(old, new): - ensure_deleted(new) - os.rename(old, new) - - -def resolve_possible_paths(path, relative_prefix, possible_extensions=None, leading_underscore=False): - """ - Attempts to resolve the given absolute or relative ``path``. If it - doesn't exist as is, tries to create an absolute path using the - ``relative_prefix``. If that fails, tries relative/absolute versions - with each of ``possible_extensions``. - - :returns: The absolute path, or ``None`` if no such file can be found. - """ - possible_extensions = [''] + list(possible_extensions) if possible_extensions else [''] - possible_paths = [path + e if os.path.isabs(path + e) else os.path.join(relative_prefix, path + e) - for e in possible_extensions] - - if leading_underscore and not os.path.basename(path).startswith('_'): - extra_paths = [os.path.join(os.path.dirname(p), '_' + os.path.basename(p)) - for p in possible_paths] - possible_paths = possible_paths + extra_paths - - for p in possible_paths: - p = os.path.normpath(p) - if os.path.isfile(p): - return p - - return None - - -def get_node_modules_dir(module=None): - moduledir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'node_modules')) - if module: - return os.path.join(moduledir, module) - else: - return moduledir - - -def get_node_bin_dir(cmd=None): - bindir = get_node_modules_dir('.bin') - if cmd: - return os.path.join(bindir, cmd) - else: - return bindir - - -def no_dependencies(input): - if not isinstance(input, (list, tuple)): - return [input] - else: - return input - - -def run_command(cmd, errmsg, env=None): - if env is not None: - newenv = os.environ.copy() - newenv.update(env) - env = newenv - - if isinstance(cmd, (list, tuple)): - cmd = ' '.join(c for c in cmd if c != '') - - try: - logv('>>> ' + cmd) - return subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT, shell=True).decode('ascii', 'replace') - except CalledProcessError as e: - raise StaticCompilerError(errmsg, str(e), e.output.decode('ascii', 'replace')) - - -def extract_line_num(output, regexp): - m = re.search(regexp, output) - if m: - try: - return int(m.group(1)) - except ValueError: - pass - return None - - -def extract_lines_from_source(source, line_num): - start = max(0, line_num - 5) - with open(source, 'r', **FILE_HANDLE_KWARGS) as f: - lines = f.readlines()[start:start + 10] - - ret = ['{}: {}'.format(i + start + 1, l) for (i, l) in enumerate(lines)] - ret[3] = ret[3].rstrip() + ' <<<<<<\n' - return ''.join(ret) - - diff --git a/build/lib.linux-x86_64-2.7/webmake/package.json b/build/lib.linux-x86_64-2.7/webmake/package.json deleted file mode 100644 index 9adf0a5..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "private": true, - "dependencies": { - "babel-cli": "^6.26.0", - "babel-core": "^6.26.0", - "babel-preset-es2015": "^6.24.1", - "babel-preset-react": "^6.24.1", - "babelify": "^8.0.0", - "bless": "^3.0.3", - "browserify": "^9.0.8", - "cssmin": "^0.4.3", - "less": "^2.7.3", - "ng-annotate": "1.x", - "node-sass": "^4.11.0", - "uglify-es": "^3.3.9" - } -} diff --git a/build/lib.linux-x86_64-2.7/webmake/settings.py b/build/lib.linux-x86_64-2.7/webmake/settings.py deleted file mode 100644 index 8c0f903..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/settings.py +++ /dev/null @@ -1,13 +0,0 @@ - -# Whether to show verbose log messages -VERBOSE = False - -# Whether to minify/exclude source maps for production -RELEASE = False - -# Whether to force compilation of all files, rather than compiling modified -FORCE = False - -# The makefile contents & path, and dependencies map -MAKEFILE = None -MAKEFILEPATH = None diff --git a/build/lib.linux-x86_64-2.7/webmake/watcher.py b/build/lib.linux-x86_64-2.7/webmake/watcher.py deleted file mode 100644 index 232d8d8..0000000 --- a/build/lib.linux-x86_64-2.7/webmake/watcher.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -import time -import itertools -from watchdog.observers import Observer -from watchdog.events import FileSystemEventHandler -from .modules.utils import log -from . import settings, compiler - - -FORCE_EXIT = False - - -class WatchdogEventHandler(FileSystemEventHandler): - def on_any_event(self, event): - if event.is_directory or event.src_path.endswith('.depscache'): - return - - if os.path.abspath(event.src_path) == os.path.abspath(settings.MAKEFILEPATH): - log('Detected change to makefile {}, please restart the watcher.\n'.format(settings.MAKEFILEPATH)) - global FORCE_EXIT # pylint: disable=global-statement - FORCE_EXIT = True - return - - what = 'directory' if event.is_directory else 'file' - log('{} {} {}'.format(event.event_type.title(), what, event.src_path)) - - compiler.compile_if_modified(settings.MAKEFILE, settings.MAKEFILEPATH, settings.RELEASE) - log('') - - -def start_watching(): - log('\nWatching for filesystem changes, Ctrl-C to exit...\n') - settings.VERBOSE = True - - paths = itertools.chain.from_iterable(d['dependencies'] for d in settings.MAKEFILE) - paths = set(os.path.abspath(os.path.dirname(p)) for p in paths) - -# import pprint -# pprint.pprint(paths, indent=4) - - observer = Observer() - for path in paths: - observer.schedule(WatchdogEventHandler(), path, recursive=False) - observer.start() - - try: - while not FORCE_EXIT: - time.sleep(1) - raise KeyboardInterrupt() - except KeyboardInterrupt: - log('Shutting down...') - observer.stop() - - observer.join() diff --git a/build/lib/webmake/__init__.py b/build/lib/webmake/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib/webmake/__main__.py b/build/lib/webmake/__main__.py deleted file mode 100644 index 9dab16c..0000000 --- a/build/lib/webmake/__main__.py +++ /dev/null @@ -1,2 +0,0 @@ -import webmake.main -webmake.main.main() diff --git a/build/lib/webmake/api.py b/build/lib/webmake/api.py deleted file mode 100644 index 363ec1c..0000000 --- a/build/lib/webmake/api.py +++ /dev/null @@ -1,259 +0,0 @@ - - -def list_matching_files(dir, extensions=None, recursive=True): - """ - Returns a list of all files in the specified directory, - optionally recursively and/or with the specified extensions. - """ - from .modules import utils - return utils.list_matching_files(dir, extensions=extensions, recursive=recursive) - - -def concatenate(input_files, output_file): - """ - Concatenates the input files into the single output file. - - In debug mode this function adds a comment with the filename - before the contents of each file. - """ - from .modules import utils, concat - - if not isinstance(input_files, (list, tuple)): - raise RuntimeError('Concatenate takes a list of input files.') - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': concat.concatenate_input_files, - 'input': input_files, - 'output': output_file, - 'kwargs': {}, - } - - -def copy_files(src_dir, dst_dir, filespec='*', recursive=False): - """ - Copies any files matching filespec from src_dir into dst_dir. - - If `recursive` is `True`, also copies any matching directories. - """ - import os - from .modules import copyfiles - - if src_dir == dst_dir: - raise RuntimeError('copy_files() src and dst directories must be different.') - - if not os.path.isdir(src_dir): - raise RuntimeError('copy_files() src directory "{}" does not exist.'.format(src_dir)) - - return { - 'dependencies_fn': copyfiles.list_files, - 'compiler_fn': copyfiles.copy_files, - 'input': src_dir, - 'output': dst_dir, - 'kwargs': { - 'filespec': filespec, - 'recursive': recursive, - }, - } - - -def minify_js(input_files, output_file, annotate_angular=False): - """ - Minifies the input javascript files to the output file. - - Output file may be same as input to minify in place. - - In debug mode this function just concatenates the files - without minifying. - """ - from functools import partial - from .modules import minify, utils - - if not isinstance(input_files, (list, tuple)): - raise RuntimeError('JS minifier takes a list of input files.') - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': partial(minify.minify_js, annotate_angular=annotate_angular), - 'input': input_files, - 'output': output_file, - 'kwargs': {}, - } - - -def minify_css(input_files, output_file): - """ - Minifies the input CSS files to the output file. - - Output file may be same as input to minify in place. - - In debug mode this function just concatenates the files - without minifying. - """ - from .modules import minify, utils - - if not isinstance(input_files, (list, tuple)): - raise RuntimeError('CSS minifier takes a list of input files.') - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': minify.minify_css, - 'input': input_files, - 'output': output_file, - 'kwargs': {}, - } - - -def split_css_for_ie_selector_limit(input_file, output_file): - """ - Splits a large CSS file into several smaller files, each one - containing less than the IE 4096 selector limit. - """ - from .modules import bless, utils - - if not isinstance(input_file, str): - raise RuntimeError('CSS splitter takes only a single input file.') - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': bless.bless_css, - 'input': input_file, - 'output': output_file, - 'kwargs': {}, - } - - -def compile_less(input_file, output_file): - """ - Compile a LESS source file. Minifies the output in release mode. - """ - from .modules import less - - if not isinstance(input_file, str): - raise RuntimeError('LESS compiler takes only a single input file.') - - return { - 'dependencies_fn': less.less_dependencies, - 'compiler_fn': less.less_compile, - 'input': input_file, - 'output': output_file, - 'kwargs': {}, - } - - -def compile_sass(input_file, output_file): - """ - Compile a SASS source file. Minifies the output in release mode. - """ - from .modules import sass - - if not isinstance(input_file, str): - raise RuntimeError('SASS compiler takes only a single input file.') - - return { - 'dependencies_fn': sass.sass_dependencies, - 'compiler_fn': sass.sass_compile, - 'input': input_file, - 'output': output_file, - 'kwargs': {}, - } - - -def browserify_node_modules(module_name_list, output_file, babelify=False): - """ - Browserify a list of libraries from node_modules into a single - javascript file. Generates source maps in debug mode. Minifies the - output in release mode. - - Note you may also specify the relative path to the module - as ``./path/to/module`` or ``./path/to/module/file.js``. - """ - from .modules import browserify - - if not isinstance(module_name_list, (list, tuple)): - raise RuntimeError('Browserify Node Modules compiler takes a list of node module names as input.') - - return { - 'dependencies_fn': browserify.browserify_deps_node_modules, - 'compiler_fn': browserify.browserify_compile_node_modules, - 'input': module_name_list, - 'output': output_file, - 'kwargs': { - 'babelify': babelify, - }, - } - - -def browserify_libs(lib_dirs, output_file, babelify=False): - """ - Browserify one or more library directories into a single - javascript file. Generates source maps in debug mode. Minifies the - output in release mode. - - The final directory name in each of lib_dirs is the library name - for importing. Eg.:: - - lib_dirs = ['cordova_libs/jskit'] - - var MyClass = require('jskit/MyClass'); - """ - from .modules import browserify - - if not isinstance(lib_dirs, (list, tuple)): - raise RuntimeError('Browserify Libs compiler takes a list of library directories as input.') - - return { - 'dependencies_fn': browserify.browserify_deps_libs, - 'compiler_fn': browserify.browserify_compile_libs, - 'input': lib_dirs, - 'output': output_file, - 'kwargs': { - 'babelify': babelify, - }, - } - - -def browserify_file(entry_point, output_file, babelify=False, export_as=None): - """ - Browserify a single javascript entry point plus non-external - dependencies into a single javascript file. Generates source maps - in debug mode. Minifies the output in release mode. - - By default, it is not possible to ``require()`` any exports from the entry - point or included files. If ``export_as`` is specified, any module exports - in the specified entry point are exposed for ``require()`` with the - name specified by ``export_as``. - """ - from .modules import browserify - - if not isinstance(entry_point, str): - raise RuntimeError('Browserify File compiler takes a single entry point as input.') - - return { - 'dependencies_fn': browserify.browserify_deps_file, - 'compiler_fn': browserify.browserify_compile_file, - 'input': entry_point, - 'output': output_file, - 'kwargs': { - 'babelify': babelify, - 'export_as': export_as, - }, - } - - -def custom_function(func, input_files, output_file): - """ - Calls a custom function which must create the output file. - - The custom function takes 3 parameters: ``input_files``, - ``output_file`` and a boolean ``release``. - """ - from .modules import utils - - return { - 'dependencies_fn': utils.no_dependencies, - 'compiler_fn': func, - 'input': input_files, - 'output': output_file, - 'kwargs': {}, - } diff --git a/build/lib/webmake/compiler.py b/build/lib/webmake/compiler.py deleted file mode 100644 index 4ddd84e..0000000 --- a/build/lib/webmake/compiler.py +++ /dev/null @@ -1,111 +0,0 @@ -import os -import json -from .modules.utils import log, logv, StaticCompilerError - - -def load_dependencies_for_target(target, makefilepath): - logv('\nFinding dependencies for: {}'.format(target['output'])) - try: - dependency_fn = target['dependencies_fn'] - target['dependencies'] = [makefilepath] + dependency_fn(target['input'], **target['kwargs']) - except (IOError, OSError) as e: - msg = '\nERROR: Failed loading dependencies for "{}":\n\nReceived error:\n{}'.format(target['output'], str(e)) - log(msg) - return False - except StaticCompilerError as e: - log(str(e)) - return False - - return True - - -def save_dependencies_to_cache(targets, makefilepath): - cachefile = makefilepath + '.depscache' - logv('\nWriting dependencies cache: {}'.format(cachefile)) - - cache = [{'output': t['output'], 'dependencies': t['dependencies']} - for t in targets if 'dependencies' in t] - - with open(cachefile, 'w') as f: - json.dump(cache, f, indent=4) - - -def load_dependencies_from_cache(targets, makefilepath): - cachefile = makefilepath + '.depscache' - try: - with open(cachefile, 'r') as f: - cache = json.load(f) - except IOError: - return - - for i, entry in enumerate(cache): - output = entry['output'] - deps = entry['dependencies'] - - if i >= len(targets): - break - - if targets[i]['output'] == output: - targets[i]['dependencies'] = deps - - -def dependencies_are_up_to_date(target): - output = target['output'] - deps = target.get('dependencies') - last_compiled_timestamp = os.path.getmtime(output) if os.path.exists(output) else -1 - - if not deps: - return False - - for file in deps: - try: - if os.path.getmtime(file) >= last_compiled_timestamp: - return False - except Exception: - return False - - return True - - -def compile_if_modified(targets, makefilepath, release): - modified = False - first_up_to_date = True - - for target in targets: - if dependencies_are_up_to_date(target): - if first_up_to_date: - logv('') - first_up_to_date = False - logv('Up-to-date: {}', target['output']) - else: - modified = True - first_up_to_date = True - if not compile_target(target, makefilepath, release=release): - return False - - if modified: - save_dependencies_to_cache(targets, makefilepath) - - return True - - -def compile_all(targets, makefilepath, release): - for target in targets: - if not compile_target(target, makefilepath, release=release): - return False - - save_dependencies_to_cache(targets, makefilepath) - return True - - -def compile_target(target, makefilepath, release): - try: - logv('\nCompiling: {}'.format(target['output'])) - compiler_fn = target['compiler_fn'] - compiler_fn(target['input'], target['output'], release=release, **target['kwargs']) - load_dependencies_for_target(target, makefilepath) - return True - except StaticCompilerError as e: - log(str(e)) - return False - diff --git a/build/lib/webmake/cordova/hooks/before_prepare/runwebmake.py b/build/lib/webmake/cordova/hooks/before_prepare/runwebmake.py deleted file mode 100644 index 2c8cff2..0000000 --- a/build/lib/webmake/cordova/hooks/before_prepare/runwebmake.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python -import os - -cmdline = 'webmk -v' -if '--release' in os.environ['CORDOVA_CMDLINE']: - cmdline += ' --force --release' - -print(cmdline) -os.system(cmdline) diff --git a/build/lib/webmake/django/__init__.py b/build/lib/webmake/django/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib/webmake/django/middleware.py b/build/lib/webmake/django/middleware.py deleted file mode 100644 index 84056d3..0000000 --- a/build/lib/webmake/django/middleware.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -Middleware class to watch dependencies and automatically -compile static files during development. - -Usage ------ - -1. Add the following to your local/development settings:: - - # Webmake Middleware - MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + ( - 'webmake.django.middleware.WebmakeCompilerMiddleware', - ) - -2. Create a ``webmakefile.py`` in your project root, and add the -files to compile. - -3. Call ``webmk -fr`` from your deployment process to create -release versions of all target files:: - - def pre_process(self, deployment_settings, *args, **kwargs): - with lcd(PROJECT_PATH): - local('webmk -fr') -""" -import re -import os -import sys -import subprocess -import warnings -from django.conf import settings # pylint: disable=import-error - - -SETTINGS_ROOT = os.path.dirname(os.path.abspath(os.path.join(sys.modules[settings.SETTINGS_MODULE].__file__))) -PROJECT_ROOT = os.path.abspath(os.path.join(re.sub(r'settings[/\\]?$', '', SETTINGS_ROOT), os.pardir)) -WEBMAKE_BIN = 'webmk' -WEBMAKEFILE = os.path.join(PROJECT_ROOT, 'webmakefile.py') - -POSSIBLE_BINFILES = [f for f in ( - os.path.join(os.path.dirname(sys.executable), WEBMAKE_BIN), - os.path.join(os.path.dirname(sys.executable), WEBMAKE_BIN + '.exe'), - ) if os.path.isfile(f)] - -BINFILE = POSSIBLE_BINFILES[0] if POSSIBLE_BINFILES else WEBMAKE_BIN - - -class WebmakeRuntimeWarning(RuntimeWarning): - pass - - -class WebmakeCompilerMiddleware: - def __init__(self, get_response=None): - self.get_response = get_response - - def __call__(self, request): - self.process_request(request) - return self.get_response(request) - - def process_request(self, request): - if not settings.DEBUG: - warnings.warn('WebmakeCompilerMiddleware should not be used in production!', WebmakeRuntimeWarning) - - cmd = ' '.join([BINFILE, '-m', WEBMAKEFILE]) - env = os.environ.copy() - env.pop('PYTHONPATH', None) - - try: - subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True, env=env) - except subprocess.CalledProcessError as e: - output = e.output.decode('utf-8') if hasattr(e.output, 'decode') else str(e.output) - raise RuntimeError('WebmakeCompilerMiddleware:\n' + output) - - return None diff --git a/build/lib/webmake/main.py b/build/lib/webmake/main.py deleted file mode 100644 index 4affb99..0000000 --- a/build/lib/webmake/main.py +++ /dev/null @@ -1,86 +0,0 @@ -import os -import sys -import argparse -import importlib -import functools -import traceback -from .modules import utils -from . import settings, compiler, watcher - - -def command_line_error(parser, makefile, message): - tb = sys.exc_info()[2] - lineinfo = '' - if tb: - try: - tb = [s for s in reversed(traceback.extract_tb(tb)) if s[0].endswith('webmakefile.py')][0] - lineinfo = 'webmakefile.py:{}: '.format(tb[1]) - except IndexError: - pass - - msg = '\nProcessing: {}\n\n{}{}'.format(makefile, lineinfo, message) - parser.error(msg) - - -def parse_command_line(): - default_webmakefile = os.path.join(os.getcwd(), 'webmakefile.py') - - parser = argparse.ArgumentParser(description='A simple pythonic build system for Web and Cordova projects (JS,Less,Sass...)') - parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output.') - parser.add_argument('-r', '--release', action='store_true', help='Release mode. Minify output and don\'t generate source maps.') - parser.add_argument('-f', '--force', action='store_true', help='Force recompilation of all source files, even if not modified.') - parser.add_argument('-m', '--makefile', default=default_webmakefile, help='Specify the webmakefile.py to use for compilation settings.') - parser.add_argument('-w', '--watch', action='store_true', help='Watch all input files for changes, and recompile automatically.') - - args = parser.parse_args() - error_fn = functools.partial(command_line_error, parser, args.makefile) - - if not args.makefile or not os.path.isfile(args.makefile): - error_fn('webmakefile.py does not exist, please create one in ' - 'your project root and run from there.') - - return (args, error_fn) - - -def main(): - args, error_fn = parse_command_line() - settings.VERBOSE = args.verbose - settings.RELEASE = args.release - settings.FORCE = args.force - settings.MAKEFILEPATH = args.makefile - - webmakefile_dir = os.path.abspath(os.path.expanduser(os.path.dirname(args.makefile))) - webmakefile_name = os.path.basename(args.makefile) - webmakefile_module = os.path.splitext(webmakefile_name)[0] - - os.chdir(webmakefile_dir) - sys.path.insert(0, webmakefile_dir) - - try: - makefile = importlib.import_module(webmakefile_module) - except RuntimeError as e: - error_fn(str(e)) - except Exception as e: # pylint: disable=broad-except - error_fn('Unable to parse webmakefile.py.\n\n{}'.format(str(e))) - - try: - settings.MAKEFILE = makefile.MAKEFILE - except AttributeError: - error_fn('MAKEFILE variable missing in webmakefile.py.') - - utils.logv('WEBMAKEFILE = {}', os.path.join(webmakefile_dir, webmakefile_name)) - utils.logv('RELEASE MODE = {}', ('On' if settings.RELEASE else 'Off')) - utils.logv('FORCE COMPILATION = {}', ('On' if settings.FORCE else 'Off')) - - # Load any cached dependencies - compiler.load_dependencies_from_cache(settings.MAKEFILE, settings.MAKEFILEPATH) - - if settings.FORCE: - if not compiler.compile_all(settings.MAKEFILE, settings.MAKEFILEPATH, settings.RELEASE): - sys.exit(1) - else: - if not compiler.compile_if_modified(settings.MAKEFILE, settings.MAKEFILEPATH, release=settings.RELEASE): - sys.exit(1) - - if args.watch: - watcher.start_watching() diff --git a/build/lib/webmake/modules/__init__.py b/build/lib/webmake/modules/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib/webmake/modules/bless.py b/build/lib/webmake/modules/bless.py deleted file mode 100644 index dc51d77..0000000 --- a/build/lib/webmake/modules/bless.py +++ /dev/null @@ -1,18 +0,0 @@ -from . import utils - - -def bless_css(input_file, output_file, release=False): - assert isinstance(input_file, str) - - cmdline = [ - utils.get_node_bin_dir('blessc'), - '--no-imports', - ] - cmdline.append(input_file) - cmdline.append(output_file) - - try: - utils.run_command(cmdline, 'Failed to split CSS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - raise diff --git a/build/lib/webmake/modules/browserify.py b/build/lib/webmake/modules/browserify.py deleted file mode 100644 index 25950aa..0000000 --- a/build/lib/webmake/modules/browserify.py +++ /dev/null @@ -1,161 +0,0 @@ -import os -from . import utils, minify - - -def get_extensions_and_params(babelify=False): - extensions = ['.js'] - params = [] - - if babelify: - babelify = utils.get_node_modules_dir('babelify') - preset_es2015 = utils.get_node_modules_dir('babel-preset-es2015') - preset_react = utils.get_node_modules_dir('babel-preset-react') - extensions.extend(['.jsx']) - params.extend(['-t', '[', babelify, '--presets', '[', preset_es2015, preset_react, ']', ']']) - - return (extensions, params) - - -def browserify_basic_error(func_name, output_file, list_deps): - if list_deps: - return 'Failed to list dependencies in {}()'.format(func_name) - else: - return 'Error compiling with {}() to "{}"'.format(func_name, output_file) - - -def browserify_basic_command(output_file, release, list_deps): - sourcemap = '-d' if not release else '' - - cmdline = [ - utils.get_node_bin_dir('browserify'), - ] - - if list_deps: - cmdline.extend([ - '--list', - '--fast', - ]) - else: - cmdline.extend([ - sourcemap, - '-o', - output_file, - ]) - - return cmdline - - -def browserify_run(cmdline, errmsg, output_file, release, list_deps): - env = {'NODE_ENV': 'production'} if release else None - - try: - if output_file: - utils.ensure_path_exists(os.path.dirname(output_file)) - - output = utils.run_command(cmdline, errmsg, env=env) - if list_deps: - return [os.path.abspath(p) if os.path.exists(p) else p for p in output.splitlines()] - elif release: - minify.minify_js([output_file], output_file, release=release) - except: - if output_file: - utils.ensure_deleted(output_file) - raise - - -def browserify_node_modules(module_list, output_file=None, release=False, list_deps=False, babelify=False): - (_, params) = get_extensions_and_params(babelify=babelify) - errmsg = browserify_basic_error('browserify_node_modules', output_file, list_deps) - - # No source maps for vendor libs, load time is too slow - cmdline = browserify_basic_command(output_file, release=True, list_deps=list_deps) - cmdline.extend(params) - - for m in module_list: - if m.startswith('./'): - cmdline.extend(['-r', m + ':' + os.path.basename(m).rsplit('.', maxsplit=1)[0]]) - else: - cmdline.extend(['-r', m]) - - result = browserify_run(cmdline, errmsg, output_file, release, list_deps) - - if list_deps: - def fix_node_modules_path(path): - newpath = os.path.abspath(os.path.join('node_modules', path)) - return newpath if not os.path.exists(path) and os.path.exists(newpath) else path - result = [fix_node_modules_path(p) for p in result] - - return result - - -def browserify_libs(lib_dirs, output_file=None, release=False, list_deps=False, babelify=False): - (exts, params) = get_extensions_and_params(babelify=babelify) - errmsg = browserify_basic_error('browserify_libs', output_file, list_deps) - - cmdline = browserify_basic_command(output_file, release, list_deps) - cmdline.append('--no-bundle-external') - cmdline.extend(params) - - for dir in lib_dirs: - files = utils.list_matching_files(dir, extensions=exts, recursive=True, linux_style_paths=True) - dir = dir.replace('\\', '/') - libname = os.path.basename(dir.rstrip('/\\')) - - for f in files: - assert f.startswith(dir) - newname = libname + os.path.splitext(f[len(dir):])[0] - if not os.path.isabs(f): - f = './' + f - cmdline.extend(['-r', '{}:{}'.format(f, newname)]) - - return browserify_run(cmdline, errmsg, output_file, release, list_deps) - - -def browserify_file(entry_point, output_file=None, release=False, list_deps=False, babelify=False, export_as=None): - (_, params) = get_extensions_and_params(babelify=babelify) - errmsg = browserify_basic_error('browserify_file', output_file, list_deps) - - cmdline = browserify_basic_command(output_file, release, list_deps) - cmdline.append('--no-bundle-external') - cmdline.extend(params) - - if not export_as: - cmdline.extend([ - '-e', - entry_point, - ]) - else: - f = entry_point.replace('\\', '/') - if not os.path.isabs(f): - f = './' + f - - cmdline.extend([ - '-r', - '{}:{}'.format(f, export_as) - ]) - - return browserify_run(cmdline, errmsg, output_file, release, list_deps) - - -def browserify_deps_node_modules(module_list, babelify=False): - return browserify_node_modules(module_list, list_deps=True, babelify=babelify) - - -def browserify_compile_node_modules(module_list, output_file, release=False, babelify=False): - browserify_node_modules(module_list, output_file, release=release, babelify=babelify) - - -def browserify_deps_libs(lib_dirs, babelify=False): - return browserify_libs(lib_dirs, list_deps=True, babelify=babelify) - - -def browserify_compile_libs(lib_dirs, output_file, release=False, babelify=False): - browserify_libs(lib_dirs, output_file, release=release, babelify=babelify) - - -def browserify_deps_file(entry_point, babelify=False, export_as=None): - return browserify_file(entry_point, list_deps=True, babelify=babelify, export_as=export_as) - - -def browserify_compile_file(entry_point, output_file, release=False, babelify=False, export_as=None): - browserify_file(entry_point, output_file, release=release, babelify=babelify, export_as=export_as) diff --git a/build/lib/webmake/modules/concat.py b/build/lib/webmake/modules/concat.py deleted file mode 100644 index ed91217..0000000 --- a/build/lib/webmake/modules/concat.py +++ /dev/null @@ -1,46 +0,0 @@ -import os -import six -from . import utils - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') - - -def _trimpath(path): - comps = [] - for _ in range(3): - path, c = os.path.split(path) - comps.append(c) - return os.path.join(*reversed(comps)).replace('\\', '/') - - -def concatenate_input_files(input_files, output_file, release=False): - assert isinstance(input_files, (list, tuple)) - - if len(input_files) == 1 and input_files[0] == output_file: - return - - for f in input_files: - assert f != output_file, 'Concatenate input file is same as output.' - - if output_file: - utils.ensure_path_exists(os.path.dirname(output_file)) - - try: - utils.logv('>>> concat {} > {}'.format(' '.join(input_files), output_file)) - with open(output_file, 'w', **FILE_HANDLE_KWARGS) as output: - for input_file in input_files: - with open(input_file, 'r', **FILE_HANDLE_KWARGS) as input: - output.write(input.read()) - - if not release: - path = _trimpath(input_file) - output.write('\n\n' - '/*\n' - ' * {caret}\n' - ' * {path} \n' - ' * {caret}\n' - ' */\n\n\n'.format(path=path, caret='^' * len(path))) - - except IOError as e: - utils.ensure_deleted(output_file) - raise utils.StaticCompilerError('Failed to concatenate to {}'.format(output_file), error=str(e)) diff --git a/build/lib/webmake/modules/copyfiles.py b/build/lib/webmake/modules/copyfiles.py deleted file mode 100644 index e7a53b1..0000000 --- a/build/lib/webmake/modules/copyfiles.py +++ /dev/null @@ -1,42 +0,0 @@ -import os -import shutil -from fnmatch import fnmatch -from . import utils - - -def list_files(src_dir, filespec, recursive=False, include_dirs=True): - inputs = [] - - for dir, _, files in os.walk(src_dir): - if include_dirs: - inputs.append(dir) - - inputs.extend(os.path.join(dir, f) for f in files if match_file(f)) - - if not recursive: - break - - return inputs - - -def copy_files(src_dir, dst_dir, filespec, recursive=False, release=None): - assert src_dir != dst_dir, 'Source and destination directories are the same.' - assert os.path.isdir(src_dir), 'Source directory "{}" does not exist.'.format(src_dir) - - if not os.path.isdir(dst_dir): - try: - os.mkdir(dst_dir) - except OSError as e: - raise utils.StaticCompilerError('Failed to create destination dir "{}"'.format(dst_dir), error=str(e)) - - input_files = list_files(src_dir, filespec, recursive, include_dirs=False) - output_files = [os.path.join(dst_dir, os.path.relpath(p, src_dir)) for p in input_files] - - for input, output in zip(input_files, output_files): - utils.logv('>>> copy {} > {}'.format(input, output)) - dirname = os.path.split(output)[0] - if not os.path.exists(dirname): - os.mkdir(dirname) - shutil.copy2(input, output) - - os.utime(dst_dir, None) diff --git a/build/lib/webmake/modules/less.py b/build/lib/webmake/modules/less.py deleted file mode 100644 index b6fc638..0000000 --- a/build/lib/webmake/modules/less.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import re -import six -from . import utils - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') -LESS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.less)?)['"]\s*;""") - - -def _read_less_imports(file): - deps = [] - with open(file, **FILE_HANDLE_KWARGS) as f: - less = f.read() - imports = LESS_IMPORT_RE.findall(less) - less_dir = os.path.dirname(file) - - for imp in imports: - dep = utils.resolve_possible_paths(imp, less_dir, ['.less']) - if dep: - deps.append(dep) - else: - raise ValueError('Invalid LESS import in {}: {}'.format(file, imp)) - - return deps - - -def less_dependencies(input_file): - return utils.breadth_first_search(_read_less_imports, input_file) - - -def less_compile(input_file, output_file, release=False): - map_file = output_file + '.map' - input_abs = os.path.abspath(os.path.dirname(input_file)) - output_abs = os.path.abspath(os.path.dirname(output_file)) - map_url = os.path.basename(map_file) - map_base = os.path.commonprefix([input_abs, output_abs]).replace('\\', '/') - map_rel = os.path.dirname(output_abs[len(map_base):]).replace('\\', '/') - map_root = '/'.join([os.pardir] * len(map_rel.split('/'))) - - minify = '-x' if release else '' - sourcemap = ('-source-map-rootpath={rp} --source-map-basepath={bp} --source-map-url={url} --source-map={map}' - .format(rp=map_root, bp=map_base, url=map_url, map=map_file) - if not release else '') - - cmdline = [ - utils.get_node_bin_dir('lessc'), - '--no-color', - minify, - sourcemap, - input_file, - output_file, - ] - - try: - utils.ensure_deleted(map_file) - utils.run_command(cmdline, 'Failed to compile LESS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - utils.ensure_deleted(map_file) - raise diff --git a/build/lib/webmake/modules/minify.py b/build/lib/webmake/modules/minify.py deleted file mode 100644 index 82a3ade..0000000 --- a/build/lib/webmake/modules/minify.py +++ /dev/null @@ -1,80 +0,0 @@ -import os -import six -from . import utils, concat - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') - - -def minify_js(input_files, output_file, release=False, annotate_angular=False): - assert isinstance(input_files, (list, tuple)) - - concat.concatenate_input_files(input_files, output_file, release=release) - - if not release: - return - - if annotate_angular: - try: - annotate_angular_injections(output_file, output_file) - except: - # utils.ensure_deleted(output_file) - raise - - if output_file: - utils.ensure_path_exists(os.path.dirname(output_file)) - - cmdline = [ - utils.get_node_bin_dir('uglifyjs'), - '--compress', - '--mangle', - '-o', - output_file, - '--', - ] - cmdline.extend([output_file]) - - try: - utils.run_command(cmdline, 'Failed to minify JS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - raise - -def annotate_angular_injections(input_file, output_file): - cmdline = [ - utils.get_node_bin_dir('ng-annotate'), - '--add', - '-o', - output_file, - ] - cmdline.extend([input_file]) - - try: - utils.run_command(cmdline, 'Failed to annotate Annnngular injections to "{}"'.format(output_file)) - except Exception as e: - # utils.ensure_deleted(output_file) - raise - -def minify_css(input_files, output_file, release=False): - assert isinstance(input_files, (list, tuple)) - - concat.concatenate_input_files(input_files, output_file, release=release) - if not release: - return - - cmdline = [ - utils.get_node_bin_dir('cssmin'), - ] - cmdline.append(output_file) - - try: - output = utils.run_command(cmdline, 'Failed to minify CSS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - raise - - try: - with open(output_file, 'w', **FILE_HANDLE_KWARGS) as f: - f.write(output) - except IOError as e: - utils.ensure_deleted(output_file) - raise utils.StaticCompilerError('Failed to minify CSS to "{}"'.format(output_file), str(e)) diff --git a/build/lib/webmake/modules/sass.py b/build/lib/webmake/modules/sass.py deleted file mode 100644 index 1f9bfb6..0000000 --- a/build/lib/webmake/modules/sass.py +++ /dev/null @@ -1,52 +0,0 @@ -import os -import re -import six -from . import utils - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') -SASS_IMPORT_RE = re.compile(r"""@import\s+['"](.+?(?:\.s[ca]ss)?)['"]\s*;""") - - -def _read_sass_imports(file): - deps = [] - with open(file, **FILE_HANDLE_KWARGS) as f: - sassfile = f.read() - imports = SASS_IMPORT_RE.findall(sassfile) - sass_dir = os.path.dirname(file) - - for imp in imports: - dep = utils.resolve_possible_paths(imp, sass_dir, ['.scss', '.sass'], leading_underscore=True) - if dep: - deps.append(dep) - else: - raise ValueError('Invalid SASS import in {}: {}'.format(file, imp)) - - return deps - - -def sass_dependencies(input_file): - return utils.breadth_first_search(_read_sass_imports, input_file) - - -def sass_compile(input_file, output_file, release=False): - map_file = output_file + '.map' - output_style = 'compressed' if release else 'expanded' - source_map = '--source-comments --source-map-embed --source-map-contents --source-map {}'.format(map_file) if not release else '' - - cmdline = [ - utils.get_node_bin_dir('node-sass'), - '--output-style', - output_style, - source_map, - input_file, - output_file, - ] - - try: - utils.ensure_deleted(map_file) - utils.run_command(cmdline, 'Failed to compile SASS to "{}"'.format(output_file)) - except: - utils.ensure_deleted(output_file) - raise - finally: - utils.ensure_deleted(map_file) diff --git a/build/lib/webmake/modules/utils.py b/build/lib/webmake/modules/utils.py deleted file mode 100644 index 24b2f22..0000000 --- a/build/lib/webmake/modules/utils.py +++ /dev/null @@ -1,195 +0,0 @@ -import re -import os -import six -import subprocess -from subprocess import CalledProcessError -from .. import settings - -FILE_HANDLE_KWARGS = {} if six.PY2 else dict(encoding='utf-8') - - -def log(msg, *args, **kwargs): - """ - Print out a log message. - """ - if len(args) == 0 and len(kwargs) == 0: - print(msg) - else: - print(msg.format(*args, **kwargs)) - - -def logv(msg, *args, **kwargs): - """ - Print out a log message, only if verbose mode. - """ - if settings.VERBOSE: - log(msg, *args, **kwargs) - - -class StaticCompilerError(Exception): - def __init__(self, message, error=None, output=None, source=None): - super(StaticCompilerError, self).__init__() - self.message = message - self.error = error or '' - self.output = output or '' - self.source = source or '' - - def __str__(self): - err = [ - '\nERROR: ', - self.message, - '\n\nReceived error:\n', - self.error, - ] - - if self.output: - err.extend(['\n\nOutput:\n', self.output]) - - if self.source: - err.extend(['\n\nSource:\n', self.source]) - - return ''.join(err) - - -def breadth_first_search(get_deps_fn, root_file): - root_file = os.path.abspath(root_file) - queue = [root_file] - deps = [root_file] - - while len(queue) > 0: - cur_file = queue.pop(0) - new_deps = get_deps_fn(cur_file) - queue.extend(new_deps) - deps.extend(new_deps) - - return deps - - -def list_matching_files(path, extensions=None, recursive=True, linux_style_paths=False): - if isinstance(extensions, list): - extensions = tuple(extensions) - - result = [] - - if recursive: - it = os.walk(path) - else: - it = [(path, (), (f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))))] - - for (dir, _, files) in it: - if extensions: - files = [f for f in files if f.endswith(extensions)] - - for f in files: - f = os.path.join(dir, f) - if linux_style_paths: - f = f.replace('\\', '/') - result.append(f) - - return result - - -def ensure_path_exists(path): - path = os.path.abspath(path) - if not os.path.exists(path): - os.makedirs(path) - - -def ensure_deleted(*args): - for file in args: - try: - os.unlink(file) - except Exception: # pylint: disable=broad-except - pass - - -def rename(old, new): - ensure_deleted(new) - os.rename(old, new) - - -def resolve_possible_paths(path, relative_prefix, possible_extensions=None, leading_underscore=False): - """ - Attempts to resolve the given absolute or relative ``path``. If it - doesn't exist as is, tries to create an absolute path using the - ``relative_prefix``. If that fails, tries relative/absolute versions - with each of ``possible_extensions``. - - :returns: The absolute path, or ``None`` if no such file can be found. - """ - possible_extensions = [''] + list(possible_extensions) if possible_extensions else [''] - possible_paths = [path + e if os.path.isabs(path + e) else os.path.join(relative_prefix, path + e) - for e in possible_extensions] - - if leading_underscore and not os.path.basename(path).startswith('_'): - extra_paths = [os.path.join(os.path.dirname(p), '_' + os.path.basename(p)) - for p in possible_paths] - possible_paths = possible_paths + extra_paths - - for p in possible_paths: - p = os.path.normpath(p) - if os.path.isfile(p): - return p - - return None - - -def get_node_modules_dir(module=None): - moduledir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'node_modules')) - if module: - return os.path.join(moduledir, module) - else: - return moduledir - - -def get_node_bin_dir(cmd=None): - bindir = get_node_modules_dir('.bin') - if cmd: - return os.path.join(bindir, cmd) - else: - return bindir - - -def no_dependencies(input): - if not isinstance(input, (list, tuple)): - return [input] - else: - return input - - -def run_command(cmd, errmsg, env=None): - if env is not None: - newenv = os.environ.copy() - newenv.update(env) - env = newenv - - if isinstance(cmd, (list, tuple)): - cmd = ' '.join(c for c in cmd if c != '') - - try: - logv('>>> ' + cmd) - return subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT, shell=True).decode('ascii', 'replace') - except CalledProcessError as e: - raise StaticCompilerError(errmsg, str(e), e.output.decode('ascii', 'replace')) - - -def extract_line_num(output, regexp): - m = re.search(regexp, output) - if m: - try: - return int(m.group(1)) - except ValueError: - pass - return None - - -def extract_lines_from_source(source, line_num): - start = max(0, line_num - 5) - with open(source, 'r', **FILE_HANDLE_KWARGS) as f: - lines = f.readlines()[start:start + 10] - - ret = ['{}: {}'.format(i + start + 1, l) for (i, l) in enumerate(lines)] - ret[3] = ret[3].rstrip() + ' <<<<<<\n' - return ''.join(ret) - - diff --git a/build/lib/webmake/package.json b/build/lib/webmake/package.json deleted file mode 100644 index 9adf0a5..0000000 --- a/build/lib/webmake/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "private": true, - "dependencies": { - "babel-cli": "^6.26.0", - "babel-core": "^6.26.0", - "babel-preset-es2015": "^6.24.1", - "babel-preset-react": "^6.24.1", - "babelify": "^8.0.0", - "bless": "^3.0.3", - "browserify": "^9.0.8", - "cssmin": "^0.4.3", - "less": "^2.7.3", - "ng-annotate": "1.x", - "node-sass": "^4.11.0", - "uglify-es": "^3.3.9" - } -} diff --git a/build/lib/webmake/settings.py b/build/lib/webmake/settings.py deleted file mode 100644 index 8c0f903..0000000 --- a/build/lib/webmake/settings.py +++ /dev/null @@ -1,13 +0,0 @@ - -# Whether to show verbose log messages -VERBOSE = False - -# Whether to minify/exclude source maps for production -RELEASE = False - -# Whether to force compilation of all files, rather than compiling modified -FORCE = False - -# The makefile contents & path, and dependencies map -MAKEFILE = None -MAKEFILEPATH = None diff --git a/build/lib/webmake/watcher.py b/build/lib/webmake/watcher.py deleted file mode 100644 index 232d8d8..0000000 --- a/build/lib/webmake/watcher.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -import time -import itertools -from watchdog.observers import Observer -from watchdog.events import FileSystemEventHandler -from .modules.utils import log -from . import settings, compiler - - -FORCE_EXIT = False - - -class WatchdogEventHandler(FileSystemEventHandler): - def on_any_event(self, event): - if event.is_directory or event.src_path.endswith('.depscache'): - return - - if os.path.abspath(event.src_path) == os.path.abspath(settings.MAKEFILEPATH): - log('Detected change to makefile {}, please restart the watcher.\n'.format(settings.MAKEFILEPATH)) - global FORCE_EXIT # pylint: disable=global-statement - FORCE_EXIT = True - return - - what = 'directory' if event.is_directory else 'file' - log('{} {} {}'.format(event.event_type.title(), what, event.src_path)) - - compiler.compile_if_modified(settings.MAKEFILE, settings.MAKEFILEPATH, settings.RELEASE) - log('') - - -def start_watching(): - log('\nWatching for filesystem changes, Ctrl-C to exit...\n') - settings.VERBOSE = True - - paths = itertools.chain.from_iterable(d['dependencies'] for d in settings.MAKEFILE) - paths = set(os.path.abspath(os.path.dirname(p)) for p in paths) - -# import pprint -# pprint.pprint(paths, indent=4) - - observer = Observer() - for path in paths: - observer.schedule(WatchdogEventHandler(), path, recursive=False) - observer.start() - - try: - while not FORCE_EXIT: - time.sleep(1) - raise KeyboardInterrupt() - except KeyboardInterrupt: - log('Shutting down...') - observer.stop() - - observer.join() From 6147e4776c1978a0a4e29d4d27139c8cd716186a Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Thu, 12 Nov 2020 16:53:48 -0500 Subject: [PATCH 11/13] Adding Jetbrains project folder to the gitignore file. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d5b1858..0599b6f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ __pycache__ /webmake.egg-info /.project /.pydevproject +/.idea /tests/test_project/package-lock.json /webmake/package-lock.json /build From e976a1a9e911d584f4bf907d0105f14d68943e23 Mon Sep 17 00:00:00 2001 From: YellowSharkMT Date: Thu, 12 Nov 2020 16:55:58 -0500 Subject: [PATCH 12/13] Re-implementing the encoding kwargs for opening LESS files. This resolves an issue that came up on a project that uses webmake, although I'm not certain of the exact bit of LESS that's causing the issue. --- webmake/modules/less.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmake/modules/less.py b/webmake/modules/less.py index ce52688..4da8b57 100644 --- a/webmake/modules/less.py +++ b/webmake/modules/less.py @@ -8,7 +8,7 @@ def _read_less_imports(file): deps = [] - with open(file) as f: + with open(file, encoding='utf-8') as f: less = f.read() imports = LESS_IMPORT_RE.findall(less) less_dir = os.path.dirname(file) From 3aab8b16299e0217b851ab142a16bf8825346121 Mon Sep 17 00:00:00 2001 From: Joe Bergantine Date: Tue, 26 Oct 2021 16:06:12 +0100 Subject: [PATCH 13/13] Remove the mangle arg from uglifyjs call Mangle doesn't seem to be compatible out-of-the-box with annotate angular --- webmake/modules/minify.py | 1 - 1 file changed, 1 deletion(-) diff --git a/webmake/modules/minify.py b/webmake/modules/minify.py index a2955dc..e39dd47 100644 --- a/webmake/modules/minify.py +++ b/webmake/modules/minify.py @@ -28,7 +28,6 @@ def minify_js(input_files, output_file, release=False, annotate_angular=False): cmdline = [ utils.get_node_bin_path('uglify-es', 'bin', 'uglifyjs'), '--compress', - '--mangle', '-o', output_file, '--',