def run_subtask(self, stn, subtask): groups = subtask['groups'] for (group, tests) in sorted(groups.items()): for (i, test) in enumerate(tests, 1): cmd = test['cmd'] test_file = self.test_filepath(stn, group, i) if cmd == 'copy': self.copy(test['file'], test_file) elif cmd == 'echo': self.echo(test['args'], test_file) else: test['args'].insert(0, '%s-%s-%s' % (stn, group, i)) source = FilePath(self._directory, test['source']) if cmd == 'cpp': self.run_cpp_generator(source, test['args'], test_file) elif cmd in ['py', 'py2', 'py3']: self.run_py_generator(source, test['args'], test_file, cmd) elif cmd == 'java': self.run_java_generator(source, test['args'], test_file) elif cmd == 'run': bin_path = FilePath(self._directory, test['bin']) self.run_bin_generator(bin_path, test['args'], test_file) else: ui.fatal_error( 'unexpected command when running plan: %s ' % cmd)
def task_mode(args, optlist): if not args: ui.ocimatic_help(TASK_ACTIONS) (contest_dir, task_call) = filesystem.change_directory() if args[0] == 'new': new_task(args[1:]) elif args[0] in TASK_ACTIONS: contest = core.Contest(contest_dir) if ocimatic.config['task']: tasks = [contest.find_task(ocimatic.config['task'])] elif task_call: tasks = [contest.find_task(task_call.basename)] else: tasks = contest.tasks if not tasks: ui.show_message("Warning", "no tasks", ui.WARNING) action_name = args[0] args.pop(0) action = TASK_ACTIONS[action_name] kwargs = parseopt.kwargs_from_optlist(action, args, optlist) for task in tasks: getattr(task, action.get('method', action_name))(**kwargs) else: ui.fatal_error('Unknown action for task mode.') ui.ocimatic_help(TASK_ACTIONS)
def __init__(self, directory, task_directory, dataset_directory, filename='testplan.txt'): self._directory = directory self._testplan_path = FilePath(directory, filename) if not self._testplan_path.exists(): ui.fatal_error('No such file plan for creating dataset: "%s"' % self._testplan_path) self._task_directory = task_directory self._dataset_directory = dataset_directory self._cpp_compiler = CppCompiler() self._java_compiler = JavaCompiler()
def _check_args_len(args, action_args, optional_count): max_count = len(action_args) mandatory_count = max_count - optional_count if len(args) > max_count: ui.fatal_error( 'action expects no more than %d argument, %d were given' % (max_count, len(args))) if len(args) < mandatory_count: ui.fatal_error( 'action expects at least %d argument, %d were given' % (mandatory_count, len(args)))
def _check_args_len(args, action_args, optional_count): max_count = len(action_args) mandatory_count = max_count - optional_count if len(args) > max_count: ui.fatal_error( 'action expects no more than %d argument, %d were given' % (max_count, len(args))) if len(args) < mandatory_count: ui.fatal_error('action expects at least %d argument, %d were given' % (mandatory_count, len(args)))
def server_mode(args, optlist): if not args: ui.ocimatic_help(SERVER_ACTIONS) if args[0] in SERVER_ACTIONS: action_name = args[0] args.pop() action = SERVER_ACTIONS[action_name] kwargs = parseopt.kwargs_from_optlist(action, args, optlist) getattr(server, action.get('method', action_name))(**kwargs) else: ui.fatal_error('Unknown action for server mode.')
def dataset_mode(args, optlist): if not args: ui.ocimatic_help(DATASET_ACTIONS) if args[0] in DATASET_ACTIONS: action_name = args[0] args.pop() action = DATASET_ACTIONS[action_name] kwargs = parseopt.kwargs_from_optlist(action, args, optlist) dataset = core.Dataset(Directory.getcwd()) getattr(dataset, action.get('method', action_name))(**kwargs) else: ui.fatal_error('Unknown action for dataset mode.')
def contest_mode(args, optlist): if not args: ui.ocimatic_help(CONTEST_ACTIONS) if args[0] == "new": new_contest(args[1:], optlist) elif args[0] in CONTEST_ACTIONS: action_name = args[0] args.pop(0) action = CONTEST_ACTIONS[action_name] contest_dir = filesystem.change_directory()[0] contest = core.Contest(contest_dir) getattr(contest, action.get('method', action_name))() else: ui.fatal_error('Unknown action for contest mode.') ui.ocimatic_help(CONTEST_ACTIONS)
def main(): try: optlist, args = parseopt.gnu_getopt( sys.argv[1:], 'hvt:', ['help', 'task=', 'phase=', 'timeout='], TASK_ACTIONS, CONTEST_ACTIONS, DATASET_ACTIONS) except getopt.GetoptError as err: ui.fatal_error(str(err)) if not args: ui.ocimatic_help(TASK_ACTIONS) modes = { 'contest': (contest_mode, CONTEST_ACTIONS), 'task': (task_mode, TASK_ACTIONS), 'dataset': (dataset_mode, DATASET_ACTIONS), 'server': (server_mode, SERVER_ACTIONS), } # If no mode is provided we assume task if args[0] in modes: mode = args.pop(0) else: mode = 'task' # Process options for key, val in optlist.items(): if key == '-v': ocimatic.config['verbosity'] += 1 if key in ('--help', '-h'): ui.ocimatic_help(modes[mode][1]) elif key in ('--task', 't'): ocimatic.config['task'] = val elif key == '--timeout': ocimatic.config['timeout'] = float(val) # Select mode # try: if mode in modes: modes[mode][0](args, optlist) print() else: ui.fatal_error('Unknown mode.')
def main(): try: optlist, args = parseopt.gnu_getopt(sys.argv[1:], 'hvt:', ['help', 'task=', 'phase=', 'timeout='], TASK_ACTIONS, CONTEST_ACTIONS, DATASET_ACTIONS) except getopt.GetoptError as err: ui.fatal_error(str(err)) if not args: ui.ocimatic_help(TASK_ACTIONS) modes = { 'contest': (contest_mode, CONTEST_ACTIONS), 'task': (task_mode, TASK_ACTIONS), 'dataset': (dataset_mode, DATASET_ACTIONS), 'server': (server_mode, SERVER_ACTIONS), } # If no mode is provided we assume task if args[0] in modes: mode = args.pop(0) else: mode = 'task' # Process options for key, val in optlist.items(): if key == '-v': ocimatic.config['verbosity'] += 1 if key in ('--help', '-h'): ui.ocimatic_help(modes[mode][1]) elif key in ('--task', 't'): ocimatic.config['task'] = val elif key == '--timeout': ocimatic.config['timeout'] = float(val) # Select mode # try: if mode in modes: modes[mode][0](args, optlist) print() else: ui.fatal_error('Unknown mode.')
def gen_expected(self, sample=False, pattern=None): """Generate expected outputs files for dataset by running one of the correct solutions. """ if not self._correct: ui.fatal_error('No correct solution.') generator = None if pattern: for sol in self._correct: if pattern.lower() in sol.name.lower(): generator = sol break else: cpp = [ sol for sol in self._correct if isinstance(sol, CppSolution) ] if cpp: generator = cpp[0] if not generator: generator = self._correct[0] generator.gen_expected(self._dataset, sample=sample)
def change_directory(): """Changes directory to the contest root and returns the absolute path of the last directory before reaching the root, this correspond to the directory of the problem in which ocimatic was called. If the function reach system root the program exists. Returns: (Directory) If ocimatic was called inside a subdirectory of corresponding to a task this function returns the the problem directory. Otherwise it returns None. """ last_dir = None while not os.path.exists('.ocimatic_contest'): last_dir = os.getcwd() head, tail = last_dir, None while not tail: head, tail = os.path.split(head) os.chdir('..') if os.getcwd() == '/': ui.fatal_error('ocimatic was not called inside a contest.') task_call = None if not last_dir else Directory(last_dir) return (Directory(os.getcwd()), task_call)
def run_subtask(self, stn, subtask): groups = subtask['groups'] for (group, tests) in sorted(groups.items()): for (i, test) in enumerate(tests, 1): cmd = test['cmd'] test_file = self.test_filepath(stn, group, i) if cmd == 'copy': self.copy(test['file'], test_file) elif cmd == 'echo': self.echo(test['args'], test_file) else: test['args'].insert(0, '%s-%s-%s' % (stn, group, i)) source = FilePath(self._directory, test['source']) if cmd == 'cpp': self.run_cpp_generator(source, test['args'], test_file) elif cmd in ['py', 'py2', 'py3']: self.run_py_generator(source, test['args'], test_file, cmd) elif cmd == 'java': self.run_java_generator(source, test['args'], test_file) elif cmd == 'run': bin_path = FilePath(self._directory, test['bin']) self.run_bin_generator(bin_path, test['args'], test_file) else: ui.fatal_error('unexpected command when running plan: %s ' % cmd)
def new_task(args): if not args: ui.fatal_error('You have to specify a name for the task.') name = args[0] try: contest_dir = filesystem.change_directory()[0] if contest_dir.find(name): ui.fatal_error('Cannot create task in existing directory.') core.Contest(contest_dir).new_task(name) ui.show_message('Info', 'Task [%s] created' % name) except Exception as exc: # pylint: disable=broad-except ui.fatal_error('Couldn\'t create task: %s' % exc)
def new_contest(args, optlist): if not args: ui.fatal_error('You have to specify a name for the contest.') name = args[0] contest_config = {} if '--phase' in optlist: contest_config['phase'] = optlist['--phase'] try: cwd = Directory.getcwd() if cwd.find(name): ui.fatal_error("Couldn't create contest. Path already exists") contest_path = FilePath(cwd, name) core.Contest.create_layout(contest_path, contest_config) ui.show_message('Info', 'Contest [%s] created' % name) except Exception as exc: # pylint: disable=broad-except ui.fatal_error("Couldn't create contest: %s." % exc)
def parse_file(self): # pylint: disable=too-many-locals,too-many-branches """ Args: path (FilePath) """ cmds = {} st = 0 for (lineno, line) in enumerate(self._testplan_path.open('r').readlines(), 1): line = line.strip() subtask_header = re.compile(r'\s*\[\s*Subtask\s*(\d+)\s*(?:-\s*([^\]\s]+))?\s*\]\s*') cmd_line = re.compile(r'\s*([^;\s]+)\s*;\s*(\S+)(:?\s+(.*))?') comment = re.compile(r'\s*#.*') if not line: continue if not comment.fullmatch(line): header_match = subtask_header.fullmatch(line) cmd_match = cmd_line.fullmatch(line) if header_match: found_st = int(header_match.group(1)) validator = header_match.group(2) if st + 1 != found_st: ui.fatal_error('line %d: found subtask %d, but subtask %d was expected' % (lineno, found_st, st + 1)) st += 1 cmds[st] = {'validator': validator, 'groups': {}} elif cmd_match: if st == 0: ui.fatal_error( 'line %d: found command before declaring a subtask.' % lineno) group = cmd_match.group(1) cmd = cmd_match.group(2) args = (cmd_match.group(3) or '').split() if group not in cmds[st]['groups']: cmds[st]['groups'][group] = [] if cmd == 'copy': if len(args) > 2: ui.fatal_error( 'line %d: command copy expects exactly one argument.' % lineno) cmds[st]['groups'][group].append({ 'cmd': 'copy', 'file': args[0], }) elif cmd == 'echo': cmds[st]['groups'][group].append({'cmd': 'echo', 'args': args}) else: f = FilePath(self._directory, cmd) if f.ext in ['.cpp', '.java', '.py', '.py2', '.py3']: cmds[st]['groups'][group].append({ 'cmd': f.ext[1:], 'source': cmd, 'args': args }) else: cmds[st]['groups'][group].append({ 'cmd': 'run', 'bin': cmd, 'args': args }) else: ui.fatal_error('line %d: error while parsing line `%s`\n' % (lineno, line)) return (st, cmds)
def parse_file(self): # pylint: disable=too-many-locals,too-many-branches """ Args: path (FilePath) """ cmds = {} st = 0 for (lineno, line) in enumerate(self._testplan_path.open('r').readlines(), 1): line = line.strip() subtask_header = re.compile( r'\s*\[\s*Subtask\s*(\d+)\s*(?:-\s*([^\]\s]+))?\s*\]\s*') cmd_line = re.compile(r'\s*([^;\s]+)\s*;\s*(\S+)(:?\s+(.*))?') comment = re.compile(r'\s*#.*') if not line: continue if not comment.fullmatch(line): header_match = subtask_header.fullmatch(line) cmd_match = cmd_line.fullmatch(line) if header_match: found_st = int(header_match.group(1)) validator = header_match.group(2) if st + 1 != found_st: ui.fatal_error( 'line %d: found subtask %d, but subtask %d was expected' % (lineno, found_st, st + 1)) st += 1 cmds[st] = {'validator': validator, 'groups': {}} elif cmd_match: if st == 0: ui.fatal_error( 'line %d: found command before declaring a subtask.' % lineno) group = cmd_match.group(1) cmd = cmd_match.group(2) args = _parse_args(cmd_match.group(3) or '') if group not in cmds[st]['groups']: cmds[st]['groups'][group] = [] if cmd == 'copy': if len(args) > 2: ui.fatal_error( 'line %d: command copy expects exactly one argument.' % lineno) cmds[st]['groups'][group].append({ 'cmd': 'copy', 'file': args[0], }) elif cmd == 'echo': cmds[st]['groups'][group].append({ 'cmd': 'echo', 'args': args }) else: f = FilePath(self._directory, cmd) if f.ext in ['.cpp', '.java', '.py', '.py2', '.py3']: cmds[st]['groups'][group].append({ 'cmd': f.ext[1:], 'source': cmd, 'args': args }) else: cmds[st]['groups'][group].append({ 'cmd': 'run', 'bin': cmd, 'args': args }) else: ui.fatal_error('line %d: error while parsing line `%s`\n' % (lineno, line)) return (st, cmds)