def initial_reporting(config, run_tracker): """Sets up the initial reporting configuration. Will be changed after we parse cmd-line flags. """ reports_dir = os.path.join(config.getdefault('pants_workdir'), 'reports') link_to_latest = os.path.join(reports_dir, 'latest') run_id = run_tracker.run_info.get_info('id') if run_id is None: raise ReportingError('No run_id set') run_dir = os.path.join(reports_dir, run_id) safe_rmtree(run_dir) html_dir = os.path.join(run_dir, 'html') safe_mkdir(html_dir) try: if os.path.lexists(link_to_latest): os.unlink(link_to_latest) os.symlink(run_dir, link_to_latest) except OSError as e: # Another run may beat us to deletion or creation. if not (e.errno == errno.EEXIST or e.errno == errno.ENOENT): raise report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = StringIO() capturing_reporter_settings = PlainTextReporter.Settings( outfile=outfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter('capturing', capturing_reporter) # Set up HTML reporting. We always want that. template_dir = config.get('reporting', 'reports_template_dir') html_reporter_settings = HtmlReporter.Settings(log_level=Report.INFO, html_dir=html_dir, template_dir=template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter('html', html_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info('default_report', html_reporter.report_path()) (_, port) = ReportingServerManager.get_current_server_pid_and_port() if port: run_tracker.run_info.add_info( 'report_url', 'http://localhost:%d/run/%s' % (port, run_id)) return report
def initial_reporting(config, run_tracker): """Sets up the initial reporting configuration. Will be changed after we parse cmd-line flags. """ reports_dir = os.path.join(config.getdefault('pants_workdir'), 'reports') link_to_latest = os.path.join(reports_dir, 'latest') run_id = run_tracker.run_info.get_info('id') if run_id is None: raise ReportingError('No run_id set') run_dir = os.path.join(reports_dir, run_id) safe_rmtree(run_dir) html_dir = os.path.join(run_dir, 'html') safe_mkdir(html_dir) try: if os.path.lexists(link_to_latest): os.unlink(link_to_latest) os.symlink(run_dir, link_to_latest) except OSError as e: # Another run may beat us to deletion or creation. if not (e.errno == errno.EEXIST or e.errno == errno.ENOENT): raise report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = StringIO() capturing_reporter_settings = PlainTextReporter.Settings(outfile=outfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter('capturing', capturing_reporter) # Set up HTML reporting. We always want that. template_dir = config.get('reporting', 'reports_template_dir') html_reporter_settings = HtmlReporter.Settings(log_level=Report.INFO, html_dir=html_dir, template_dir=template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter('html', html_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info('default_report', html_reporter.report_path()) (_, port) = ReportingServerManager.get_current_server_pid_and_port() if port: run_tracker.run_info.add_info('report_url', 'http://localhost:%d/run/%s' % (port, run_id)) return report
def initial_reporting(self, run_tracker): """Sets up the initial reporting configuration. Will be changed after we parse cmd-line flags. """ link_to_latest = os.path.join(self.get_options().reports_dir, 'latest') run_id = run_tracker.run_info.get_info('id') if run_id is None: raise ReportingError('No run_id set') run_dir = os.path.join(self.get_options().reports_dir, run_id) safe_rmtree(run_dir) html_dir = os.path.join(run_dir, 'html') safe_mkdir(html_dir) relative_symlink(run_dir, link_to_latest) report = Report() # Capture initial console reporting into a buffer. We'll do something with it once # we know what the cmd-line flag settings are. outfile = StringIO() capturing_reporter_settings = PlainTextReporter.Settings(outfile=outfile, log_level=Report.INFO, color=False, indent=True, timing=False, cache_stats=False) capturing_reporter = PlainTextReporter(run_tracker, capturing_reporter_settings) report.add_reporter('capturing', capturing_reporter) # Set up HTML reporting. We always want that. html_reporter_settings = HtmlReporter.Settings(log_level=Report.INFO, html_dir=html_dir, template_dir=self.get_options().template_dir) html_reporter = HtmlReporter(run_tracker, html_reporter_settings) report.add_reporter('html', html_reporter) # Add some useful RunInfo. run_tracker.run_info.add_info('default_report', html_reporter.report_path()) (_, port) = ReportingServerManager.get_current_server_pid_and_port() if port: run_tracker.run_info.add_info('report_url', 'http://localhost:{}/run/{}'.format(port, run_id)) return report
def execute(self): DONE = '__done_reporting' def maybe_open(port): if self.get_options().open: binary_util.ui_open('http://localhost:{port}'.format(port=port)) (pid, port) = ReportingServerManager.get_current_server_pid_and_port() if port: maybe_open(port) print('Server already running with pid {pid} at http://localhost:{port}' .format(port=port, pid=pid), file=sys.stderr) return def run_server(reporting_queue): def report_launch(actual_port): reporting_queue.put( 'Launching server with pid {pid} at http://localhost:{port}' .format(pid=os.getpid(), port=actual_port)) def done_reporting(): reporting_queue.put(DONE) try: # We mustn't block in the child, because the multiprocessing module enforces that the # parent either kills or joins to it. Instead we fork a grandchild that inherits the queue # but is allowed to block indefinitely on the server loop. if not os.fork(): # Child process. # The server finds run-specific info dirs by looking at the subdirectories of info_dir, # which is conveniently and obviously the parent dir of the current run's info dir. info_dir = os.path.dirname(self.context.run_tracker.run_info_dir) # If these are specified explicitly in the config, use those. Otherwise # they will be None, and we'll use the ones baked into this package. template_dir = self.get_options().template_dir assets_dir = self.get_options().assets_dir settings = ReportingServer.Settings(info_dir=info_dir, template_dir=template_dir, assets_dir=assets_dir, root=get_buildroot(), allowed_clients=self.get_options().allowed_clients) server = ReportingServer(self.get_options().port, settings) actual_port = server.server_port() ReportingServerManager.save_current_server_port(actual_port) report_launch(actual_port) done_reporting() # Block forever here. server.start() except socket.error: done_reporting() raise # We do reporting on behalf of the child process (necessary, since reporting may be buffered in # a background thread). We use multiprocessing.Process() to spawn the child so we can use that # module's inter-process Queue implementation. reporting_queue = multiprocessing.Queue() proc = multiprocessing.Process(target=run_server, args=[reporting_queue]) proc.daemon = True proc.start() s = reporting_queue.get() while s != DONE: print(s, file=sys.stderr) s = reporting_queue.get() # The child process is done reporting, and is now in the server loop, so we can proceed. (_, server_port) = ReportingServerManager.get_current_server_pid_and_port() maybe_open(server_port)
def execute(self): DONE = '__done_reporting' def maybe_open(port): if self.get_options().open: binary_util.ui_open( 'http://localhost:{port}'.format(port=port)) (pid, port) = ReportingServerManager.get_current_server_pid_and_port() if port: maybe_open(port) print( 'Server already running with pid {pid} at http://localhost:{port}' .format(port=port, pid=pid), file=sys.stderr) return def run_server(reporting_queue): def report_launch(actual_port): reporting_queue.put( 'Launching server with pid {pid} at http://localhost:{port}' .format(pid=os.getpid(), port=actual_port)) def done_reporting(): reporting_queue.put(DONE) try: # We mustn't block in the child, because the multiprocessing module enforces that the # parent either kills or joins to it. Instead we fork a grandchild that inherits the queue # but is allowed to block indefinitely on the server loop. if not os.fork(): # Child process. # The server finds run-specific info dirs by looking at the subdirectories of info_dir, # which is conveniently and obviously the parent dir of the current run's info dir. info_dir = os.path.dirname( self.context.run_tracker.run_info_dir) # If these are specified explicitly in the config, use those. Otherwise # they will be None, and we'll use the ones baked into this package. template_dir = self.get_options().template_dir assets_dir = self.get_options().assets_dir settings = ReportingServer.Settings( info_dir=info_dir, template_dir=template_dir, assets_dir=assets_dir, root=get_buildroot(), allowed_clients=self.get_options().allowed_clients) server = ReportingServer(self.get_options().port, settings) actual_port = server.server_port() ReportingServerManager.save_current_server_port( actual_port) report_launch(actual_port) done_reporting() # Block forever here. server.start() except socket.error: done_reporting() raise # We do reporting on behalf of the child process (necessary, since reporting may be buffered in # a background thread). We use multiprocessing.Process() to spawn the child so we can use that # module's inter-process Queue implementation. reporting_queue = multiprocessing.Queue() proc = multiprocessing.Process(target=run_server, args=[reporting_queue]) proc.daemon = True proc.start() s = reporting_queue.get() while s != DONE: print(s, file=sys.stderr) s = reporting_queue.get() # The child process is done reporting, and is now in the server loop, so we can proceed. (_, server_port ) = ReportingServerManager.get_current_server_pid_and_port() maybe_open(server_port)