def build_lyx(target, source, env): '''Compile a pdf from a LyX file This function is a SCons builder that compiles a .lyx file as a pdf and places it at the path specified by target. Parameters ---------- target: string or list The target of the SCons command. This should be the path of the pdf that the builder is instructed to compile. source: string or list The source of the SCons command. This should be the .lyx file that the function will compile as a PDF. env: SCons construction environment, see SCons user guide 7.2 ''' # Prelims source = misc.make_list_if_string(source) target = misc.make_list_if_string(target) source_file = str(source[0]) misc.check_code_extension(source_file, '.lyx') # Set up target file and log file newpdf = source_file[:-4] + '.pdf' target_file = str(target[0]) target_dir = misc.get_directory(target_file) start_time = misc.current_time() misc.check_code_extension(source_file, 'lyx') newpdf = source_file.replace('.lyx', '.pdf') try: log_ext = '_%s' % env['log_ext'] except KeyError: log_ext = '' log_file = os.path.join(target_dir, ('sconscript%s.log' % log_ext)) # System call try: command = 'lyx -e pdf2 %s > %s' % (source_file, log_file) subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) # Move rendered pdf to the target shutil.move(newpdf, target_file) except subprocess.CalledProcessError: message = misc.command_error_msg("lyx", command) raise ExecCallError(message) # Close log end_time = misc.current_time() log_timestamp(start_time, end_time, log_file) return None
def build_stata(target, source, env): '''Build targets with a Stata command This function executes a Stata script to build objects specified by target using the objects specified by source. Parameters ---------- target: string or list The target(s) of the SCons command. source: string or list The source(s) of the SCons command. The first source specified should be the Stata .do script that the builder is intended to execute. env: SCons construction environment, see SCons user guide 7.2 ''' # Prelims source = misc.make_list_if_string(source) target = misc.make_list_if_string(target) start_time = misc.current_time() # Set up source file and the original location of the log source_file = str(source[0]) misc.check_code_extension(source_file, '.do') loc_log = os.path.basename(source_file).replace('.do', '.log') # Set up log file destination target_file = str(target[0]) target_dir = misc.get_directory(target_file) try: log_ext = '_%s' % env['log_ext'] except KeyError: log_ext = '' log_file = os.path.join(target_dir, ('sconscript%s.log' % log_ext)) # Set up command line arguments cl_arg = misc.command_line_args(env) executable = misc.get_stata_executable(env) command_skeleton = misc.get_stata_command(executable) try: command = command_skeleton % (source_file, cl_arg) subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) except subprocess.CalledProcessError: message = misc.command_error_msg("Stata", command) raise ExecCallError(message) shutil.move(loc_log, log_file) end_time = misc.current_time() log_timestamp(start_time, end_time, log_file) return None
def build_r(target, source, env): '''Build SCons targets using an R script This function executes an R script to build objects specified by target using the objects specified by source. Parameters ---------- target: string or list The target(s) of the SCons command. source: string or list The source(s) of the SCons command. The first source specified should be the R script that the builder is intended to execute. env: SCons construction environment, see SCons user guide 7.2 ''' # Prelims source = misc.make_list_if_string(source) target = misc.make_list_if_string(target) source_file = str(source[0]) target_file = str(target[0]) target_dir = misc.get_directory(target_file) start_time = misc.current_time() misc.check_code_extension(source_file, 'r') try: log_ext = '_%s' % env['log_ext'] except KeyError: log_ext = '' log_file = os.path.join(target_dir, ('sconscript%s.log' % log_ext)) cl_arg = misc.command_line_args(env) if cl_arg != '': if misc.is_unix(): # R has platform-specific cl_arg syntax cl_arg = "'--args %s'" % cl_arg else: cl_arg = "\"--args %s\"" % cl_arg # System call try: command = 'R CMD BATCH --no-save %s %s %s' % (cl_arg, source_file, log_file) subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) except subprocess.CalledProcessError: message = misc.command_error_msg("R", command) raise ExecCallError(message) end_time = misc.current_time() log_timestamp(start_time, end_time, log_file) return None
def raise_system_call_exception(self, command='', traceback=''): ''' Create and raise an informative error message from failed system call. ''' if not command: command = self.system_call traceback = str(traceback) traceback = '%s%s' % ('\n' * bool(traceback), traceback) message = '%s did not run successfully. ' \ 'Please check that the executable, source, and target files are correctly specified. ' \ 'Check %s and sconstruct.log for errors. ' \ '\nCommand tried: %s%s' % (self.name, self.log_file, command, traceback) raise ExecCallError(message) return None
def build_python(target, source, env): '''Build SCons targets using a Python script This function executes a Python script to build objects specified by target using the objects specified by source. Parameters ---------- target: string or list The target(s) of the SCons command. source: string or list The source(s) of the SCons command. The first source specified should be the Python script that the builder is intended to execute. env: SCons construction environment, see SCons user guide 7.2 ''' # Prelims source = misc.make_list_if_string(source) target = misc.make_list_if_string(target) source_file = str(source[0]) target_file = str(target[0]) target_dir = misc.get_directory(target_file) start_time = misc.current_time() misc.check_code_extension(source_file, '.py') try: log_ext = '_%s' % env['log_ext'] except KeyError: log_ext = '' log_file = os.path.join(target_dir, ('sconscript%s.log' % log_ext)) cl_arg = misc.command_line_args(env) # System call try: command = 'python %s %s > %s' % (source_file, cl_arg, log_file) subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) except subprocess.CalledProcessError as ex: message = misc.command_error_msg("Python", command) raise ExecCallError('%s\n%s' % (message, ex.output)) # Close log end_time = misc.current_time() log_timestamp(start_time, end_time, log_file) return None
def build_matlab(target, source, env): '''Build targets with a MATLAB command This function executes a MATLAB function to build objects specified by target using the objects specified by source. It requires MATLAB to be callable from the command line via `matlab`. Accessing command line arguments from within matlab is possible via the `command_line_arg = getenv('CL_ARG')`. Parameters ---------- target: string or list The target(s) of the SCons command. source: string or list The source(s) of the SCons command. The first source specified should be the MATLAB .M script that the builder is intended to execute. env: SCons construction environment, see SCons user guide 7.2 ''' if misc.is_unix(): options = '-nosplash -nodesktop' elif sys.platform == 'win32': options = '-nosplash -minimize -wait' else: raise PrerequisiteError("Unsupported OS") source = misc.make_list_if_string(source) target = misc.make_list_if_string(target) source_file = str(source[0]) target_file = str(target[0]) target_dir = misc.get_directory(target_file) start_time = misc.current_time() misc.check_code_extension(source_file, '.m') try: log_ext = '_%s' % env['log_ext'] except KeyError: log_ext = '' log_file = os.path.join(target_dir, ('sconscript%s.log' % log_ext)) # Set up command line arguments cl_arg = misc.command_line_args(env) os.environ['CL_ARG'] = cl_arg # Run MATLAB on source file shutil.copy(source_file, 'source.m') try: command = 'matlab %s -r source > %s' % (options, log_file) subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) except subprocess.CalledProcessError: message = misc.command_error_msg("Matlab", command) raise ExecCallError(message) os.remove('source.m') end_time = misc.current_time() log_timestamp(start_time, end_time, log_file) return None
def build_tables(target, source, env): '''Build a SCons target by filling a table This function uses the tablefill function from gslab_fill to produced a filled table from (i) an empty table in a LyX/Tex file and (ii) text files containing data to be used in filling the table. Parameters ---------- target: string or list The target(s) of the SCons command. source: string or list The source(s) of the SCons command. The first source specified should be the LyX/Tex file specifying the table format. The subsequent sources should be the text files containing the data with which the tables are to be filled. env: SCons construction environment, see SCons user guide 7.2 ''' # Prelims source = misc.make_list_if_string(source) target = misc.make_list_if_string(target) start_time = misc.current_time() # Set up source file (table format) source_file = str(source[0]) misc.check_code_extension(source_file, ['.lyx', '.tex']) # Set up input string (list of data tables) input_string = ' '.join([str(i) for i in source[1:]]) # Set up target file (filled table) target_file = str(target[0]) target_dir = misc.get_directory(target_file) misc.check_code_extension(target_file, ['.lyx', '.tex']) try: log_ext = '_%s' % env['log_ext'] except KeyError: log_ext = '' log_file = os.path.join(target_dir, ('sconscript%s.log' % log_ext)) # Command call output = tablefill(input=input_string, template=source_file, output=target_file) with open(log_file, 'wb') as f: f.write(output) f.write("\n\n") # Close log if "traceback" in str.lower(output): # if tablefill.py returns an error command = """tablefill(input = %s, template = %s, output = %s)""" % (input_string, source_file, target_file) message = misc.command_error_msg("tablefill.py", command) raise ExecCallError(message) end_time = misc.current_time() log_timestamp(start_time, end_time, log_file) return None