const { Injectable } = require('flitter-di') const ImplementationError = require('libflitter/errors/ImplementationError') class PackageManager extends Injectable { static get services() { return [...super.services, 'hosts'] } static PACKAGE_STATE_INSTALLED = 'installed' static PACKAGE_STATE_AVAILABLE = 'available' static PACKAGE_STATE_UNKNOWN = 'unknown' _command_install_package = '%%PACKAGE%%' _command_uninstall_package = '%%PACKAGE%%' _command_update_package = '%%PACKAGE%%' _command_reinstall_package = '%%PACKAGE%%' _command_add_repo = '%%URI%%' _command_clear_cache = '' _command_count_installed = '' _command_count_available = '' _group_packages_by = ' ' constructor(host_or_hostname) { super() if ( typeof host_or_hostname === 'string' ) { host_or_hostname = this.hosts.get(host_or_hostname) } this._host = host_or_hostname } async list_updates() { throw new ImplementationError() } async list_repos() { throw new ImplementationError() } async status(pkg) { throw new ImplementationError() } async search(term) { throw new ImplementationError() } async list_installed() { throw new ImplementationError() } async is_installed(pkg) { const result = await this.status(pkg) return result.state === this.constructor.PACKAGE_STATE_INSTALLED } async clear_cache() { await this._host.run_line_result(this._command_clear_cache) } async count_installed() { return this._host.run_line_result(this._command_count_installed) } async count_available() { return this._host.run_line_result(this._command_count_available) } async install(...packages) { await this._standard_format_execution(packages, this._command_install_package) } async uninstall(...packages) { await this._standard_format_execution(packages, this._command_uninstall_package) } async update(...packages) { await this._standard_format_execution(packages, this._command_update_package) } async reinstall(...packages) { await this._standard_format_execution(packages, this._command_reinstall_package) } async add_repo(uri) { await this._standard_format_execution([uri], this._command_add_repo, '%%URI%%') } async _standard_format_execution(packages, command, placeholder = '%%PACKAGE%%') { if ( this._group_packages_by ) { packages = [packages.join(this._group_packages_by)] } for ( const package_name of packages ) { const result = await this._host.execute(command.replace(placeholder, package_name)) if ( result.exit_code !== 0 ) { throw new Error(`Error encountered while executing command (${command.replace(placeholder, package_name)}): ${result.stderr.join('\n')}`) } } } } module.exports = exports = PackageManager