def check_stata(sf): import gslab_scons.misc as misc command = '' flavors = ['stata-mp', 'stata-se', 'stata'] if sf is not None: flavors = [sf] + flavors if misc.is_unix(): for flavor in flavors: if misc.is_in_path(flavor): command = misc.stata_command_unix(flavor) break elif sys.platform == 'win32': try: key_exist = os.environ['STATAEXE'] is not None command = misc.stata_command_win("%%STATAEXE%%") except KeyError: flavors = [(f.replace('-', '') + '.exe') for f in flavors] if misc.is_64_windows(): flavors = [f.replace('.exe', '-64.exe') for f in flavors] for flavor in flavors: if misc.is_in_path(flavor): command = misc.stata_command_win(flavor) break if command == '': raise PrerequisiteError( 'Stata is not installed or excecutable is not added to path') check_stata_packages(command)
def test_is_unix(self): ''' Test that is_unix() returns True on Mac and Linux machines and False otherwise. ''' platform_ref = 'gslab_scons.misc.sys.platform' with mock.patch(platform_ref, 'win32'): self.assertFalse(misc.is_unix()) with mock.patch(platform_ref, 'darwin'): self.assertTrue(misc.is_unix()) with mock.patch(platform_ref, 'linux'): self.assertTrue(misc.is_unix()) with mock.patch(platform_ref, 'atheos'): self.assertFalse(misc.is_unix())
def add_executable_options(self): ''' ''' if misc.is_unix(): platform_option = '-nodesktop ' elif sys.platform == 'win32': platform_option = '-minimize -wait ' else: message = 'Cannot find MATLAB command line syntax for platform.' raise PrerequisiteError(message) options = ' -nosplash %s -r' % platform_option return options
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 start_log(mode, vers, log='sconstruct.log'): '''Begins logging a build process''' if not (mode in ['develop', 'cache']): raise Exception("Error: %s is not a defined mode" % mode) start_message = "*** New build: {%s} ***\n" % misc.current_time() with open(log, "w") as f: f.write(start_message) if misc.is_unix(): sys.stdout = os.popen('tee -a %s' % log, 'wb') elif sys.platform == 'win32': sys.stdout = open(log, 'ab') sys.stderr = sys.stdout return None
def collect_builder_logs(parent_dir): ''' Recursively return dictionary of files named sconscript*.log in parent_dir and nested directories. Also return timestamp from those sconscript.log (snippet from SO 3964681)''' builder_log_collect = {} # Store paths to logs in a list, found from platform-specific command line tool rel_parent_dir = os.path.relpath(parent_dir) log_name = 'sconscript*.log' if misc.is_unix(): command = 'find %s -name "%s"' % (rel_parent_dir, log_name) else: command = 'dir "%s" /b/s' % os.path.join(rel_parent_dir, log_name) try: log_paths = subprocess.check_output(command, shell=True).replace('\r\n', '\n') log_paths = log_paths.split('\n') log_paths = filter(bool, map(str.strip, log_paths)) # Strip paths and keep non-empty except subprocess.CalledProcessError: log_paths = [] # Read the file at each path to a log and store output complete-time in a dict at filename for log_path in log_paths: with open(log_path, 'rU') as f: try: s = f.readlines()[ 1] # line 0 = log start time, line 1 = log end time except IndexError: s = '' s = s[s.find('{') + 1:s.find('}')] # find {} time identifier try: builder_log_end_time = datetime.strptime( s, "%Y-%m-%d %H:%M:%S") except ValueError: # if the code breaks, there's no time identifier beginning_of_time = datetime.min builder_log_end_time = beginning_of_time builder_log_collect[log_path] = builder_log_end_time return builder_log_collect
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_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. Note: the user can specify a flavour by typing `scons sf=StataMP` (By default, SCons will try to find each flavour). ''' cl_arg = misc.command_line_args(env) 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, 'stata') log_file = target_dir + '/sconscript.log' loc_log = os.path.basename(source_file).replace('.do', '.log') user_flavor = env['user_flavor'] if user_flavor is not None: if misc.is_unix(): command = misc.stata_command_unix(user_flavor, cl_arg) elif sys.platform == 'win32': command = misc.stata_command_win(user_flavor, cl_arg) else: flavors = ['stata-mp', 'stata-se', 'stata'] if misc.is_unix(): for flavor in flavors: if misc.is_in_path(flavor): command = misc.stata_command_unix(flavor, cl_arg) break elif sys.platform == 'win32': try: key_exist = os.environ['STATAEXE'] is not None command = misc.stata_command_win("%%STATAEXE%%") except KeyError: flavors = [(f.replace('-', '') + '.exe') for f in flavors] if misc.is_64_windows(): flavors = [f.replace('.exe', '-64.exe') for f in flavors] for flavor in flavors: if misc.is_in_path(flavor): command = misc.stata_command_win(flavor, cl_arg) break try: subprocess.check_output(command % source_file, stderr=subprocess.STDOUT, shell=True) except subprocess.CalledProcessError: raise BadExecutableError('Could not find executable.') shutil.move(loc_log, log_file) end_time = misc.current_time() log_timestamp(start_time, end_time, log_file) return None