From 15e5909fb03f718bedb1c737b24e2323d68a0c6c Mon Sep 17 00:00:00 2001 From: Leix_b Date: Fri, 6 Oct 2017 11:36:23 +0200 Subject: [PATCH] Close #12 --- README.rst | 11 +++++--- jutge_cli/commands/test.py | 52 ++++++++++++++++++++++-------------- jutge_cli/commands/upload.py | 23 +++++++++++++--- jutge_cli/jutge.py | 3 ++- setup.py | 2 +- zsh_completion/_jutge | 1 + 6 files changed, 64 insertions(+), 28 deletions(-) diff --git a/README.rst b/README.rst index ffa1e95..8e0aa3b 100644 --- a/README.rst +++ b/README.rst @@ -286,9 +286,14 @@ but you can specify another one through the ``--compiler`` flag. jutge upload P00001_ca_prog.cpp --compiler 'G++' If the flag ``--problem-set`` the command will upload all problems from the -specified set. (Keep in mind that jutge.org limits the number of submissions -to 20 per hour so it is discouraged to use this flag with large problem -sets) +specified set found in the current working directory or in the set folder in +the current working directory. (Keep in mind that jutge.org limits the number +of submissions to 20 per hour so it is discouraged to use this flag with large +problem sets) + +By default upload will test all problems against public test cases in the +database (not including custom ones). You can skip those checks with the flag +``--skip-check`` Check-submissions (check) ~~~~~~~~~~~~~~~~~ diff --git a/jutge_cli/commands/test.py b/jutge_cli/commands/test.py index d0c9586..9f45c86 100755 --- a/jutge_cli/commands/test.py +++ b/jutge_cli/commands/test.py @@ -40,35 +40,46 @@ class ansi: class test: def __init__(self,args): - if args.prog.name.endswith('.cpp') or args.prog.name.endswith('.cc'): + self.args = args + if args.SUBCOMMAND == 'test': + self.quiet = self.args.quiet + exit(self.eval(args)) + self.quiet = True - prog_name = '.'.join(args.prog.name.split('.')[:-1]) + '.x' + def eval(self): + + if isinstance(self.args.prog,str): source_file = self.args.prog + else : source_file = self.args.prog.name + + if source_file.endswith('.cpp') or source_file.endswith('.cc'): + + prog_name = '.'.join(source_file.split('.')[:-1]) + '.x' log.debug('Compiling to {}'.format(prog_name)) - p = Popen(['g++', '-std=c++11', '-g', args.prog.name, '-o', prog_name]) + p = Popen(['g++', '-std=c++11', '-g', source_file, '-o', prog_name]) return_code = p.wait() if return_code: log.error('Compilation returned {}, aborting'.format(return_code)) exit(return_code) - else: prog_name = args.prog.name + else: prog_name = source_file if prog_name[0]!='.' and prog_name[0]!='/': prog_name = './' + prog_name cont,cor = 0,0 - code = get_code.get_code(args).code - download.download(args) + code = get_code.get_code(self.args).code + download.download(self.args) - for sample_inp in sorted(glob('{}/{}/*.{}'.format(expanduser(args.database),code,args.inp_suffix))): - sample_cor = ''.join(sample_inp.split('.')[:-1]) + '.' + args.cor_suffix + for sample_inp in sorted(glob('{}/{}/*.{}'.format(expanduser(self.args.database),code,self.args.inp_suffix))): + sample_cor = ''.join(sample_inp.split('.')[:-1]) + '.' + self.args.cor_suffix test_input = open(sample_inp,'r') test_output = NamedTemporaryFile() if basename(sample_inp).startswith('custom'): - if args.no_custom: continue + if self.args.no_custom: continue is_custom = '(custom)' else: is_custom = '' @@ -80,27 +91,28 @@ def __init__(self,args): if return_code: log.warning("Program returned {}".format(return_code)) test_input.seek(0) - if not args.quiet: print(ansi.OKBLUE, ansi.BOLD, '*** Input {} {}'.format(cont,is_custom), ansi.ENDC, ansi.HEADER) - if not args.quiet: print(test_input.read(), ansi.ENDC) + if not self.quiet: print(ansi.OKBLUE, ansi.BOLD, '*** Input {} {}'.format(cont,is_custom), ansi.ENDC, ansi.HEADER) + if not self.quiet: print(test_input.read(), ansi.ENDC) test_input.close() try: - out = check_output([args.diff_prog]+args.diff_flags.split(',')+[test_output.name,sample_cor]) - if not args.quiet: print(ansi.OKGREEN, ansi.BOLD, '*** The results match :)', ansi.ENDC, ansi.ENDC) - if not args.quiet: print(out.decode('UTF-8')) + out = check_output([self.args.diff_prog]+self.args.diff_flags.split(',')+[test_output.name,sample_cor]) + if not self.quiet: print(ansi.OKGREEN, ansi.BOLD, '*** The results match :)', ansi.ENDC, ansi.ENDC) + if not self.quiet: print(out.decode('UTF-8')) cor+=1 except CalledProcessError as err: # Thrown if files doesn't match - if not args.quiet: print(ansi.FAIL, ansi.BOLD, '*** The results do NOT match :(', ansi.ENDC, ansi.ENDC) - if not args.quiet: print(err.output.decode('UTF-8')) + if not self.quiet: print(ansi.FAIL, ansi.BOLD, '*** The results do NOT match :(', ansi.ENDC, ansi.ENDC) + if not self.quiet: print(err.output.decode('UTF-8')) test_output.close() if cont == 0: - if not args.quiet: print("Program has no test-cases yet") + if not self.quiet: print("Program has no test-cases yet") elif cont == cor: - if not args.quiet: print(ansi.OKGREEN, ansi.BOLD, '*** ({}/{}) ALL OK :)'.format(cor,cont), ansi.ENDC, ansi.ENDC) + if not self.quiet: print(ansi.OKGREEN, ansi.BOLD, '*** ({}/{}) ALL OK :)'.format(cor,cont), ansi.ENDC, ansi.ENDC) else: - if not args.quiet: print(ansi.FAIL, ansi.BOLD, '*** ({}/{}) :('.format(cor,cont), ansi.ENDC, ansi.ENDC) - exit(cont-cor) + if not self.quiet: print(ansi.FAIL, ansi.BOLD, '*** ({}/{}) :('.format(cor,cont), ansi.ENDC, ansi.ENDC) + + return cont-cor diff --git a/jutge_cli/commands/upload.py b/jutge_cli/commands/upload.py index ccb6a4f..a3c47d0 100755 --- a/jutge_cli/commands/upload.py +++ b/jutge_cli/commands/upload.py @@ -29,12 +29,22 @@ from . import get_code from . import defaults +from . import test class upload: def __init__(self,args): + config = defaults.config() + if not args.skip_test: + # Add defaults for test + args_dict = vars(args) + args_dict['inp_suffix'] = config.param['inp-suffix'] + args_dict['cor_suffix'] = config.param['cor-suffix'] + args_dict['diff_flags'] = config.param['diff-flags'] + args_dict['diff_prog'] = config.param['diff-prog'] + args_dict['no_custom'] = True if args.problem_set: set_name = args.prog - try: problems = defaults.config().subfolders[set_name] + try: problems = config.subfolders[set_name] except KeyError: log.error('Problem set not found') exit(20) @@ -47,7 +57,7 @@ def __init__(self,args): for subcode in problems: - files = glob('{}*'.format(subcode)) + glob('{}/{}*'.format(set_name,subcode)) + files = glob('{}*[!.x]'.format(subcode)) + glob('{}/{}*[!.x]'.format(set_name,subcode)) if len(files) > 0: submit_queue += [files[0]] else: log.warning(subcode + ' solution not found, skiping ...') @@ -71,13 +81,20 @@ def __init__(self,args): sleep(args.delay/1000.0) - else: upload(args) + else: self.upload(args) def upload(self,args): if args.no_download: log.error('Remove --no-download flag to upload') exit(4) + if not args.skip_test: + veredict = test.test(args).eval() + if veredict != 0: + log.error('Problem did not pass public tests, aborting... (use --skip-test to upload anyways)') + exit(veredict) + else: log.debug('Public tests passed') + code = get_code.get_code(args).code log.debug(code) diff --git a/jutge_cli/jutge.py b/jutge_cli/jutge.py index 9807953..61b5502 100755 --- a/jutge_cli/jutge.py +++ b/jutge_cli/jutge.py @@ -35,7 +35,7 @@ def run_login(args): login.login(args) import argparse -jutge_cli_version = '1.5.3' +jutge_cli_version = '1.5.4' config = defaults.config().param @@ -111,6 +111,7 @@ def run_login(args): login.login(args) parser_upload.add_argument('--problem-set',action='store_true', help='upload all files in problem set', default=False) parser_upload.add_argument('--delay', type=int, metavar='milliseconds', help='delay between jutge.org upload requests', default=100) parser_upload.add_argument('-f','--folder', type=str, help='folder where programs are archived',default=config['folder']) +parser_upload.add_argument('--skip-test', action='store_true', help='do not test public cases before uploading', default=False) parser_upload.set_defaults(func=run_upload) parser_update = subparsers.add_parser('update', aliases=['import'], help='add programs to archived folder from zip file', parents=[parent_parser]) diff --git a/setup.py b/setup.py index 37a0504..0a5df7f 100755 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ setup( name='jutge_cli', - version='1.5.3', + version='1.5.4', description='CLI to manage jutge.org problems', long_description=long_description, diff --git a/zsh_completion/_jutge b/zsh_completion/_jutge index 983f9cc..2fb0674 100644 --- a/zsh_completion/_jutge +++ b/zsh_completion/_jutge @@ -165,6 +165,7 @@ case $state in + '(code)' {-c,--code}'[problem code]:code' \ '--compiler[compiler id to use]:compiler:_jutge_compilers'\ '--problem-set[upload all files from a problem set]'\ + '--skip-check[do not test against public test cases before upload]'\ '--delay[delay between jutge-org upload requests]:milliseconds' ;; (update|import)