Project

General

Profile

Download (3.48 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / test / script_loader.py @ 3a90084e

1
# SPDX-License-Identifier: GPL-3.0-or-later
2

    
3
"""
4
Loading of parts of Haketilo source for testing in browser
5
"""
6

    
7
# This file is part of Haketilo.
8
#
9
# Copyright (C) 2021 Wojtek Kosior <koszko@koszko.org>
10
#
11
# This program is free software: you can redistribute it and/or modify
12
# it under the terms of the GNU General Public License as published by
13
# the Free Software Foundation, either version 3 of the License, or
14
# (at your option) any later version.
15
#
16
# This program is distributed in the hope that it will be useful,
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
# GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License
22
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
23
#
24
# I, Wojtek Kosior, thereby promise not to sue for violation of this file's
25
# license. Although I request that you do not make use this code in a
26
# proprietary program, I am not going to enforce this in court.
27

    
28
from pathlib import Path
29
import subprocess, re
30

    
31
from .misc_constants import *
32

    
33
script_root = here.parent
34
awk_script = script_root / 'compute_scripts.awk'
35

    
36
def make_relative_path(path):
37
    path = Path(path)
38

    
39
    if path.is_absolute():
40
        path = path.relative_to(script_root)
41

    
42
    return path
43

    
44
"""Used to ignore hidden files and emacs auto-save files."""
45
script_name_regex = re.compile(r'^[^.#].*\.js$')
46

    
47
def available_scripts(directory):
48
    for script in directory.rglob('*.js'):
49
        if script_name_regex.match(script.name):
50
            yield script
51

    
52
def wrapped_script(script_path, wrap_partially=True):
53
    if script_path == 'exports_init.js':
54
        if not (script_root / 'exports_init.js').exists():
55
            subprocess.run([str(script_root / 'write_exports_init.sh'),
56
                            'mozilla', '.', 'default_settings.json'],
57
                           cwd=script_root, check=True)
58

    
59
        with open(script_root / 'exports_init.js') as script:
60
            return script.read()
61

    
62
    command = 'partially_wrapped_code' if wrap_partially else 'wrapped_code'
63
    awk_command = ['awk', '-f', str(awk_script), command, str(script_path)]
64
    awk = subprocess.run(awk_command, stdout=subprocess.PIPE, cwd=script_root,
65
                         check=True)
66

    
67
    return awk.stdout.decode()
68

    
69
def load_script(path, import_dirs):
70
    """
71
    `path` and `import_dirs` are .js file path and a list of directory paths,
72
    respectively. They may be absolute or specified relative to Haketilo's
73
    project directory.
74

    
75
    Return a string containing script from `path` together with all other
76
    scripts it depends. Dependencies are wrapped in the same way Haketilo's
77
    build system wraps them, with imports properly satisfied. The main script
78
    being loaded is wrapped partially - it also has its imports satisfied, but
79
    its code is not placed inside an anonymous function, so the
80
    """
81
    path = make_relative_path(path)
82

    
83
    import_dirs = [make_relative_path(dir) for dir in import_dirs]
84
    available = [s for dir in import_dirs for s in available_scripts(dir)]
85

    
86
    awk = subprocess.run(['awk', '-f', str(awk_script), 'script_dependencies',
87
                          str(path), *[str(s) for s in available]],
88
                         stdout=subprocess.PIPE, cwd=script_root, check=True)
89

    
90
    to_load = awk.stdout.decode().split()
91
    texts = [wrapped_script(path, wrap_partially=(i == len(to_load) - 1))
92
             for i, path in enumerate(to_load)]
93

    
94
    return '\n'.join(texts)
(6-6/8)