def __update_build_targets_visibility(self, active): """ Update the Build & Run, Build & Debug and the plugin's associated Build Targets depending on ``active``. """ build_run_target = GPS.BuildTarget("Build & Run") build_debug_target = GPS.BuildTarget("Build & Debug") if active: build_run_target.hide() build_debug_target.hide() for target in self.__debug_build_targets: target.show() if self.__flashing_tool: for target in self.__flash_build_targets: target.show() else: for target in self.__flash_build_targets: target.hide() else: build_run_target.show() build_debug_target.show() for target in self.__debug_build_targets: target.hide() for target in self.__flash_build_targets: target.hide()
def __update_build_targets_visibility(): """ Update the GNATtest/'Run Main' Build Targets visibility regarding the nature of the loaded project. Also check whether or not we need to display GNATtest emulator Build Targets. """ try: test_run_target = GPS.BuildTarget("Run a test-driver") test_run_targets = GPS.BuildTarget("Run a test drivers list") run_main_target = GPS.BuildTarget("Run Main") test_run_emulator_target = GPS.BuildTarget( "Run test driver with emulator") test_run_emulator_targets = GPS.BuildTarget( "Run test-drivers list with emulator") except Exception: # In some rare cases GPS recompute project view before build targets # are actually created. We don't update targets in these cases. return if not GPS.Project.root().is_harness_project(): run_main_target.show() test_run_target.hide() test_run_targets.hide() test_run_emulator_targets.hide() test_run_emulator_target.hide() elif get_driver_list() == "": """ We have a single test driver. """ run_main_target.hide() test_run_targets.hide() test_run_emulator_targets.hide() if GNATemulator.gnatemu_on_path(): test_run_emulator_target.show() test_run_target.hide() else: test_run_emulator_target.hide() test_run_target.show() else: """ The file 'test_drivers.list' is present. We have a list of test drivers to execute. """ run_main_target.hide() test_run_target.hide() test_run_emulator_target.hide() if GNATemulator.gnatemu_on_path(): test_run_targets.hide() test_run_emulator_targets.show() else: test_run_targets.show() test_run_emulator_targets.hide()
def run_gnatname(): """ Run gnatname with the naming patterns entered by the user in a simple input dialog. """ naming_patterns = GPS.MDI.input_dialog( "Enter the space-separated naming patterns that will be " + "used by gnatname to find compilation units " + "(e.g: 'body_* spec_*'). These files are searched among the " + "project's source directories.", "Naming Patterns") if naming_patterns: naming_patterns = ''.join(naming_patterns) source_dirs = GPS.Project.root().source_dirs() root = GPS.Project.root().file().directory() extra_args = ['-d' + os.path.relpath(source_dir, root) for source_dir in source_dirs] extra_args = ' '.join(extra_args) extra_args += ' ' + naming_patterns GPS.BuildTarget("gnatname").execute( extra_args=extra_args, synchronous=False, on_exit=on_exit)
def recompute_xref(self, force=False, quiet=True): """ Launch recompilation of the cross references. if Force is True, run regardless of a running gnatinspect (this flag is used to protect against reentry)""" if self.gnatinspect_already_running: # We are already running gnatinspect. If someone registers # another gnatinspect launch, set up the corresponding flag, # and wait for gnatinspect to complete before launching the # next one. self.gnatinspect_launch_registered = True return # The project might not exist, for instance when GPS is loading the # default project in a directory if not os.path.exists(GPS.Project.root().file().path): return # We are about to launch gnatinspect self.gnatinspect_launch_registered = False self.gnatinspect_already_running = True target = GPS.BuildTarget("Load Xref Info") # This might fail if we have spaces in the name of the directory, but # any quoting we do here is passed directly to gnatinspect, and the # switch will not be handled correctly. extra_args = ['--db=%s' % (GPS.xref_db(), )] if not self.trusted_mode: extra_args.append("--symlinks") target.execute(synchronous=GPS.Logger("TESTSUITE").active, quiet=quiet, extra_args=extra_args)
def test_driver(): b = GPS.EditorBuffer.get(GPS.File("main.adb")) GPS.BuildTarget("Build All").execute(force=True) yield wait_tasks() gps_assert('gprbuild: "baz bar"' in GPS.Console("Messages").get_text(), False)
def __create_targets_lazily(self): active = GNATemulator.gnatemu_on_path() if not self.__buildTargets and active: targets_def = [[ "Run with Emulator", "run-with-emulator", GNATemulator.build_and_run, "gps-emulatorloading-run-symbolic" ], [ "Debug with Emulator", "debug-with-emulator", GNATemulator.build_and_debug, "gps-emulatorloading-debug-symbolic" ]] for target in targets_def: workflows.create_target_from_workflow( target_name=target[0], workflow_name=target[1], workflow=target[2], icon_name=target[3], parent_menu='/Build/Emulator/%s/' % target[0]) self.__buildTargets.append(GPS.BuildTarget(target[0])) if active: for b in self.__buildTargets: b.show() else: for b in self.__buildTargets: b.hide()
def __update_build_targets_visibility(): """ Update the GNATtest/'Run Main' Build Targets visibility regarding the nature of the loaded project. Also check whether or not we need to display GNATtest emulator Build Targets. """ test_run_target = GPS.BuildTarget("Run a test-driver") test_run_targets = GPS.BuildTarget("Run a test drivers list") run_main_target = GPS.BuildTarget("Run Main") test_run_emulator_target = GPS.BuildTarget("Run test driver with emulator") test_run_emulator_targets = GPS.BuildTarget( "Run test-drivers list with emulator") if not GPS.Project.root().is_harness_project(): run_main_target.show() test_run_target.hide() test_run_targets.hide() test_run_emulator_targets.hide() test_run_emulator_target.hide() elif get_driver_list() == "": """ We have a single test driver. """ run_main_target.hide() test_run_targets.hide() test_run_emulator_targets.hide() if GNATemulator.gnatemu_on_path(): test_run_emulator_target.show() test_run_target.hide() else: test_run_emulator_target.hide() test_run_target.show() else: """ The file 'test_drivers.list' is present. We have a list of test drivers to execute. """ run_main_target.hide() test_run_target.hide() test_run_emulator_target.hide() if GNATemulator.gnatemu_on_path(): test_run_targets.hide() test_run_emulator_targets.show() else: test_run_targets.show() test_run_emulator_targets.hide()
def __init__(self, target_name): """ Build the target and initialize promise to None """ # handler for my target self.__target = GPS.BuildTarget(target_name) # promise about building this target self.__promise = None
def run_gnatdoc(target, force=False, extra_args=[]): """ Runs GNATdoc using given target and extra arguments. """ extra = list(extra_args) if not GNATdoc_Module.trusted_mode: extra.append("--symlinks") GPS.BuildTarget(target).execute(synchronous=False, force=force, extra_args=extra)
def on_prove_check(context): msg = context._loc_msg text_msg = get_comp_text(msg) msg_line = map_msg[text_msg, 'check_line'] msg_col = map_msg[text_msg, 'check_col'] vc_kind = get_vc_kind(msg) llarg = limit_line_option(msg, msg_line, msg_col, vc_kind) args = [llarg] if inside_generic_unit_context(context): args.append("-U") GPS.Locations.remove_category("Builder results") GPS.BuildTarget(prove_check()).execute(extra_args=args, synchronous=False)
def check_proof_after_close(proc, ex_st, outp): """run gnatprove to check a proof after the external editor has been closed """ if not proc._is_killed: try: vc_kind = get_vc_kind(proc._proc_msg) llarg = limit_line_option(proc._proc_msg, vc_kind) GPS.Locations.remove_category("Builder results") GPS.BuildTarget(prove_check()).execute(extra_args=[llarg], synchronous=False) except TypeError: pass
def __update_build_targets_visibility(): """ Update the GNATtest/'Run Main' Build Targets visibility regarding the nature of the loaded project. """ test_run_target = GPS.BuildTarget("Run a test-driver") test_run_targets = GPS.BuildTarget("Run a test drivers list") run_main_target = GPS.BuildTarget("Run Main") if not GPS.Project.root().is_harness_project(): run_main_target.show() test_run_target.hide() test_run_targets.hide() return elif get_driver_list() == "": run_main_target.hide() test_run_target.show() test_run_targets.hide() else: run_main_target.hide() test_run_target.hide() test_run_targets.show()
def __create_target_lazily(self): """ Create the "Build & Run All" target. """ if not self.__buildTarget: workflows.create_target_from_workflow( parent_menu='/Build/Project/', target_name="Build & Run All", workflow_name="build-and-run-all", workflow=self.__build_and_run_all_wf, icon_name="gps-run-symbolic", main_arg="") self.__buildTarget = GPS.BuildTarget("Build & Run All")
def cpp_on_file(): obj_dir = GPS.Project.root().artifacts_dir() file = GPS.current_context().file() # Put the generated file in the object dir and for "foo.c" # creates "foo.prep.c" output_file = file.path.replace(file.directory(), obj_dir) splitted = output_file.split(".") output_file = ".".join(splitted[:-1]) + ".prep." + splitted[-1] output = "-o " + output_file def on_exit(status): if not status: GPS.EditorBuffer.get(GPS.File(output_file)) target = GPS.BuildTarget("c preprocess file") target.execute(synchronous=False, on_exit=on_exit, extra_args=output)
def update_worflow_build_targets(self): gnatcov_available = self.is_gnatcov_available() instrumentation_supported = self.is_instrumentation_supported() if gnatcov_available and not self.__run_gnatcov_wf_build_target: workflows.create_target_from_workflow( target_name="Run GNATcoverage", workflow_name="run-gnatcov", workflow=self.run_gnatcov_wf, icon_name="gps-run-gnatcov-symbolic", parent_menu="/Build/Workflow/GNATcov/") self.__run_gnatcov_wf_build_target = \ GPS.BuildTarget("Run GNATcoverage") if instrumentation_supported: workflows.create_target_from_workflow( target_name="Run GNATcoverage with instrumentation", workflow_name="run-gnatcov-with-instrumentation", in_toolbar=False, workflow=self.run_gnatcov_with_instrumentation_wf, parent_menu=PLUGIN_MENU + "/Intrumentation/") self.__run_gnatcov_instr_wf_build_target = \ GPS.BuildTarget("Run GNATcoverage with instrumentation") if not gnatcov_available: if self.__run_gnatcov_wf_build_target: self.__run_gnatcov_wf_build_target.hide() if self.__run_gnatcov_instr_wf_build_target: self.__run_gnatcov_instr_wf_build_target.hide() elif not instrumentation_supported: if self.__run_gnatcov_instr_wf_build_target: self.__run_gnatcov_instr_wf_build_target.hide()
def generic_action_on_subp(self, action): """execute the action on the the given subprogram entity """ # The argument --limit-subp is not defined in the examine_subp/prove_subp # build targets, because we have no means of designating the proper # location at that point. A mild consequence is that --limit-subp does not # appear in the editable box shown to the user, even if it appears in the # uneditable argument list displayed below it. arg = build_limit_subp_string(self) if arg is not None: args = [arg] if inside_generic_unit_context(self): args.append("-U") GPS.Locations.remove_category("Builder results") target = GPS.BuildTarget(action) target.execute(extra_args=args, synchronous=False)
def on_fuzzable_subprogram_click(self, message): """React to a click on a "fuzzable subprogram" message box""" # This is akin to a compilation: save everything that needs saving GPS.MDI.save_all() output_dir = os.path.join(GPS.Project.root().object_dirs()[0], "fuzz_harness") if os.path.exists(output_dir): shutil.rmtree(output_dir) analyze_report_file = self.path_to_analyze_json() if not os.path.exists(analyze_report_file): self.error(f"Analyze file not found: {analyze_report_file}") return # Launch "gnatfuzz generate" GPS.BuildTarget("gnatfuzz generate").execute( extra_args=[ "-o", output_dir, "--analysis", analyze_report_file, "--subprogram-id", str(message.analyze_id), ], synchronous=True, ) # TODO: make this a workflow, in case this takes a long time. harness_project = os.path.join(output_dir, "fuzz_testing", "fuzz_test.gpr") if os.path.exists(harness_project): r = GPS.MDI.yes_no_dialog( "Harness generation successful.\n\nSwitch to harness project?") if r: GPS.Project.load(harness_project)
def update_worflow_build_targets(self): gnatcov_available = self.is_gnatcov_available() instrumentation_supported = self.is_instrumentation_supported() if gnatcov_available and not self.__run_gnatcov_wf_build_target: if self.is_binary_supported(): workflows.create_target_from_workflow( target_name="Run GNATcoverage", workflow_name="run-gnatcov", workflow=self.run_gnatcov_wf, in_toolbar=not instrumentation_supported, icon_name="gps-run-gnatcov-symbolic", parent_menu=BINARY_TRACES_MENU + "/Run All Actions/") self.__run_gnatcov_wf_build_target = \ GPS.BuildTarget("Run GNATcoverage") GPS.parse_xml(list_to_xml(self.BINARY_TRACES_BUILD_TARGETS)) if instrumentation_supported: workflows.create_target_from_workflow( target_name="Run GNATcoverage with instrumentation", workflow_name="run-gnatcov-with-instrumentation", in_toolbar=True, icon_name="gps-run-gnatcov-symbolic", workflow=self.run_gnatcov_with_instrumentation_wf, parent_menu=SOURCE_TRACES_MENU + "/Run All Actions/") self.__run_gnatcov_instr_wf_build_target = \ GPS.BuildTarget("Run GNATcoverage with instrumentation") # We want the toolbar to be ordered according to the coverage # process: # GNATcoverage source traces # -> Instrument # -> Build # -> Run # -> Generate Report # # As the Run action is a a workflow, and is not included in # SOURCE_TRACES_BUILD_TARGETS, we have to incorporate it in the # middle. We thus first parse the XML corresponding to the # Instrument and Build steps, then parse the XML for the Run # workflow, and in the end, for the Generate Report build # target. # Instrument and Build GPS.parse_xml(list_to_xml( self.SOURCE_TRACES_BUILD_TARGETS[:4])) workflows.create_target_from_workflow( target_name="Run instrumented main", workflow_name="run-instrumented-main", in_toolbar=False, icon_name="gps-run-gnatcov-symbolic", workflow=self.run_instrumented_main_wf, parent_menu=SOURCE_TRACES_MENU + "/Run/") # Generate Report GPS.parse_xml(list_to_xml( self.SOURCE_TRACES_BUILD_TARGETS[4:])) if not gnatcov_available: if self.__run_gnatcov_wf_build_target: self.__run_gnatcov_wf_build_target.hide() if self.__run_gnatcov_instr_wf_build_target: self.__run_gnatcov_instr_wf_build_target.hide() elif not instrumentation_supported: if self.__run_gnatcov_instr_wf_build_target: self.__run_gnatcov_instr_wf_build_target.hide()
def __create_targets_lazily(self): """ Create all the build targets needed to flash/debug a board. Here is the list of these build targets: . 'Flash to Board' and 'Flash <current file> to Board' build targets . 'Debug on Board' and 'Debug <current file> on Board' build targets . TargetConnector build target (created from IDE'Connection_Tool) This method is called each time the project changes. """ project = GPS.Project.root() # Update the settings used for flash/debug self.__update_settings(project) # Check if it's a project for non-native targets active = self.__is_non_native_project(project) # Remove the previous Target Connector build target since the # connection tool and/or its arguments may have changed. if self.__connector: self.__connector.remove() # Create the Target Connector build target if a connection tool # has been specified in the project. if active and self.__connection_tool: cmd = self.__get_connection_command_line() self.__connector = TargetConnector( tool_name=cmd[0], default_args=cmd[1:]) # Create the build targets needed in order to flash/debug the board # if not created yet. if not self.__debug_build_targets: workflows.create_target_from_workflow( parent_menu='/Build/Bareboard/Debug on Board/', target_name="Debug on Board", workflow_name="debug-on-board", workflow=self.__debug_wf, icon_name="gps-boardloading-debug-symbolic") self.__debug_build_targets.append( GPS.BuildTarget("Debug on Board")) workflows.create_target_from_workflow( parent_menu='/Build/Bareboard/', target_name="Debug <current file> on Board", workflow_name="debug-current-on-board", workflow=self.__debug_wf, icon_name="gps-boardloading-debug-symbolic", in_toolbar=False, main_arg="%fp") self.__debug_build_targets.append( GPS.BuildTarget("Debug <current file> on Board")) if not self.__flash_build_targets: workflows.create_target_from_workflow( parent_menu='/Build/Bareboard/Flash to Board/', target_name="Flash to Board", workflow_name="flash-to-board", workflow=self.__flash_wf, icon_name="gps-boardloading-flash-symbolic") self.__flash_build_targets.append( GPS.BuildTarget("Flash to Board")) workflows.create_target_from_workflow( parent_menu='/Build/Bareboard/', target_name="Flash <current file> to Board", workflow_name="flash-current-to-board", workflow=self.__flash_wf, icon_name="gps-boardloading-flash-symbolic", in_toolbar=False, main_arg="%fp") self.__flash_build_targets.append( GPS.BuildTarget("Flash <current file> to Board")) # Show/Hide the build targets accordingly self.__update_build_targets_visibility(active)
def run_gnatpp_on_project_only(): """ Run gnatpp on the root project, without pretty printing the subprojects. """ GPS.BuildTarget('Pretty Print current project').execute(synchronous=False)
def run_gnatpp_on_project_and_subprojects(): """ Run gnatpp on the root project and the subprojects. """ GPS.BuildTarget('Pretty Print current project and subprojects').execute( synchronous=False)
def run_instrumented_main_wf(self, main_name, generate=False): exe = str(GPS.File(main_name).executable_path) # Go to the object directory before executing the instrumented main: we # want to produce the trace file in the object dir and not in the # project's root directory obj_dir = GPS.Project.root().object_dirs()[0] GPS.cd(obj_dir) # Clean the previous trace file if it exists (the run can fails and # then the trace file will not be overwritten: it will show outdated # data) srctrace_filename = os.path.join(obj_dir, exe + ".srctrace") try: os.remove(srctrace_filename) except FileNotFoundError: pass # Run the instrumented main (through GNATemulator for cross targets) # it will generate the new trace file. target = GPS.get_target() if target == "": cmdargs = [exe] p = promises.ProcessWrapper(cmdargs) GPS.Console().write(' '.join(cmdargs)) status, output = yield p.wait_until_terminate(show_if_error=True) if status != 0: GPS.Console("Messages").write( "Failed to execute main with status " + str(status)) else: # Launch the instrumented executable through GNATemulator cmdargs = GPS.BuildTarget( "Run GNATemulator").get_expanded_command_line() cmdargs.append(exe) GPS.Console().write(' '.join(cmdargs) + "\n") gnatemu_promise = promises.ProcessWrapper(cmdargs=cmdargs) status, output = yield gnatemu_promise.wait_until_terminate( show_if_error=True) # Put the output in a file and use 'gnatcov extract-base64-trace' # to retrieve the traces information from it out_filename = os.path.join(obj_dir, exe + ".out") with open(out_filename, "w") as f: f.write(output) extract_trace_cmd = [ "gnatcov", "extract-base64-trace", out_filename, srctrace_filename ] GPS.Console().write(' '.join(extract_trace_cmd) + "\n") status = GPS.Process(extract_trace_cmd).wait() if status != 0: GPS.Console().write( "Could not extract traces info from executable's output", mode="error") if status == 0 and generate: # Generate and display the GNATcov Coverage Report p = promises.TargetWrapper( "Generate GNATcov Instrumented Main Report") yield p.wait_on_execute(exe, quiet=True) return status
def gnatfuzz_fuzz_workflow(self, task): """The 'gnatfuzz fuzz' workflow""" # Move away the previous fuzzing session dir fuzz_session_dir = os.path.join(self.output_dir, "fuzz_testing", "session") if os.path.exists(fuzz_session_dir): shutil.rmtree(fuzz_session_dir) # Generate the -X switches args = [] for variable, value in GPS.Project.scenario_variables().items(): # We pass all -X switches except the ones that are internal # to gnatfuzz. if not (variable.startswith("GNATFUZZ") or variable == "AFL_MODE"): args.append(f"-X{variable}={value}") args.extend([ f"--corpus-path={self.output_dir}/fuzz_testing/starting_corpus", f"--stop-criteria={self.output_dir}" "/fuzz_testing/user_configuration/stop_criteria.xml", ]) GPS.BuildTarget("gnatfuzz fuzz").execute( extra_args=args, synchronous=False, ) # Create a CodeAnalysis object to store the coverage data a = GPS.CodeAnalysis.get("gnatfuzz") xcov_files = {} # Keys: full path, values: timestamp # Launch the GNATfuzz view GPS.execute_action("open GNATfuzz view") # Clear the GNATfuzz view GPS.execute_action("clear GNATfuzz view") # Monitor the disk for the presence of xcov files while True: # This is interrupted by the user calling the menu again, # in which case the Task will be removed: see at the bottom # of the loop. yield promises.timeout(FUZZ_MONITOR_TIMEOUT) if not os.path.exists(fuzz_session_dir): self.error( f"fuzz session directory {fuzz_session_dir} not found") self.stop_fuzz() break # Monitor for coverage files found_xcov_files = glob.glob( os.path.join(fuzz_session_dir, "coverage_output", "*.xcov")) for xcov in found_xcov_files: (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(xcov) timestamp = time.ctime(mtime) if xcov not in xcov_files or xcov_files[xcov] != timestamp: xcov_files[xcov] = timestamp base = os.path.basename(xcov)[:-5] a.add_gcov_file_info(GPS.File(base), GPS.File(xcov), raise_window=False) a.show_file_coverage_info(GPS.File(base)) # Monitor for crashes view = get_gnatfuzz_view() if view is not None: view.refresh() # The end condition tasks = [t for t in GPS.Task.list() if t.name() == "gnatfuzz fuzz"] if len(tasks) == 0: break return
def show_dialog_and_run_gnathub(): target = GPS.BuildTarget("gnathub") target.execute(synchronous=False)
def my_action(): target = GPS.BuildTarget("my_command") target.execute(synchronous=False)
def run(project, target, extra_args=""): """ Run gnattest and switch to harness if success. """ last_gnattest['project'] = project GPS.BuildTarget(target).execute(synchronous=False, extra_args=extra_args)
def generic_on_analyze(target, args=[]): disable_trace_and_ce() GPS.Locations.remove_category("Builder results") GPS.BuildTarget(target).execute(extra_args=args, synchronous=False)
def gnatmetric_on_file(): target = GPS.BuildTarget("GNAT Metrics for file") target.execute(synchronous=False)
def gnatmetric_on_all_project(): target = GPS.BuildTarget("GNAT Metrics for project and subprojects") target.execute(synchronous=False)
def view_types_layout(): context = GPS.current_context() f = context.file() GPS.BuildTarget('Compute Types Layout').execute(file=f)