예제 #1
0
def handle(argv: list):
    """
    handle cli
    gets argv and runs entered command as subcommand (if not subcommand inserted, runs help command as default)

    Args:
        argv: the program arguments as list
    """
    # parse inserted arguments
    parsed_args = ArgParser.parse(argv)

    # find called subcommand by args
    if len(parsed_args['arguments']) == 0:
        # no subcommand called
        # call help command as default
        parsed_args['arguments'].append('help')

    try:
        command = commands[parsed_args['arguments'][0]]
    except:
        pr.e(sys.argv[0] + ': unknow command "' + parsed_args['arguments'][0] +
             '"')
        pr.exit(1)

    cmdobj = command()
    sys.exit(cmdobj.handle(parsed_args))
예제 #2
0
파일: cati.py 프로젝트: parsampsh/cati
def cati_installation_is_corrupt(filepath: str, filetype: str):
    """
    Will run when cati installation is corrupt
    shows error to user
    """
    pr.e(
        ansi.red +
        'Cati installation is corrupt. to repair it, just run cati with root access'
        + ansi.reset)
    pr.exit(1)
예제 #3
0
def require_root_permission(is_cli=True, die_action=None):
    """
    checks root premission.

    Args:
        is_cli (bool): if is True, when user have not root permission,
            error will print in terminal. but if is False,
            the `die_action` will run as a function.
            (will be disable in testing environment)
        die_action (callable): the function will be run when `is_cli` is False
    """

    # if program is in testing mode don't check permission
    if is_testing:
        return

    if os.getuid() == 0:
        return

    # check write and read access for needed files
    files_to_check = [
        Env.packages_lists(),
        Env.installed_lists(),
        Env.state_file(),
        Env.unremoved_conffiles(),
        Env.security_blacklist(),
        Env.any_scripts(),
        Env.repos_config(),
        Env.repos_config_dir(),
        Env.cache_dir(),
        Env.allowed_archs(),
    ]
    for f in files_to_check:
        if not os.access(f, os.W_OK) or not os.access(f, os.R_OK):
            if is_cli:
                pr.e(ansi.red + sys.argv[0] + ': permission is denied' +
                     ansi.reset)
                pr.exit(1)
                return
            else:
                die_action()
                return
예제 #4
0
    def validate(self, args: dict):
        """
        Validate inserted arguments in command config frame
        loads command config from `config` function output
        next checks arguments and compares them with command config
        then, if an unknow option is inserted or more/less argument inserted,
        shows error to user.

        Args:
            args: command arguments as doctonary
                  example:
                  {'arguments': list, 'options': dict{ '--foo': 'value', '-x': None } }
        """

        # load command config
        command_config = self.config()
        # add --help option as default
        command_config['options']['--help'] = [False, False]

        self.name = command_config['name']
        self.cati_exec = sys.argv[0]

        # pop first argument (command self name)
        args['arguments'].pop(0)

        # check knowed options and value of them
        for k in args['options']:
            try:
                option_config = command_config['options'][k]
            except:
                self.message('unknow option "' + k + '"')
                return pr.exit(1)

            if option_config[1] == True:
                if args['options'][k] == None:
                    self.message('option ' + k + ' requires value')
                    return pr.exit(1)

        # check required options
        for option in command_config['options']:
            if command_config['options'][option][0] == True:
                try:
                    args['options'][option]
                except:
                    self.message('option ' + option + ' is required')
                    return pr.exit(1)

        self.args = args
        self.arguments = self.args['arguments']

        # check arguments count
        if not self.has_option('--help'):
            if command_config['max_args_count'] != None:
                if len(args['arguments']) > command_config['max_args_count']:
                    self.message('this command requires less than ' +
                                 str(command_config['max_args_count'] + 1) +
                                 ' arguments')
                    return pr.exit(1)

            if command_config['min_args_count'] != None:
                if len(args['arguments']) < command_config['min_args_count']:
                    self.message('this command requires more than ' +
                                 str(command_config['min_args_count'] - 1) +
                                 ' arguments')
                    return pr.exit(1)
예제 #5
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()