From 6f955388348310178acb5b601d129490fca02642 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Tue, 15 Feb 2022 17:10:38 +0100 Subject: [PATCH] Split the build script tasks into separate files Build scripts are now located in the scripts folder. Signed-off-by: Trivernis --- .dockerignore | 5 +- .gitignore | 1 + Dockerfile | 6 +- README.md | 17 ++- build.py | 210 ------------------------------------ mediarepo-daemon/Cargo.lock | 2 +- scripts/build.py | 116 ++++++++++++++++++++ scripts/check.py | 57 ++++++++++ scripts/clean.py | 27 +++++ scripts/lib.py | 57 ++++++++++ 10 files changed, 280 insertions(+), 218 deletions(-) delete mode 100755 build.py create mode 100755 scripts/build.py create mode 100755 scripts/check.py create mode 100755 scripts/clean.py create mode 100644 scripts/lib.py diff --git a/.dockerignore b/.dockerignore index e5c8b1c..ced1b76 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,8 @@ # compiled output out +__pycache__ +target +dist # IDEs and editors mediarepo-api/.idea @@ -36,4 +39,4 @@ mediarepo-daemon/*.folded # api mediarepo-api/.idea -mediarepo-api/target +mediarepo-api/target \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2ca27a3..df4f7a5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /out-tsc /target /out +__pycache__ # IDEs and editors mediarepo-api/.idea diff --git a/Dockerfile b/Dockerfile index e9caab0..d1dc609 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ WORKDIR /usr/src COPY mediarepo-api ./mediarepo-api COPY mediarepo-daemon ./mediarepo-daemon COPY mediarepo-ui ./mediarepo-ui -COPY build.py . +COPY scripts ./scripts RUN apt-get update RUN apt-get install -y \ @@ -37,4 +37,6 @@ RUN apt remove cmdtest -y RUN curl https://sh.rustup.rs -sSf | bash -s -- -y ENV PATH="/root/.cargo/bin:${PATH}" -RUN python3 build.py build +RUN python3 scripts/clean.py +RUN python3 scripts/check.py --install +RUN python3 scripts/build.py all --verbose --ffmpeg diff --git a/README.md b/README.md index dd07f19..a837fd3 100644 --- a/README.md +++ b/README.md @@ -69,23 +69,32 @@ You also need to have a working [python](https://www.python.org/) installation o After all required dependencies are installed and tools are accessible in the `PATH`, you can build the project like follows: -> Note: You might need to make the `build.py` file executable with `chmod +x build.py`. +Check (and install) required tooling: +```sh +$ ./scripts/check.py --install +``` +> Note: this only installs tools that are installable via cargo or npm All Componens: ```sh -$ ./build.py build --ffmpeg +$ ./scripts/build.py all --ffmpeg ``` Daemon only: ```sh -$ ./build.py build --daemon --ffmpeg +$ ./scripts/build.py daemon --ffmpeg ``` If you don't want to build with ffmpeg support omit the `--ffmpeg` flag. UI only: ```sh -$ ./build.py build --ui +$ ./scripts/build.py ui +``` + +Clean the output directory: +```sh +$ ./scripts/clean.py ``` After building the `out` directory contains all the built binaries and bundles. diff --git a/build.py b/build.py deleted file mode 100755 index fc6be03..0000000 --- a/build.py +++ /dev/null @@ -1,210 +0,0 @@ -#!/bin/env python3 -import shutil as shut -import os -import subprocess - -tauri_cli_version = '1.0.0-rc.5' -build_output = 'out' -verbose = False -ffmpeg = False - -windows = os.name == 'nt' - - -def exec(cmd: str, dir: str = None) -> str: - print('Running: {}'.format(cmd)) - child = subprocess.run(cmd, shell=True, cwd=dir) - child.check_returncode() - - -def check_exec(name: str): - print('Checking {}...'.format(name)) - - if shut.which(name) is None: - raise Exception('{} not found'.format(name)) - exec(name + ' --version') - - -def check_yarn(): - print('Checking yarn...') - - if shut.which('yarn') is None: - print('installing yarn...') - npm('install -g yarn') - check_exec('yarn') - exec('yarn --version') - - -def check_ng(): - print('Checking ng...') - - if shut.which('ng') is None: - print('installing ng...') - npm('install -g @angular/cli') - check_exec('ng') - exec('ng --version') - - -def store_artifact(path: str): - print('Storing {}'.format(path)) - if os.path.isdir(path): - shut.copytree(path, os.path.join( - build_output, os.path.basename(path)), dirs_exist_ok=True) - else: - shut.copy(path, build_output) - - -def cargo(cmd: str, dir: str = None): - if verbose: - exec('cargo {} --verbose'.format(cmd), dir) - else: - exec('cargo {}'.format(cmd), dir) - - -def npm(cmd: str, dir: str = None): - exec('npm {}'.format(cmd), dir) - - -def yarn(cmd: str, dir: str = None): - exec('yarn {}'.format(cmd), dir) - - -def build_daemon(): - '''Builds daemon''' - cargo('fetch', 'mediarepo-daemon') - - if not ffmpeg: - cargo('build --release --frozen --no-default-features', 'mediarepo-daemon') - else: - cargo('build --release --frozen', 'mediarepo-daemon') - - if windows: - store_artifact('mediarepo-daemon/target/release/mediarepo-daemon.exe') - else: - store_artifact('mediarepo-daemon/target/release/mediarepo-daemon') - - -def build_ui(): - '''Builds UI''' - cargo('install tauri-cli --version ^{}'.format(tauri_cli_version)) - yarn('install', 'mediarepo-ui') - cargo('tauri build', 'mediarepo-ui') - - if windows: - store_artifact( - 'mediarepo-ui/src-tauri/target/release/mediarepo-ui.exe') - else: - store_artifact('mediarepo-ui/src-tauri/target/release/mediarepo-ui') - - store_artifact('mediarepo-ui/src-tauri/target/release/bundle/') - - -def check_daemon(): - '''Checks dependencies for daemon''' - check_exec('clang') - check_exec('cargo') - - -def check_ui(): - '''Checks dependencies for UI''' - - if not windows: - check_exec('wget') - check_exec('curl') - check_exec('file') - - check_exec('clang') - check_exec('cargo') - check_exec('node') - check_exec('npm') - check_yarn() - check_ng() - - -def check(): - '''Checks dependencies''' - check_daemon() - check_ui() - print('All checks passed') - - -def create_output_dir(): - '''Creates build output directory''' - if not os.path.exists(build_output): - os.mkdir(build_output) - - -def clean(): - '''Removes build output''' - if os.path.exists(build_output): - shut.rmtree(build_output) - print('Cleaned') - - -def build(daemon=True, ui=True): - '''Builds both daemon and UI''' - clean() - create_output_dir() - - if daemon: - check_daemon() - build_daemon() - - if ui: - check_ui() - build_ui() - - print('Build complete') - - -def parse_args(): - import argparse - parser = argparse.ArgumentParser(description='Build mediarepo') - subparsers = parser.add_subparsers(dest='command') - subparsers.required = True - - subparsers.add_parser('check') - - build_parser = subparsers.add_parser('build') - build_parser.add_argument( - '--daemon', action='store_true', help='Build daemon') - build_parser.add_argument('--ui', action='store_true', help='Build UI') - build_parser.add_argument( - '--verbose', action='store_true', help='Verbose build') - build_parser.add_argument( - '--output', action='store', help='Build output directory') - build_parser.add_argument( - '--ffmpeg', action='store_true', help='Build with ffmpeg') - - subparsers.add_parser('clean') - args = parser.parse_args() - return args - - -def main(): - opts = parse_args() - - if opts.command == 'build': - global build_output - build_output = opts.output if opts.output else build_output - - global verbose - verbose = opts.verbose - - global ffmpeg - ffmpeg = opts.ffmpeg - - if opts.daemon: - build(True, False) - elif opts.ui: - build(False, True) - else: - build() - elif opts.command == 'check': - check() - elif opts.command == 'clean': - clean() - - -if __name__ == '__main__': - main() diff --git a/mediarepo-daemon/Cargo.lock b/mediarepo-daemon/Cargo.lock index 09f9992..6b809a2 100644 --- a/mediarepo-daemon/Cargo.lock +++ b/mediarepo-daemon/Cargo.lock @@ -1398,7 +1398,7 @@ dependencies = [ [[package]] name = "mediarepo-daemon" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "console-subscriber", "glob", diff --git a/scripts/build.py b/scripts/build.py new file mode 100755 index 0000000..84ef686 --- /dev/null +++ b/scripts/build.py @@ -0,0 +1,116 @@ +#!/bin/env python3 +import shutil as shut +import os +from lib import * +import json +from clean import clean +from check import check_daemon_depends, check_ui_depends + + +build_output = 'out' +verbose = False +ffmpeg = False +install_deps = False + +windows = os.name == 'nt' + + +def main(): + opts = parse_args() + + global install_deps + global build_output + global verbose + global ffmpeg + global install_deps + + build_output = opts.output if opts.output else build_output + verbose = opts.verbose + ffmpeg = opts.ffmpeg + install_deps = opts.install_deps + + build(opts.component) + + +def parse_args(): + import argparse + parser = argparse.ArgumentParser(description='Build mediarepo') + parser.add_argument( + 'component', type=str, nargs='?', default='all', choices=['daemon', 'ui', 'all']) + parser.add_argument( + '--verbose', action='store_true', help='Verbose build') + parser.add_argument('--install-deps', action='store_true', + help='Install dependencies') + parser.add_argument( + '--output', action='store', help='Build output directory') + parser.add_argument( + '--ffmpeg', action='store_true', help='Build with ffmpeg') + + args = parser.parse_args() + return args + + +def build(component: str): + '''Builds the selected component''' + clean() + create_output_dir() + + if component == 'daemon' or component == 'all': + check_daemon_depends() + build_daemon() + elif component == 'ui' or component == 'all': + check_ui_depends(install_deps) + build_ui() + else: + raise Exception('Unknown component: {}'.format(component)) + + print('Build complete') + + +def build_daemon(): + '''Builds daemon''' + cargo('fetch', 'mediarepo-daemon') + + if not ffmpeg: + cargo('build --release --frozen --no-default-features', 'mediarepo-daemon') + else: + cargo('build --release --frozen', 'mediarepo-daemon') + + if windows: + store_artifact('mediarepo-daemon/target/release/mediarepo-daemon.exe') + else: + store_artifact('mediarepo-daemon/target/release/mediarepo-daemon') + + +def build_ui(): + '''Builds UI''' + yarn('install', 'mediarepo-ui') + cargo('tauri build', 'mediarepo-ui') + + if windows: + store_artifact( + 'mediarepo-ui/src-tauri/target/release/mediarepo-ui.exe') + else: + store_artifact('mediarepo-ui/src-tauri/target/release/mediarepo-ui') + + store_artifact('mediarepo-ui/src-tauri/target/release/bundle/') + + +def create_output_dir(): + '''Creates build output directory''' + if not os.path.exists(build_output): + os.mkdir(build_output) + + +def store_artifact(path: str): + '''Stores a build artifact''' + print('Storing {}'.format(path)) + if os.path.isdir(path): + shut.copytree(path, os.path.join( + build_output, os.path.basename(path)), dirs_exist_ok=True) + else: + shut.copy(path, build_output) + + +if __name__ == '__main__': + main() diff --git a/scripts/check.py b/scripts/check.py new file mode 100755 index 0000000..36374b7 --- /dev/null +++ b/scripts/check.py @@ -0,0 +1,57 @@ +#!/bin/env python3 +from lib import * +import argparse +import os + + +tauri_cli_version = '1.0.0-rc.5' +windows = os.name == 'nt' + + +def main(): + opts = parse_args() + check(opts.install_deps) + + +def parse_args(): + '''Parses command line arguments''' + args = argparse.ArgumentParser(description='Build mediarepo') + args.add_argument('--install-deps', action='store_true', + help='Install dependencies that can be installed automatically') + return args.parse_args() + + +def check(install_deps: bool = False): + '''Checks dependencies''' + check_daemon_depends() + check_ui_depends(install_deps) + print('All checks passed') + + +def check_daemon_depends(): + '''Checks dependencies for daemon''' + check_exec('clang') + check_exec('cargo') + + +def check_ui_depends(install_deps: bool = False): + '''Checks dependencies for UI''' + + if not windows: + check_exec('wget') + check_exec('curl') + check_exec('file') + + check_exec('clang') + check_exec('cargo') + check_exec('node') + check_exec('npm') + check_yarn(install_deps) + check_ng(install_deps) + + if install_deps: + install_tauri_cli(tauri_cli_version) + + +if __name__ == '__main__': + main() diff --git a/scripts/clean.py b/scripts/clean.py new file mode 100755 index 0000000..6e87d7a --- /dev/null +++ b/scripts/clean.py @@ -0,0 +1,27 @@ +#!/bin/env python3 +import os +import shutil as shut +import argparse + + +def main(): + opts = parse_args() + clean(opts.output if opts.output else 'out') + + +def parse_args(): + '''Parses command line arguments''' + args = argparse.ArgumentParser(description='Build mediarepo') + args.add_argument('--output', action='store', help='Build output directory') + return args.parse_args() + + +def clean(build_output: str = 'out'): + '''Removes build output''' + if os.path.exists(build_output): + shut.rmtree(build_output) + print('Cleaned') + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/scripts/lib.py b/scripts/lib.py new file mode 100644 index 0000000..8e14c02 --- /dev/null +++ b/scripts/lib.py @@ -0,0 +1,57 @@ +import subprocess +import shutil as shut + + +def install_tauri_cli(version: str): + cargo('install tauri-cli --version ^{}'.format(version)) + + +def check_ng(install: bool = False): + '''Checks if ng is available and installs it + if the install flag is set''' + if not check_exec('ng'): + if install: + npm('install -g @angular/cli') + else: + raise Exception('ng not found') + + +def check_yarn(install: bool = False): + '''Checks if yarn is available and installs it + if the install flag is set''' + if not check_exec('yarn'): + if install: + npm('install yarn') + else: + raise Exception('yarn not found') + + +def yarn(cmd: str, dir: str = None) -> str: + '''Executes yarn in a given directory''' + exec('yarn {}'.format(cmd), dir) + + +def cargo(cmd: str, dir: str = None): + '''Executes cargo in a given directory''' + exec('cargo {}'.format(cmd), dir) + + +def npm(cmd: str, dir: str = None) -> str: + '''Executes npm in a given directory''' + exec('npm {}'.format(cmd), dir) + + +def check_exec(name: str) -> bool: + '''Checks if a command is available''' + if shut.which(name) is None: + print('{} not found'.format(name)) + return False + exec('{} --version'.format(name)) + return True + + +def exec(cmd: str, dir: str = None) -> str: + '''Executes a command in a given directory''' + print('Running: {}'.format(cmd)) + child = subprocess.run(cmd, shell=True, cwd=dir) + child.check_returncode() \ No newline at end of file