Example #1
0
    def install_dependent_packages(packet: Packet, rate_limit: int, install_directory: str, metadata):

        from limit import Limiter, TokenBucket
        from registry import get_environment_keys

        disp = str(packet.dependencies).replace(
            "[", "").replace("]", "").replace("\'", "")
        write(f'{packet.display_name} has the following dependencies: {disp}',
              'bright_yellow', metadata)
        continue_install = confirm(
            'Would you like to install the above dependencies ?')
        if continue_install:
            write(
                f'Installing Dependencies For => {packet.display_name}', 'cyan', metadata)
            if len(packet.dependencies) > 1 and len(packet.dependencies) <= 5:
                write(
                    f'Using Parallel Installation For Installing Dependencies', 'bright_green', metadata)
                packets = []
                for package in packet.dependencies:
                    res = utils.send_req_package(package)
                    pkg = res
                    keys = list(pkg.keys())
                    idx = 0
                    for key in keys:
                        if key not in ['package-name', 'nightly', 'display-name']:
                            idx = keys.index(key)
                            break
                    version = keys[idx]
                    pkg = pkg[version]
                    custom_dir = None
                    if install_directory:
                        custom_dir = install_directory + \
                            f'\\{pkg["package-name"]}'
                    else:
                        custom_dir = install_directory

                    install_exit_codes = None
                    if 'valid-install-exit-codes' in list(pkg.keys()):
                        install_exit_codes = pkg['valid-install-exit-codes']

                    packet = Packet(
                        package,
                        res['package-name'],
                        pkg['url'],
                        pkg['file-type'],
                        pkg['clswitch'],
                        pkg['iswitches'],
                        pkg['uswitches'],
                        custom_dir,
                        pkg['dependencies'],
                        install_exit_codes,
                        None,
                        pkg['set-env'] if 'set-env' in list(
                            pkg.keys()) else None,
                        pkg['default-install-dir'] if 'default-install-dir' in list(
                            pkg.keys()) else None,
                        pkg['uninstall'] if 'uninstall' in list(
                            pkg.keys()) else [],
                        pkg['add-path'] if 'add-path' in list(
                            pkg.keys()) else None,
                        pkg['checksum'] if 'checksum' in list(
                            pkg.keys()) else None,
                        pkg['bin'] if 'bin' in list(pkg.keys()) else None,
                        pkg['pre-update'] if 'pre-update' in list(
                            pkg.keys()) else None,
                    )

                    installation = utils.find_existing_installation(
                        package, packet.json_name)

                    if installation:
                        write_debug(
                            f'Aborting Installation As {packet.json_name} is already installed.', metadata)
                        write_verbose(
                            f'Found an existing installation of => {packet.json_name}', metadata)
                        write(
                            f'Found an existing installation {packet.json_name}.', 'bright_yellow', metadata)

                    write_verbose(
                        f'Package to be installed: {packet.json_name}', metadata)
                    log_info(
                        f'Package to be installed: {packet.json_name}', metadata.logfile)

                    write_verbose(
                        f'Finding closest match to {packet.json_name}...', metadata)
                    log_info(
                        f'Finding closest match to {packet.json_name}...', metadata.logfile)
                    packets.append(packet)

                    write_verbose(
                        'Generating system download path...', metadata)
                    log_info('Generating system download path...',
                             metadata.logfile)

                manager = ThreadedInstaller(packets, metadata)
                paths = manager.handle_multi_download()
                log_info('Finished Rapid Download...', metadata.logfile)
                log_info(
                    'Using Rapid Install To Complete Setup, Accept Prompts Asking For Admin Permission...', metadata.logfile)
                manager.handle_multi_install(paths)
                return
            else:
                write('Starting Sync Installation', 'bright_green', metadata)
                for package in packet.dependencies:
                    res = utils.send_req_package(package)
                    write(
                        f'SuperCached [ {Fore.LIGHTCYAN_EX}{res["display-name"]}{Fore.RESET} ]', 'white', metadata)
                    pkg = res[res['latest-version']]
                    log_info(
                        'Generating Packet For Further Installation.', metadata.logfile)

                    install_exit_codes = None
                    if 'valid-install-exit-codes' in list(pkg.keys()):
                        install_exit_codes = pkg['valid-install-exit-codes']

                    packet = Packet(
                        res,
                        res['package-name'],
                        res['display-name'],
                        pkg['url'],
                        pkg['file-type'],
                        pkg['clswitch'],
                        pkg['iswitches'],
                        pkg['uswitches'],
                        install_directory,
                        pkg['dependencies'],
                        install_exit_codes,
                        [],
                        None,
                        False,
                        pkg['set-env'] if 'set-env' in list(
                            pkg.keys()) else None,
                        pkg['default-install-dir'] if 'default-install-dir' in list(
                            pkg.keys()) else None,
                        pkg['uninstall'] if 'uninstall' in list(
                            pkg.keys()) else [],
                        pkg['add-path'] if 'add-path' in list(
                            pkg.keys()) else None,
                        pkg['checksum'] if 'checksum' in list(
                            pkg.keys()) else None,
                        pkg['bin'] if 'bin' in list(pkg.keys()) else None,
                        pkg['pre-update'] if 'pre-update' in list(
                            pkg.keys()) else None,
                    )

                    log_info(
                        'Searching for existing installation of package.', metadata.logfile)
                    installation = utils.find_existing_installation(
                        package, packet.json_name)

                    if installation:
                        write_debug(
                            f'Found existing installation of {packet.json_name}.', metadata)
                        write_verbose(
                            f'Found an existing installation of => {packet.json_name}', metadata)
                        write(
                            f'Found an existing installation {packet.json_name}.', 'bright_yellow', metadata)
                        continue

                    if packet.dependencies:
                        ThreadedInstaller.install_dependent_packages(
                            packet, rate_limit, install_directory, metadata)

                    write_verbose(
                        f'Package to be installed: {packet.json_name}', metadata)
                    log_info(
                        f'Package to be installed: {packet.json_name}', metadata.logfile)

                    write_verbose(
                        'Generating system download path...', metadata)
                    log_info('Generating system download path...',
                             metadata.logfile)

                    download_url = packet.win64

                    log_info('Initializing Rapid Download...',
                             metadata.logfile)

                    # Downloading The File From Source
                    write_debug(
                        f'Downloading {packet.display_name} from => {packet.win64}', metadata)
                    write_verbose(
                        f"Downloading from '{download_url}'", metadata)
                    log_info(
                        f"Downloading from '{download_url}'", metadata.logfile)

                    if rate_limit == -1:
                        path = utils.download(
                            download_url, packet.json_name, metadata, packet.win64_type)
                    else:
                        log_info(
                            f'Starting rate-limited installation => {rate_limit}', metadata.logfile)
                        bucket = TokenBucket(
                            tokens=10 * rate_limit, fill_rate=rate_limit)

                        limiter = Limiter(
                            bucket=bucket,
                            filename=f'{tempfile.gettempdir()}\Setup{packet.win64_type}',
                        )

                        from urllib.request import urlretrieve

                        urlretrieve(
                            url=download_url,
                            filename=f'{tempfile.gettempdir()}\Setup{packet.win64_type}',
                            reporthook=limiter
                        )

                        path = f'{tempfile.gettempdir()}\Setup{packet.win64_type}'

                    log_info('Finished Rapid Download', metadata.logfile)

                    if metadata.virus_check:
                        write('Scanning File For Viruses...',
                              'bright_cyan', metadata)
                        utils.check_virus(path, metadata)

                    write(
                        f'Installing {packet.display_name}', 'cyan', metadata)
                    log_info(
                        'Using Rapid Install To Complete Setup, Accept Prompts Asking For Admin Permission...', metadata.logfile)

                    write_verbose('Creating registry start snapshot', metadata)
                    log_info('Creating start snapshot of registry...',
                             metadata.logfile)
                    start_snap = get_environment_keys()

                    write_debug(
                        f'Installing {packet.json_name} through Setup{packet.win64_type}', metadata)
                    log_info(
                        f'Installing {packet.json_name} through Setup{packet.win64_type}', metadata.logfile)

                    # Running The Installer silently And Completing Setup
                    utils.install_package(path, packet, metadata)

                    changes_environment = False
                    if packet.shim:
                        changes_environment = True
                        for shim in packet.shim:
                            replace_install_dir = ''

                            if packet.directory:
                                replace_install_dir = packet.directory

                            elif packet.default_install_dir:
                                replace_install_dir = packet.default_install_dir

                            shim = shim.replace(
                                '<install-directory>', replace_install_dir).replace('<version>', packet.version)
                            shim_name = shim.split(
                                "\\")[-1].split('.')[0].replace('<version>', packet.version)
                            write(
                                f'Generating Shim For {shim_name}', 'cyan', metadata)
                            utils.generate_shim(
                                shim, shim_name, shim.split('.')[-1])

                    if packet.add_path:

                        replace_install_dir = ''

                        if packet.directory:
                            replace_install_dir = packet.directory

                        elif packet.default_install_dir:
                            replace_install_dir = packet.default_install_dir

                        write(
                            f'Appending "{packet.add_path.replace("<install-directory>", replace_install_dir)}" To PATH', 'bright_green', metadata)
                        utils.append_to_path(packet.add_path.replace(
                            '<install-directory>', replace_install_dir))

                    if packet.set_env:
                        if isinstance(packet.set_env, list):
                            for obj in packet.set_env:
                                name = obj['name']
                                replace_install_dir = ''

                                if packet.directory:
                                    replace_install_dir = packet.directory

                                elif packet.default_install_dir:
                                    replace_install_dir = packet.default_install_dir

                                write(
                                    f'Setting Environment Variable {name}', 'bright_green', metadata)
                                write_verbose(
                                    f'Setting Environment Variable {name} to {obj["value"].replace("<install-directory>", replace_install_dir)}', metadata)
                                log_info(
                                    f'Setting Environment Variable {name} to {obj["value"].replace("<install-directory>", replace_install_dir)}', metadata.logfile)

                                set_environment_variable(
                                    name, obj['value'].replace('<install-directory>', replace_install_dir))

                        else:
                            name = packet.set_env['name']
                            replace_install_dir = ''

                            if packet.directory:
                                replace_install_dir = packet.directory

                            elif packet.default_install_dir:
                                replace_install_dir = packet.default_install_dir

                            write(
                                f'Setting Environment Variable {name}', 'bright_green', metadata)
                            write_verbose(
                                f'Setting Environment Variable {name} to {packet.set_env["value"].replace("<install-directory>", replace_install_dir)}', metadata)
                            log_info(
                                f'Setting Environment Variable {name} to {packet.set_env["value"].replace("<install-directory>", replace_install_dir)}', metadata.logfile)

                            set_environment_variable(
                                name, packet.set_env['value'].replace('<install-directory>', replace_install_dir))

                    write_verbose(
                        'Creating Final Snapshot Of Environment Keys', metadata)
                    final_snap = get_environment_keys()
                    if final_snap.env_length > start_snap.env_length or final_snap.sys_length > start_snap.sys_length or changes_environment:
                        write('The PATH environment variable has changed. Run `refreshenv` to refresh your environment variables.',
                              'bright_green', metadata)

                    write_verbose(
                        'Successfully Verified Installation Of Packages', metadata)

                    write(
                        f'Successfully Installed {packet.display_name}', 'bright_magenta', metadata)

                    log_info(
                        f'Successfully Installed {packet.display_name}', metadata.logfile)

                    utils.register_package_success(
                        packet, install_directory, metadata)

                    if metadata.reduce_package:

                        os.remove(path)
                        try:
                            os.remove(
                                Rf'{tempfile.gettempdir()}\downloadcache.pickle')
                        except:
                            pass

                        log_info(
                            'Successfully Cleaned Up Installer From Temporary Directory And DownloadCache', metadata.logfile)
                        write('Successfully Cleaned Up Installer From Temp Directory...',
                              'bright_green', metadata)

                    write_verbose(
                        'Dependency successfully Installed.', metadata)
                    log_info('Dependency successfully Installed.',
                             metadata.logfile)
        else:
            os._exit(1)
Example #2
0
def install(
    package_name: str,
    verbose: bool,
    debug: bool,
    no_progress: bool,
    no_color: bool,
    logfile: str,
    yes: bool,
    silent: bool,
    python: bool,
    install_directory: str,
    virus_check: bool,
    no_cache: bool,
    sync: bool,
    reduce: bool,
    rate_limit: int,
    node: bool,
):
    if logfile:
        logfile = logfile.replace('=', '')
    metadata = generate_metadata(no_progress, silent, verbose, debug, no_color,
                                 yes, logfile, virus_check, reduce)

    if logfile:
        logfile = logfile.replace('.txt', '.log')
        createConfig(logfile, logging.INFO, 'Install')

    if python:

        package_names = package_name.split(',')

        for name in package_names:
            handle_python_package(name, 'install', metadata)

        sys.exit()

    if node:
        package_names = package_name.split(',')
        for name in package_names:
            handle_node_package(name, 'install', metadata)

        sys.exit()

    super_cache = check_supercache_valid()
    if no_cache:
        super_cache = False

    status = 'Initializing'
    setup_name = ''
    keyboard.add_hotkey('ctrl+c',
                        lambda: handle_exit(status, setup_name, metadata))

    packages = package_name.strip(' ').split(',')

    if super_cache:
        res, time = handle_cached_request()

    else:
        status = 'Networking'
        write_verbose('Sending GET Request To /packages', metadata)
        write_debug('Sending GET Request To /packages', metadata)
        log_info('Sending GET Request To /packages', logfile)
        res, time = send_req_all()
        res = json.loads(res)
        update_supercache(res)
        del res['_id']

    correct_names = get_correct_package_names(res)
    corrected_package_names = []

    for name in packages:
        if name in correct_names:
            corrected_package_names.append(name)
        else:
            corrections = difflib.get_close_matches(name, correct_names)
            if corrections:
                if silent:
                    click.echo(
                        click.style(
                            'Incorrect / Invalid Package Name Entered. Aborting Installation.',
                            fg='red'))
                    log_info(
                        'Incorrect / Invalid Package Name Entered. Aborting Installation',
                        logfile)
                    handle_exit(status, setup_name, metadata)

                if yes:
                    write(f'Autocorrecting To {corrections[0]}', 'green',
                          metadata)
                    log_info(f'Autocorrecting To {corrections[0]}', logfile)
                    write(f'Successfully Autocorrected To {corrections[0]}',
                          'green', metadata)
                    log_info(f'Successfully Autocorrected To {corrections[0]}',
                             logfile)
                    corrected_package_names.append(corrections[0])

                else:
                    write(f'Autocorrecting To {corrections[0]}',
                          'bright_magenta', metadata)
                    write_verbose(f'Autocorrecting To {corrections[0]}',
                                  metadata)
                    write_debug(f'Autocorrecting To {corrections[0]}',
                                metadata)
                    log_info(f'Autocorrecting To {corrections[0]}', logfile)
                    if click.prompt(
                            'Would You Like To Continue? [y/n]') == 'y':
                        package_name = corrections[0]
                        corrected_package_names.append(package_name)
                    else:
                        sys.exit()
            else:
                write(f'Could Not Find Any Packages Which Match {name}',
                      'bright_magenta', metadata)
                write_debug(f'Could Not Find Any Packages Which Match {name}',
                            metadata)
                write_verbose(
                    f'Could Not Find Any Packages Which Match {name}',
                    metadata)
                log_info(f'Could Not Find Any Packages Which Match {name}',
                         logfile)

    write_debug(install_debug_headers, metadata)
    for header in install_debug_headers:
        log_info(header, logfile)

    index = 0

    if not sync:
        if len(corrected_package_names) > 5:
            write(
                'electric Doesn\'t Support More Than 5 Parallel Downloads At Once Currently. Use The --sync Flag To Synchronously Download The Packages',
                'red', metadata)
        if len(corrected_package_names) > 1:
            packets = []
            for package in corrected_package_names:
                pkg = res[package]
                custom_dir = None
                if install_directory:
                    custom_dir = install_directory + f'\\{pkg["package-name"]}'
                else:
                    custom_dir = install_directory
                packet = Packet(package, pkg['package-name'], pkg['win64'],
                                pkg['darwin'], pkg['debian'],
                                pkg['win64-type'], pkg['darwin-type'],
                                pkg['debian-type'], pkg['custom-location'],
                                pkg['install-switches'],
                                pkg['uninstall-switches'], custom_dir)
                installation = find_existing_installation(
                    package, packet.json_name)
                if installation:
                    write_debug(
                        f"Aborting Installation As {packet.json_name} is already installed.",
                        metadata)
                    write_verbose(
                        f"Found an existing installation of => {packet.json_name}",
                        metadata)
                    write(
                        f"Found an existing installation {packet.json_name}.",
                        'bright_yellow', metadata)
                    installation_continue = click.prompt(
                        f'Would you like to reinstall {packet.json_name} [y/n]'
                    )
                    if installation_continue == 'y' or installation_continue == 'y' or yes:
                        os.system(f'electric uninstall {packet.json_name}')
                        os.system(f'electric install {packet.json_name}')
                        return
                    else:
                        handle_exit(status, setup_name, metadata)

                write_verbose(f"Package to be installed: {packet.json_name}",
                              metadata)
                log_info(f"Package to be installed: {packet.json_name}",
                         logfile)

                write_verbose(
                    f'Finding closest match to {packet.json_name}...',
                    metadata)
                log_info(f'Finding closest match to {packet.json_name}...',
                         logfile)
                packets.append(packet)

            if super_cache:
                write(
                    f'Rapidquery Successfully SuperCached Packages in {round(time, 6)}s',
                    'bright_yellow', metadata)
                write_debug(
                    f'Rapidquery Successfully SuperCached Packages in {round(time, 9)}s',
                    metadata)
                log_info(
                    f'Rapidquery Successfully SuperCached Packages in {round(time, 6)}s',
                    logfile)
            else:
                write(
                    f'Rapidquery Successfully Received packages.json in {round(time, 6)}s',
                    'bright_yellow', metadata)
                write_debug(
                    f'Rapidquery Successfully Received packages.json in {round(time, 9)}s',
                    metadata)
                log_info(
                    f'Rapidquery Successfully Received packages.json in {round(time, 6)}s',
                    logfile)

                write_verbose('Generating system download path...', metadata)
                log_info('Generating system download path...', logfile)

            manager = PackageManager(packets, metadata)
            paths = manager.handle_multi_download()
            log_info('Finished Rapid Download...', logfile)
            log_info(
                'Using Rapid Install To Complete Setup, Accept Prompts Asking For Admin Permission...',
                logfile)
            manager.handle_multi_install(paths)
            return

    for package in corrected_package_names:
        pkg = res[package]
        packet = Packet(package, pkg['package-name'], pkg['win64'],
                        pkg['darwin'], pkg['debian'], pkg['win64-type'],
                        pkg['darwin-type'], pkg['debian-type'],
                        pkg['custom-location'], pkg['install-switches'],
                        pkg['uninstall-switches'], install_directory)
        installation = find_existing_installation(package, packet.json_name)

        if installation:
            write_debug(
                f"Aborting Installation As {packet.json_name} is already installed.",
                metadata)
            write_verbose(
                f"Found an existing installation of => {packet.json_name}",
                metadata)
            write(f"Found an existing installation {packet.json_name}.",
                  'bright_yellow', metadata)
            installation_continue = click.prompt(
                f'Would you like to reinstall {packet.json_name} [y/n]')
            if installation_continue == 'y' or installation_continue == 'y' or yes:
                os.system(f'electric uninstall {packet.json_name}')
                os.system(f'electric install {packet.json_name}')
                return
            else:
                handle_exit(status, setup_name, metadata)
        write_verbose(f"Package to be installed: {packet.json_name}", metadata)
        log_info(f"Package to be installed: {packet.json_name}", logfile)

        write_verbose(f'Finding closest match to {packet.json_name}...',
                      metadata)
        log_info(f'Finding closest match to {packet.json_name}...', logfile)

        if index == 0:
            if super_cache:
                write(
                    f'Rapidquery Successfully SuperCached {packet.json_name} in {round(time, 6)}s',
                    'bright_yellow', metadata)
                write_debug(
                    f'Rapidquery Successfully SuperCached {packet.json_name} in {round(time, 9)}s',
                    metadata)
                log_info(
                    f'Rapidquery Successfully SuperCached {packet.json_name} in {round(time, 6)}s',
                    logfile)
            else:
                write(
                    f'Rapidquery Successfully Received {packet.json_name}.json in {round(time, 6)}s',
                    'bright_yellow', metadata)
                write_debug(
                    f'Rapidquery Successfully Received {packet.json_name}.json in {round(time, 9)}s',
                    metadata)
                log_info(
                    f'Rapidquery Successfully Received {packet.json_name}.json in {round(time, 6)}s',
                    logfile)

        write_verbose('Generating system download path...', metadata)
        log_info('Generating system download path...', logfile)

        start = timer()

        status = 'Download Path'
        download_url = get_download_url(packet)
        status = 'Got Download Path'
        end = timer()

        val = round(Decimal(end) - Decimal(start), 6)
        write(f'Electrons Transferred In {val}s', 'cyan', metadata)
        log_info(f'Electrons Transferred In {val}s', logfile)

        write('Initializing Rapid Download...', 'green', metadata)
        log_info('Initializing Rapid Download...', logfile)

        # Downloading The File From Source
        write_verbose(f"Downloading from '{download_url}'", metadata)
        log_info(f"Downloading from '{download_url}'", logfile)
        status = 'Downloading'

        if rate_limit == -1:
            path = download(download_url, no_progress, silent,
                            packet.win64_type)
        else:
            bucket = TokenBucket(tokens=10 * rate_limit, fill_rate=rate_limit)

            limiter = Limiter(
                bucket=bucket,
                filename=f"{tempfile.gettempdir()}\Setup{packet.win64_type}",
            )

            urlretrieve(
                url=download_url,
                filename=f"{tempfile.gettempdir()}\Setup{packet.win64_type}",
                reporthook=limiter)

            path = f"{tempfile.gettempdir()}\Setup{packet.win64_type}"

        status = 'Downloaded'

        write('\nFinished Rapid Download', 'green', metadata)
        log_info('Finished Rapid Download', logfile)

        if virus_check:
            write('Scanning File For Viruses...', 'blue', metadata)
            check_virus(path, metadata)

        write(
            'Using Rapid Install, Accept Prompts Asking For Admin Permission...',
            'cyan', metadata)
        log_info(
            'Using Rapid Install To Complete Setup, Accept Prompts Asking For Admin Permission...',
            logfile)
        if debug:
            click.echo('\n')
        write_debug(
            f'Installing {packet.json_name} through Setup{packet.win64}',
            metadata)
        log_info(f'Installing {packet.json_name} through Setup{packet.win64}',
                 logfile)
        start_snap = get_environment_keys()
        status = 'Installing'
        # Running The Installer silently And Completing Setup
        install_package(path, packet, metadata)

        status = 'Installed'
        final_snap = get_environment_keys()

        if final_snap.env_length > start_snap.env_length or final_snap.sys_length > start_snap.sys_length:
            write('Refreshing Environment Variables...', 'green', metadata)
            start = timer()
            log_info('Refreshing Environment Variables', logfile)
            write_debug(
                'Refreshing Env Variables, Calling Batch Script At scripts/refreshvars.cmd',
                metadata)
            write_verbose('Refreshing Environment Variables', metadata)
            refresh_environment_variables()
            end = timer()
            write_debug(
                f'Successfully Refreshed Environment Variables in {round(end - start)} seconds',
                metadata)

        write(f'Successfully Installed {packet.display_name}!',
              'bright_magenta', metadata)
        log_info(f'Successfully Installed {packet.display_name}!', logfile)

        if metadata.reduce_package:
            write('Successfully Cleaned Up Installer From Temp Directory...',
                  'green', metadata)
            os.remove(path)

        write_verbose('Installation and setup completed.', metadata)
        log_info('Installation and setup completed.', logfile)
        write_debug(
            f'Terminated debugger at {strftime("%H:%M:%S")} on install::completion',
            metadata)
        log_info(
            f'Terminated debugger at {strftime("%H:%M:%S")} on install::completion',
            logfile)
        closeLog(logfile, 'Install')

        index += 1
    end = timer()
Example #3
0
 def test_get_environment_keys(self):
     ans = registry.get_environment_keys()
     self.assertIsNotNone(ans)
Example #4
0
def install(
    package_name: str,
    verbose: bool,
    debug: bool,
    no_progress: bool,
    no_color: bool,
    logfile: str,
    yes: bool,
    silent: bool,
    python: bool,
    install_directory: str,
    virus_check: bool,
    no_cache: bool,
    sync: bool,
    reduce: bool,
    rate_limit: int,
    node: bool,
    vscode: bool,
):
    if logfile:
        logfile = logfile.replace('=', '')
        logfile = logfile.replace('.txt', '.log')
        createConfig(logfile, logging.INFO, 'Install')

    log_info('Generating metadata...', logfile)
    metadata = generate_metadata(no_progress, silent, verbose, debug, no_color,
                                 yes, logfile, virus_check, reduce, rate_limit)
    log_info('Successfully generated metadata.', metadata.logfile)

    if python:

        package_names = package_name.split(',')

        for name in package_names:
            handle_python_package(name, 'install', metadata)

        sys.exit()

    if node:
        package_names = package_name.split(',')
        for name in package_names:
            handle_node_package(name, 'install', metadata)

        sys.exit()

    if vscode:
        package_names = package_name.split(',')
        for name in package_names:
            handle_vscode_extension(name, 'install', metadata)

        sys.exit()

    log_info('Checking if supercache exists...', metadata.logfile)
    super_cache = check_supercache_valid()
    if super_cache:
        log_info('Supercache detected.', metadata.logfile)
    if no_cache:
        log_info('Overriding SuperCache To FALSE', metadata.logfile)
        super_cache = False

    log_info('Setting up custom `ctrl+c` shortcut.', metadata.logfile)
    status = 'Initializing'
    setup_name = ''
    keyboard.add_hotkey('ctrl+c',
                        lambda: handle_exit(status, setup_name, metadata))

    packages = package_name.strip(' ').split(',')

    if super_cache:
        log_info('Handling SuperCache Request.', metadata.logfile)
        res, time = handle_cached_request()

    else:
        spinner = halo.Halo(color='grey')
        spinner.start()
        log_info('Handling Network Request...', metadata.logfile)
        status = 'Networking'
        write_verbose('Sending GET Request To /packages', metadata)
        write_debug('Sending GET Request To /packages', metadata)
        log_info('Sending GET Request To /packages', metadata.logfile)
        res, time = send_req_all()
        res = json.loads(res)
        update_supercache(res)
        del res['_id']
        spinner.stop()

    correct_names = get_correct_package_names(res)
    corrected_package_names = get_autocorrections(packages, correct_names,
                                                  metadata)

    write_debug(install_debug_headers, metadata)
    for header in install_debug_headers:
        log_info(header, metadata.logfile)

    index = 0

    if not sync:
        if len(corrected_package_names) > 5:
            log_info('Terminating installation!', metadata.logfile)
            write(
                'electric Doesn\'t Support More Than 5 Parallel Downloads At Once Currently. Use The --sync Flag To Synchronously Download The Packages',
                'red', metadata)
        if len(corrected_package_names) > 1:
            packets = []
            for package in corrected_package_names:
                pkg = res[package]
                custom_dir = None
                if install_directory:
                    custom_dir = install_directory + f'\\{pkg["package-name"]}'
                else:
                    custom_dir = install_directory
                packet = Packet(package, pkg['package-name'], pkg['win64'],
                                pkg['win64-type'], pkg['custom-location'],
                                pkg['install-switches'],
                                pkg['uninstall-switches'], custom_dir,
                                pkg['dependencies'])
                installation = find_existing_installation(
                    package, packet.display_name)
                if installation:
                    write_debug(
                        f'Aborting Installation As {packet.json_name} is already installed.',
                        metadata)
                    write_verbose(
                        f'Found an existing installation of => {packet.json_name}',
                        metadata)
                    write(
                        f'Found an existing installation {packet.json_name}.',
                        'bright_yellow', metadata)
                    installation_continue = click.confirm(
                        f'Would you like to reinstall {packet.json_name}')
                    if installation_continue or yes:
                        os.system(f'electric uninstall {packet.json_name}')
                        os.system(f'electric install {packet.json_name}')
                        return
                    else:
                        handle_exit(status, setup_name, metadata)

                write_verbose(f'Package to be installed: {packet.json_name}',
                              metadata)
                log_info(f'Package to be installed: {packet.json_name}',
                         metadata.logfile)

                write_verbose(
                    f'Finding closest match to {packet.json_name}...',
                    metadata)
                log_info(f'Finding closest match to {packet.json_name}...',
                         metadata.logfile)
                packets.append(packet)

                write_verbose('Generating system download path...', metadata)
                log_info('Generating system download path...',
                         metadata.logfile)

            manager = PackageManager(packets, metadata)
            paths = manager.handle_multi_download()
            log_info('Finished Rapid Download...', metadata.logfile)
            log_info(
                'Using Rapid Install To Complete Setup, Accept Prompts Asking For Admin Permission...',
                metadata.logfile)
            manager.handle_multi_install(paths)
            return

    for package in corrected_package_names:
        pkg = res[package]
        log_info('Generating Packet For Further Installation.',
                 metadata.logfile)
        packet = Packet(package, pkg['package-name'], pkg['win64'],
                        pkg['win64-type'], pkg['custom-location'],
                        pkg['install-switches'], pkg['uninstall-switches'],
                        install_directory, pkg['dependencies'])
        log_info('Searching for existing installation of package.',
                 metadata.logfile)

        installation = find_existing_installation(package, packet.json_name)

        if installation:
            write_debug(f'Found existing installation of {packet.json_name}.',
                        metadata)
            write_verbose(
                f'Found an existing installation of => {packet.json_name}',
                metadata)
            write(f'Detected an existing installation {packet.json_name}.',
                  'bright_yellow', metadata)
            installation_continue = click.confirm(
                f'Would you like to reinstall {packet.json_name}')
            if installation_continue or yes:
                os.system(f'electric uninstall {packet.json_name}')
                os.system(f'electric install {packet.json_name}')
                return
            else:
                handle_exit(status, setup_name, metadata)

        if packet.dependencies:
            install_dependent_packages(packet, rate_limit, install_directory,
                                       metadata)

        write_verbose(f'Package to be installed: {packet.json_name}', metadata)
        log_info(f'Package to be installed: {packet.json_name}',
                 metadata.logfile)

        write_verbose(f'Finding closest match to {packet.json_name}...',
                      metadata)
        log_info(f'Finding closest match to {packet.json_name}...',
                 metadata.logfile)

        if index == 0:
            if super_cache:
                write_verbose(
                    f'Rapidquery Successfully SuperCached {packet.json_name} in {round(time, 6)}s',
                    metadata)
                write_debug(
                    f'Rapidquery Successfully SuperCached {packet.json_name} in {round(time, 6)}s',
                    metadata)
                log_info(
                    f'Rapidquery Successfully SuperCached {packet.json_name} in {round(time, 6)}s',
                    metadata.logfile)
            else:
                write_verbose(
                    f'Rapidquery Successfully Received {packet.json_name}.json in {round(time, 6)}s',
                    metadata)
                write_debug(
                    f'Rapidquery Successfully Received {packet.json_name}.json in {round(time, 6)}s',
                    metadata)
                log_info(
                    f'Rapidquery Successfully Received {packet.json_name}.json in {round(time, 6)}s',
                    metadata.logfile)

        write_verbose('Generating system download path...', metadata)
        log_info('Generating system download path...', metadata.logfile)

        if not metadata.silent:
            if not metadata.no_color:
                if super_cache:
                    print(
                        f'SuperCached', Fore.GREEN + '=>' + Fore.RESET, '[',
                        Fore.CYAN + f'{packet.display_name}' + Fore.RESET +
                        ' ]')
                else:
                    print(
                        f'Recieved => [', Fore.CYAN +
                        f'{packet.display_name}' + Fore.RESET + ' ]')

            else:
                print(f'Found => [ {packet.display_name} ]')
        start = timer()

        status = 'Download Path'
        download_url = get_download_url(packet)
        status = 'Got Download Path'
        end = timer()

        log_info('Initializing Rapid Download...', metadata.logfile)

        # Downloading The File From Source
        write_debug(
            f'Downloading {packet.display_name} from => {packet.win64}',
            metadata)
        write_verbose(f"Downloading from '{download_url}'", metadata)
        log_info(f"Downloading from '{download_url}'", metadata.logfile)
        status = 'Downloading'

        if rate_limit == -1:
            start = timer()
            path, cached = download(download_url, packet.json_name, metadata,
                                    packet.win64_type)
            end = timer()
        else:
            log_info(f'Starting rate-limited installation => {rate_limit}',
                     metadata.logfile)
            bucket = TokenBucket(tokens=10 * rate_limit, fill_rate=rate_limit)

            limiter = Limiter(
                bucket=bucket,
                filename=f'{tempfile.gettempdir()}\Setup{packet.win64_type}',
            )

            urlretrieve(
                url=download_url,
                filename=f'{tempfile.gettempdir()}\Setup{packet.win64_type}',
                reporthook=limiter)

            path = f'{tempfile.gettempdir()}\Setup{packet.win64_type}'

        status = 'Downloaded'

        log_info('Finished Rapid Download', metadata.logfile)

        if virus_check:
            write('Scanning File For Viruses...', 'blue', metadata)
            check_virus(path, metadata)
        if not cached:
            write(
                '\nUsing Rapid Install, Accept Prompts Asking For Admin Permission...',
                'cyan', metadata)
        else:
            write(
                'Using Rapid Install, Accept Prompts Asking For Admin Permission...',
                'cyan', metadata)
        log_info(
            'Using Rapid Install To Complete Setup, Accept Prompts Asking For Admin Permission...',
            metadata.logfile)

        write_debug(
            f'Installing {packet.json_name} through Setup{packet.win64_type}',
            metadata)
        log_info(
            f'Installing {packet.json_name} through Setup{packet.win64_type}',
            metadata.logfile)
        start_snap = get_environment_keys()
        status = 'Installing'
        # Running The Installer silently And Completing Setup
        install_package(path, packet, metadata)

        status = 'Installed'
        final_snap = get_environment_keys()
        if final_snap.env_length > start_snap.env_length or final_snap.sys_length > start_snap.sys_length:
            write('Refreshing Environment Variables...', 'green', metadata)
            start = timer()
            log_info(
                'Refreshing Environment Variables At scripts/refreshvars.cmd',
                metadata.logfile)
            write_debug(
                'Refreshing Env Variables, Calling Batch Script At scripts/refreshvars.cmd',
                metadata)
            write_verbose('Refreshing Environment Variables', metadata)
            refresh_environment_variables()
            end = timer()
            write_debug(
                f'Successfully Refreshed Environment Variables in {round(end - start)} seconds',
                metadata)

        write(f'Successfully Installed {packet.display_name}!',
              'bright_magenta', metadata)
        log_info(f'Successfully Installed {packet.display_name}!',
                 metadata.logfile)

        if metadata.reduce_package:

            os.remove(path)
            try:
                os.remove(Rf'{tempfile.gettempdir()}\downloadcache.pickle')
            except:
                pass

            log_info(
                'Successfully Cleaned Up Installer From Temporary Directory And DownloadCache',
                metadata.logfile)
            write('Successfully Cleaned Up Installer From Temp Directory...',
                  'green', metadata)

        write_verbose('Installation and setup completed.', metadata)
        log_info('Installation and setup completed.', metadata.logfile)
        write_debug(
            f'Terminated debugger at {strftime("%H:%M:%S")} on install::completion',
            metadata)
        log_info(
            f'Terminated debugger at {strftime("%H:%M:%S")} on install::completion',
            metadata.logfile)
        closeLog(metadata.logfile, 'Install')

        index += 1
    end = timer()