Пример #1
0
    def handle_install_conflicts(self):
        """ Adds installable packages conflicts to install list """
        new_to_remove = []
        i = 0
        while i < len(self.to_install):
            conflicts = self.to_install[i].get_conflicts()
            for conflict in conflicts:
                if Pkg.check_state(conflict):
                    # find package conflict
                    try:
                        self.to_install[i].conflict_get_next[conflict]
                    except:
                        try:
                            self.to_install[i].conflict_get_next[conflict] = 0
                        except:
                            self.to_install[i].conflict_get_next = {}
                            self.to_install[i].conflict_get_next[conflict] = 0
                    pkg = Pkg.check_state(conflict, get_true_pkg=True, get_true_pkg_next=self.to_install[i].conflict_get_next[conflict])
                    self.to_install[i].conflict_get_next[conflict] += 1
                    a = 0
                    added = False
                    if type(pkg) == list:
                        while a < len(self.to_remove):
                            if self.to_remove[a].data['name'] == pkg[0]:
                                added = True
                            a += 1
                        if not added:
                            new_to_remove.append(Pkg.load_last(pkg[0]))
            i += 1

        if new_to_remove:
            self.remove(new_to_remove)
        
        self.handle_install_reverse_conflicts()
Пример #2
0
    def run(self):
        """ Run command """

        if not self.is_quiet():
            pr.p('Loading packages list...')
            pr.p('========================')

        loaded_packages = []

        for argument in self.arguments:
            arg_parts = argument.split('=')
            if len(arg_parts) == 1:
                # load last version as default
                pkg = Pkg.load_last(argument)
            elif len(arg_parts) == 2:
                # load specify version
                pkg = Pkg.load_version(arg_parts[0], arg_parts[1])
                if pkg == 1:
                    pkg = False
                elif pkg == 2:
                    self.message('package "' + arg_parts[0] +
                                 '" has not version "' + arg_parts[1] + '"' +
                                 ansi.reset,
                                 before=ansi.red)
                    continue
            else:
                # load specify version and specify arch
                pkg = Pkg.load_version(arg_parts[0], arg_parts[1],
                                       arg_parts[2])
                if pkg == 1:
                    pkg = False
                elif pkg == 2:
                    self.message('package "' + arg_parts[0] +
                                 '" has not version or arch "' + arg_parts[1] +
                                 ':' + arg_parts[2] + '"' + ansi.reset,
                                 before=ansi.red)
                    continue
            if pkg:
                loaded_packages.append(pkg)
            else:
                self.message('unknow package "' + argument + '"' + ansi.reset,
                             before=ansi.red)

        if not loaded_packages:
            return 1

        # download loaded packages
        is_any_success = False
        output_path = self.option_value('--output')
        for pkg in loaded_packages:
            if len(loaded_packages) > 1:
                tmp = self.download_once(pkg)
            else:
                tmp = self.download_once(pkg, output_path)
            if tmp:
                is_any_success = True

        if not is_any_success:
            return 1
Пример #3
0
    def run(self):
        """ Run test """
        self.assert_equals(
            self.run_command(
                'pkg',
                ['install', 'repository/test-repository/testpkgc-1.0.cati']),
            0)

        self.assert_equals(
            self.run_command(
                'pkg',
                ['install', 'repository/test-repository/testpkgc-2.0.cati']),
            0)

        self.assert_equals(self.run_command('forget', ['testpkgc']), 1)

        self.assert_equals(self.run_command('remove', ['testpkgc', '-y']), 0)

        self.assert_equals(self.run_command('forget', ['testpkgc']), 0)

        self.assert_true(not Pkg.load_last('testpkgc'))

        self.assert_equals(
            self.run_command(
                'pkg',
                ['install', 'repository/test-repository/testpkgc-1.0.cati']),
            0)

        self.assert_equals(
            self.run_command(
                'pkg',
                ['install', 'repository/test-repository/testpkgc-2.0.cati']),
            0)

        self.assert_equals(self.run_command('forget', ['testpkgc=1.0']), 0)

        self.assert_equals(self.run_command('forget', ['testpkgc=2.0']), 1)

        self.refresh_env()

        self.assert_equals(
            self.run_command(
                'pkg',
                ['install', 'repository/test-repository/testpkgc-2.0.cati']),
            0)

        self.assert_equals(
            self.run_command('pkg', [
                'install', 'repository/test-repository/testpkgc-2.0-alpha.cati'
            ]), 0)

        self.assert_equals(self.run_command('forget', ['testpkgc=2.0']), 0)

        self.assert_true(not os.path.isfile(
            self.env() + '/var/lib/cati/lists/testpkgc/2.0-all'))
        self.assert_true(
            os.path.isfile(self.env() +
                           '/var/lib/cati/lists/testpkgc/2.0-alpha-all'))
Пример #4
0
    def run(self):
        """ Run command """

        pr.p('Loading packages list...')
        pr.p('========================')

        loaded_packages = []

        for argument in self.arguments:
            arg_parts = argument.split('=')
            if len(arg_parts) == 1:
                # load last version as default
                pkg = Pkg.load_last(argument)
            else:
                # load specify version
                pkg = Pkg.load_version(arg_parts[0], arg_parts[1])
                if pkg == 1:
                    pkg = False
                elif pkg == 2:
                    self.message('package "' + arg_parts[0] + '" has not version "' + arg_parts[1] + '"' + ansi.reset, before=ansi.red)
                    continue
            if pkg:
                loaded_packages.append(pkg)
            else:
                self.message('unknow package "' + argument + '"' + ansi.reset, before=ansi.red)

        if not loaded_packages:
            return 1

        # show loaded packages
        for pkg in loaded_packages:
            if self.has_option('--versions'):
                versions_list = pkg.get_versions_list()
                pr.p(pkg.data['name'] + ':')
                for ver in versions_list:
                    pr.p(' ' + ver[0] + ':' + ver[1])
            else:
                PackageShower.show(pkg.data)
            if len(loaded_packages) > 1:
                pr.p('---------------------')
Пример #5
0
    def run(self):
        """ Run command """

        if not self.is_quiet():
            pr.p('Loading packages list...')
            pr.p('========================')

        loaded_packages = []

        for argument in self.arguments:
            pkg = Pkg.load_last(argument)
            if pkg:
                loaded_packages.append(pkg)
            else:
                self.message('unknow package "' + argument + '"' + ansi.reset, before=ansi.red)

        if not loaded_packages:
            return 1

        # show loaded packages
        for pkg in loaded_packages:
            # load reverse depends
            rdepends = pkg.get_reverse_depends()
            if not self.is_quiet():
                pr.p(pkg.data['name'] + ':')
            if not rdepends:
                if not self.is_quiet():
                    pr.p('  This package has not any reverse dependency')
            for item in rdepends:
                if not self.is_quiet():
                    pr.p('  ' + item.data['name'] + '=' + item.data['version'])
                else:
                    pr.p(item.data['name'] + '=' + item.data['version'])
            if len(loaded_packages) > 1:
                if not self.is_quiet():
                    pr.p('========================')
Пример #6
0
    def run(self):
        """ Run command """

        RootRequired.require_root_permission()

        pr.p('Loading packages list...')
        pr.p('========================')

        loaded_packages = []

        for argument in self.arguments:
            arg_parts = argument.split('=')
            if len(arg_parts) == 1:
                # load last version as default
                pkg = Pkg.load_last(argument)
            else:
                # load specify version
                pkg = Pkg.load_version(arg_parts[0], arg_parts[1])
                if pkg == 1:
                    pkg = False
                elif pkg == 2:
                    self.message('package "' + arg_parts[0] + '" has not version "' + arg_parts[1] + '"' + ansi.reset, before=ansi.red)
                    continue
                else:
                    pkg.only_specify_version = True
            if pkg:
                try:
                    pkg.only_specify_version
                except:
                    pkg.only_specify_version = False
                if pkg.installed():
                    if not pkg.only_specify_version:
                        self.message('package "' + argument + '" is installed. cannot forget installed packages' + ansi.reset, before=ansi.red)
                        continue
                    else:
                        if pkg.installed() == pkg.data['version']:
                            self.message('package ' + argument + ' (' + pkg.data['version'] + ') is installed. cannot forget installed packages' + ansi.reset, before=ansi.red)
                            continue
                loaded_packages.append(pkg)
            else:
                self.message('unknow package "' + argument + '"' + ansi.reset, before=ansi.red)

        if not loaded_packages:
            return 1

        # forget loaded packages
        for pkg in loaded_packages:
            if not pkg.only_specify_version:
                # forget all of package versions
                shutil.rmtree(Env.packages_lists('/' + pkg.data['name']))
                pr.p('Package ' + pkg.data['name'] + ' was forgoten successfully')
            else:
                files = glob.glob(Env.packages_lists('/' + pkg.data['name'] + '/' + pkg.data['version'] + '-*'))
                for f in files:
                    if not '-' in f[len(Env.packages_lists('/' + pkg.data['name'] + '/' + pkg.data['version'] + '-')):]:
                        os.remove(f)
                pr.p('Version ' + pkg.data['version'] + ' of package ' + pkg.data['name'] + ' was forgoten successfully')
            try:
                if len(os.listdir(Env.packages_lists('/' + pkg.data['name']))) <= 1:
                    shutil.rmtree(Env.packages_lists('/' + pkg.data['name']))
            except:
                pass

        ListUpdater.update_indexes({
            'cannot_read_file': self.empty_method_for_event,
            'invalid_json_data': self.empty_method_for_event,
        })
Пример #7
0
    def run(self):
        """ Run command """

        if self.has_option('--installed'):
            if not self.is_quiet():
                pr.p('Loading files list...')
                pr.p('=====================')
            all_of_installed_files_list = Pkg.get_all_installed_files_list()
            for item in all_of_installed_files_list:
                if self.is_quiet():
                    pr.p(item[2])
                else:
                    message = ''
                    if item[1] == 'd':
                        message = ' (directory)'
                    elif item[1] == 'cf':
                        message = ' (config file)'
                    elif item[1] == 'cd':
                        message = ' (config directory)'
                    pr.p(item[0] + ': ' + item[2] + message)
            return 0

        if not self.arguments:
            self.message('argument package names is required', True)
            return 1

        if not self.is_quiet():
            pr.p('Loading packages list...')
            pr.p('========================')

        loaded_packages = []

        for argument in self.arguments:
            arg_parts = argument.split('=')
            if len(arg_parts) == 1:
                # load last version as default
                pkg = Pkg.load_last(argument)
            else:
                # load specify version
                pkg = Pkg.load_version(arg_parts[0], arg_parts[1])
                if pkg == 1:
                    pkg = False
                elif pkg == 2:
                    self.message('package "' + arg_parts[0] +
                                 '" has not version "' + arg_parts[1] + '"' +
                                 ansi.reset,
                                 before=ansi.red)
                    continue
            if pkg:
                loaded_packages.append(pkg)
            else:
                self.message('unknow package "' + argument + '"' + ansi.reset,
                             before=ansi.red)

        if not loaded_packages:
            return 1

        # show files list of loaded packages
        for pkg in loaded_packages:
            try:
                files_list = pkg.data['files']
            except:
                files_list = []
            if not self.is_quiet():
                pr.p(pkg.data['name'] + ':')
                if not files_list:
                    pr.p(ansi.yellow + '  This package is empty' + ansi.reset)
                for item in files_list:
                    pr.p('  ' + item)
            else:
                for item in files_list:
                    pr.p(item)
            if len(loaded_packages) > 1:
                if not self.is_quiet():
                    pr.p('========================')
Пример #8
0
    def handle_install_depends(self):
        """ Adds installable packages depends to install list """
        new_to_install = []
        i = 0
        while i < len(self.to_install):
            depends = self.to_install[i].get_depends()
            if self.with_recommends:
                depends = [*depends, *self.to_install[i].get_recommends()]
            for depend in depends:
                if not Pkg.check_state(depend) and depend.strip()[0] != '@':
                    # find package depend
                    try:
                        self.to_install[i].depend_get_next[depend]
                    except:
                        try:
                            self.to_install[i].depend_get_next[depend] = 0
                        except:
                            self.to_install[i].depend_get_next = {}
                            self.to_install[i].depend_get_next[depend] = 0
                    pkg = Pkg.check_state(depend, get_false_pkg=True, get_false_pkg_next=self.to_install[i].depend_get_next[depend])
                    self.to_install[i].depend_get_next[depend] += 1
                    if len(pkg) == 1:
                        a = 0
                        added = False
                        while a < len(self.to_install):
                            if self.to_install[a].data['name'] == pkg[0]:
                                added = True
                            a += 1
                        if not added:
                            new_to_install.append(Pkg.load_last(pkg[0]))
                    elif len(pkg) == 3:
                        a = 0
                        added = False
                        while a < len(self.to_install):
                            if self.to_install[a].data['name'] == pkg[0]:
                                wanted_version = pkg[2]
                                installed_version = self.to_install[a].wanted_version
                                if pkg[1] == '=':
                                    if Pkg.compare_version(installed_version, wanted_version) == 0:
                                        added = True
                                elif pkg[1] == '>=':
                                    if Pkg.compare_version(installed_version, wanted_version) >= 0:
                                        added = True
                                elif pkg[1] == '<=':
                                    if Pkg.compare_version(installed_version, wanted_version) <= 0:
                                        added = True
                                elif pkg[1] == '>':
                                    if Pkg.compare_version(installed_version, wanted_version) == 1:
                                        added = True
                                elif pkg[1] == '<':
                                    if Pkg.compare_version(installed_version, wanted_version) == -1:
                                        added = True
                            a += 1
                        if not added:
                            pkg_obj = None
                            if pkg[1] == '=':
                                pkg_obj = Pkg.load_version(pkg[0], pkg[2])
                            elif pkg[1] == '>=' or pkg[1] == '>':
                                pkg_obj = Pkg.load_last(pkg[0])
                            elif pkg[1] == '<=':
                                pkg_obj = Pkg.load_version(pkg[0], pkg[2])
                            elif pkg[1] == '<':
                                pkg_obj = Pkg.load_last(pkg[0])
                                versions = pkg_obj.get_versions_list()
                                x = 0
                                while x < len(versions):
                                    if Pkg.compare_version(versions[x][0], pkg[0]) >= 0:
                                        versions.pop(x)
                                    x += 1
                                versions = [v[0] for v in versions]
                                wanted_ver = pkg.get_last_version(versions)
                                pkg_obj = Pkg.load_version(pkg[0], wanted_ver)
                            new_to_install.append(pkg_obj)
            i += 1

        if new_to_install:
            self.install(new_to_install)

        self.handle_install_reverse_depends()
Пример #9
0
    def run(self):
        """ Run test """
        repo1 = "file://" + os.getcwd() + '/repository name=test arch=all pkg=cati'
        repo2 = "file://" + os.getcwd() + '/repository name=test arch=i386 pkg=cati'

        self.assert_equals(self.run_command('repo', ['--scan', os.getcwd() + '/repository']), 0)

        self.assert_equals(self.run_command('repo', ['--add', repo1]), 0)
        self.assert_equals(self.run_command('repo', ['--add', repo2]), 0)
        self.assert_equals(self.run_command('update'), 0)

        self.assert_equals(self.run_command('install', ['testpkg10', '-y']), 0)

        self.assert_true(Pkg.is_installed('testpkg10'))
        self.assert_true(Pkg.is_installed('testpkg11'))

        self.assert_equals(self.run_command('install', ['testpkgb', '-y']), 0)

        self.assert_true(Pkg.is_installed('testpkgb'))
        self.assert_true(Pkg.is_installed('testpkgc'))
        self.assert_true(not Pkg.is_installed_manual('testpkgc'))

        self.assert_equals(self.run_command('install', ['testpkgz', '-y']), 0)

        self.assert_true(not Pkg.is_installed('testpkgb'))
        self.assert_true(not Pkg.is_installed('testpkgc'))
        self.assert_true(Pkg.is_installed('testpkgz'))

        self.assert_equals(self.run_command('install', ['testpkgb', '-y']), 0)

        self.assert_true(Pkg.is_installed('testpkgb'))
        self.assert_true(Pkg.is_installed('testpkgc'))
        self.assert_true(not Pkg.is_installed('testpkgz'))

        self.assert_equals(self.run_command('remove', ['testpkgb', 'testpkgc', '-y']), 0)

        # test upgrade
        self.assert_equals(self.run_command('install', ['testpkgc=1.0', '-y']), 0)

        testpkgc = Pkg.load_last('testpkgc')
        self.assert_equals(testpkgc.installed(), '1.0')

        self.assert_equals(self.run_command('upgrade', ['-y']), 0)

        testpkgc = Pkg.load_last('testpkgc')
        self.assert_equals(testpkgc.installed(), '2.0')

        # test recommends
        self.refresh_env()

        self.assert_equals(self.run_command('repo', ['--add', 'file://' + os.getcwd() + '/repository/test-repository arch=all,i386 name=test pkg=cati']), 0)
        self.assert_equals(self.run_command('update'), 0)
        self.assert_equals(self.run_command('install', ['testpkgr', '-y']), 0)
        self.assert_true(Pkg.is_installed('testpkgr'))
        self.assert_true(Pkg.is_installed('testpkgc'))
        self.assert_true(not Pkg.is_installed('testpkg11'))

        self.refresh_env()

        self.assert_equals(self.run_command('repo', ['--add', 'file://' + os.getcwd() + '/repository/test-repository arch=all,i386 name=test pkg=cati']), 0)
        self.assert_equals(self.run_command('update'), 0)
        self.assert_equals(self.run_command('install', ['testpkgr', '-y', '--with-recommends']), 0)
        self.assert_true(Pkg.is_installed('testpkgr'))
        self.assert_true(Pkg.is_installed('testpkgc'))
        self.assert_true(Pkg.is_installed('testpkg11'))
Пример #10
0
    def run(self):
        """ Run command """

        require_root_permission()

        # check transactions state before run new transactions
        pr.p('Checking transactions state...')
        state_list = BaseTransaction.state_list(
        )  # get list of undoned transactions
        if state_list:
            # the list is not empty
            StateContentShower.show(state_list)
            return 1

        pr.p('Loading packages list...')
        pr.p('==============================')
        # load list of packages
        packages = []
        for arg in self.arguments:
            pkg = Pkg.load_last(arg)
            if pkg == False:
                self.message('unknow package "' + arg + '"' + ansi.reset,
                             before=ansi.red)
            else:
                if pkg.installed():
                    packages.append(pkg)
                else:
                    self.message('package "' + pkg.data['name'] +
                                 '" is not installed' + ansi.reset,
                                 before=ansi.red)

        # start removing loaded packages
        calc = Calculator()
        calc.remove(packages)

        # show transactions
        TransactionShower.show(calc)

        essential_packages = []
        for pkg in calc.to_remove:
            try:
                if pkg.data['essential']:
                    essential_packages.append(pkg)
            except:
                pass

        if not self.has_option('--force') and not self.has_option('-f'):
            for pkg in essential_packages:
                pr.p(
                    ansi.red + 'Package "' + pkg.data['name'] +
                    '" is a essential package and cannot be remove. use --force|-f option to force remove them'
                    + ansi.reset)
            if essential_packages:
                return 1

        if not calc.has_any_thing():
            return

        # check user confirmation
        if not self.has_option('-y') and not self.has_option('--yes'):
            pr.p('Do you want to continue? [Y/n] ', end='')
            answer = input()
            if not (answer == 'y' or answer == 'Y' or answer == ''):
                pr.p(ansi.yellow + 'Abort.' + ansi.reset)
                pr.exit(1)

        # add packages to state
        BaseTransaction.add_to_state(calc)

        packages_to_remove_names_and_versions = [
            pkg.data['name'] + '@' + pkg.data['version']
            for pkg in calc.to_remove
        ]

        # run transactions
        for pkg in calc.to_remove:
            Remove.run(pkg, {
                'removing_package': self.removing_package_event,
                'package_remove_finished': self.package_remove_finished_event,
                'dir_is_not_empty': self.dir_is_not_empty_event,
            },
                       self.has_option('--conffiles'),
                       run_scripts=(not self.has_option('--without-scripts')))
            BaseTransaction.pop_state()

        BaseTransaction.run_any_scripts(
            ['remove', packages_to_remove_names_and_versions],
            events={
                'start_run_script': self.start_run_any_script_event,
            })

        BaseTransaction.finish_all_state()
Пример #11
0
    def run(self):
        """ Run command """

        RootRequired.require_root_permission()

        pr.p('Loading packages list...')
        pr.p('========================')

        loaded_packages = []

        for argument in self.arguments:
            arg_parts = argument.split('=')
            if len(arg_parts) == 1:
                # load last version as default
                pkg = Pkg.load_last(argument)
            else:
                # load specify version
                pkg = Pkg.load_version(arg_parts[0], arg_parts[1])
                if pkg == 1:
                    pkg = False
                elif pkg == 2:
                    self.message('package "' + arg_parts[0] +
                                 '" has not version "' + arg_parts[1] + '"' +
                                 ansi.reset,
                                 before=ansi.red)
                    continue
            if pkg:
                loaded_packages.append(pkg)
            else:
                self.message('unknow package "' + argument + '"' + ansi.reset,
                             before=ansi.red)

        # remove local packages from list
        new_loaded_packages = []
        for pkg in loaded_packages:
            try:
                file_path = pkg.data['file_path']
                new_loaded_packages.append(pkg)
            except:
                self.message('package "' + pkg.data['name'] +
                             '" is a local package',
                             is_error=True)
        loaded_packages = new_loaded_packages

        if not loaded_packages:
            return 1

        # calculate transactions
        pr.p('Calculating transactions...')
        calc = Calculator(with_recommends=self.has_option('--with-recommends'))
        i = 0
        while i < len(loaded_packages):
            loaded_packages[i].is_manual = True
            i += 1
        try:
            calc.install(list(reversed(loaded_packages)))
        except:
            pr.e(ansi.red + 'ERROR: There is some dependnecy problems.' +
                 ansi.reset)
            return 1

        # handle reinstallable packages
        i = 0
        while i < len(calc.to_install):
            if calc.to_install[i].installed():
                if calc.to_install[i].installed(
                ) == calc.to_install[i].wanted_version:
                    if not self.has_option('--reinstall'):
                        pr.p(
                            'Package ' + calc.to_install[i].data['name'] +
                            '=' + calc.to_install[i].wanted_version +
                            ' is currently installed. use --reinstall option to re-install it.'
                        )
                        if calc.to_install[i].is_manual:
                            try:
                                pr.p(
                                    'Setting it as manual installed package...'
                                )
                                manual_f = open(
                                    Env.installed_lists('/' +
                                                        pkg.data['name'] +
                                                        '/manual'), 'w')
                                manual_f.write('')
                                manual_f.close()
                            except:
                                pass
                        calc.to_install.pop(i)
            i += 1

        # check transactions exists
        if not calc.has_any_thing():
            pr.p('Nothing to do.')
            return 0

        # show transaction
        TransactionShower.show(calc)

        if not self.has_option('-y') or self.has_option('--yes'):
            pr.p('Do you want to continue? [Y/n] ', end='')
            answer = input()
            if answer == 'y' or answer == 'Y' or answer == '':
                pass
            else:
                pr.p('Abort.')
                return 1

        # start download packages
        pr.p('Downloading packages...')
        downloaed_paths = []
        for pkg in calc.to_install:
            download_path = Env.cache_dir('/archives/' + pkg.data['name'] +
                                          '-' + pkg.wanted_version + '-' +
                                          pkg.data['arch'])
            if os.path.isfile(download_path):
                file_sha256 = calc_file_sha256(download_path)
                file_md5 = calc_file_md5(download_path)
                valid_sha256 = None
                valid_md5 = None
                try:
                    valid_sha256 = pkg.data['file_sha256']
                except:
                    valid_sha256 = file_sha256
                try:
                    valid_md5 = pkg.data['file_md5']
                except:
                    valid_md5 = file_md5
                if file_md5 != valid_md5 or file_sha256 != valid_sha256:
                    # file is corrupt and should be download again
                    os.remove(download_path)
                else:
                    pr.p('Using Cache for ' + pkg.data['name'] + ':' +
                         pkg.data['version'] + ':' + pkg.data['arch'] + '...')
                    downloaed_paths.append(download_path)
                    continue
            download_cmd = DownloadCommand()
            i = 0
            res = 1
            tmp = True
            while tmp:
                if i > 5:
                    pr.e(ansi.red + 'Failed to download packages' + ansi.reset)
                    return res
                pr.p('Downloading ' + pkg.data['name'] + ':' +
                     pkg.data['version'] + ':' + pkg.data['arch'] + '...')
                res = download_cmd.handle(
                    ArgParser.parse([
                        'cati', 'download', '-q',
                        pkg.data['name'] + '=' + pkg.wanted_version,
                        '--output=' + download_path
                    ]))
                if res == 1 or res == None:
                    tmp = False
                i += 1
            downloaed_paths.append(download_path)
        pr.p('Download completed.')

        # check --download-only option
        if self.has_option('--download-only'):
            return 0

        cati_pkg_cmd_options = []
        remove_cmd_options = []
        if self.has_option('--keep-conffiles'):
            cati_pkg_cmd_options.append('--keep-conffiles')
        if self.has_option('--target'):
            cati_pkg_cmd_options.append('--target')
        if self.has_option('--without-scripts'):
            cati_pkg_cmd_options.append('--without-scripts')
            remove_cmd_options.append('--without-scripts')

        # remove packages
        if calc.to_remove:
            pr.p('Removing packages...')
            package_names = [pkg.data['name'] for pkg in calc.to_remove]
            remove_cmd = RemoveCommand()
            res = remove_cmd.handle(
                ArgParser.parse([
                    'cati', 'remove', *package_names, '-y', *remove_cmd_options
                ]))
            if res != 0 and res != None:
                pr.e(ansi.red + 'Failed to remove packages' + ansi.reset)
                return res

        # install packages
        pr.p('Installing packages...')
        pkg_cmd = PkgCommand()
        res = pkg_cmd.handle(
            ArgParser.parse([
                'cati', 'pkg', 'install', *downloaed_paths,
                *cati_pkg_cmd_options
            ]))
        if res != 0 and res != None:
            self.set_manual_installs(calc.to_install)
            pr.e(ansi.red + 'Failed to install packages' + ansi.reset)
            return res

        self.set_manual_installs(calc.to_install)

        pr.p(ansi.green + 'Done.' + ansi.reset)