def build_traditional_items(printerport, fileport): ''' Menu items represent functionality. Their functionality (commands) can be in many menus, but items themselves must be in only one menu, since items call on their unique parent. TODO: arranged by preference or dynamically? ''' # menu_item = gui.itemmenu.IconMenuItem( command.NULL_COMMAND ) global save_mi, print_mi global cut_mi, copy_mi, paste_mi global doc_cut_mi, doc_copy_mi, doc_paste_mi global resize_mi, draw_mi save_mi = gui.itemmenu.TextMenuItem("Save", command.Command(fileport.do_save)) print_mi = gui.itemmenu.TextMenuItem("Print", command.Command(printerport.do_print)) # TODO share commands cut_mi = gui.itemmenu.TextMenuItem("Cut", command.Command(edit.do_cut)) copy_mi = gui.itemmenu.TextMenuItem("Copy", command.Command(edit.do_copy)) paste_mi = gui.itemmenu.TextMenuItem("Paste", command.Command(edit.do_paste)) doc_cut_mi = gui.itemmenu.TextMenuItem("Cut", command.Command(edit.do_cut)) doc_copy_mi = gui.itemmenu.TextMenuItem("Copy", command.Command(edit.do_copy)) doc_paste_mi = gui.itemmenu.TextMenuItem("Paste", command.Command(edit.do_paste)) resize_mi = gui.itemmenu.TextMenuItem("Resize TODO", command.NULL_COMMAND) draw_mi = gui.itemmenu.TextMenuItem("Draw TODO", command.NULL_COMMAND)
def test_collect_log(self): cmd = command.Command( args=['bash', '-c', 'echo -n Hello'], exit_code=0, ) self.assertEqual("Hello", cmd.output_text) self.assertEqual("", cmd.error_text)
def version(self): """Returns: a tuple representing the verion of git script uses.""" if self._version is None: version_cmd = command.Command("git", "--version", exit_code=0) version_str = version_cmd.output_text.split()[2] self._version = tuple(version_str.split(".")) return self._version
def Run(self): git_repo_name = 'kiji_schema' git_repo_dir = os.path.join(self._work_dir, git_repo_name) if not os.path.exists(git_repo_dir): command.Command( 'git', 'clone', 'git://github.com/kijiproject/kiji-schema.git', git_repo_name, work_dir=self._work_dir, exit_code=0, ) command.Command( 'git', 'fetch', 'origin', work_dir=git_repo_dir, exit_code=0, ) command.Command( 'git', 'checkout', 'origin/master', work_dir=git_repo_dir, exit_code=0, ) maven = command.Command( 'mvn', 'clean', 'test', ('-DargLine=-Dorg.kiji.schema.KijiClientTest.HBASE_ADDRESS=%s' % self.bento_cluster.zookeeper_address), work_dir=git_repo_dir, ) if maven.exit_code == 0: print('No test failure') logging.info('Maven error stream:\n%s', maven.error_text) logging.info('Maven output stream:\n%s', maven.output_text) return os.EX_OK else: logging.error('There are test failures') logging.info('Maven error stream:\n%s', maven.error_text) logging.info('Maven output stream:\n%s', maven.output_text) return os.EX_DATAERR
def run(self, args): start_count = 0 has_max_restarts = (self.flags.max_restart > 0) command_args = tuple(args) while True: try: cmd = None start_count += 1 if has_max_restarts and (start_count > self.flags.max_restart): logging.error( 'Maximum number of restarts reached, exiting!') body = MAX_RETRIES_MAIL_TEMPLATE % dict( max_retries=self.flags.max_restart, command=' \\\n\t'.join(command_args), user=getpass.getuser(), host=socket.gethostname(), work_dir=os.getcwd(), ) SafeMail(subject='[FAILURE] Command: %s' % (command_args, ), body=body) return ExitCode.FAILURE logging.info('Running attempt #%d for command: %r', start_count, command_args) cmd = command.Command(args=args, start=False) cmd.Start(wait_for=False) logging.info('Attempt #%d running with PID %d', start_count, cmd.pid) cmd.WaitFor() except: logging.error('Error running command: %r', sys.exc_info()[0]) traceback.print_exc() finally: if cmd is None: logging.fatal('Error running command: %r', args) return ExitCode.FAILURE else: logging.error('Daemon exited with code: %d', cmd.exit_code) body = RESTART_MAIL_TEMPLATE % dict( exit_code=cmd.exit_code, command=' \\\n\t'.join(command_args), user=getpass.getuser(), host=socket.gethostname(), work_dir=os.getcwd(), output=cmd.output_text, error=cmd.error_text, ) SafeMail(subject='[FAILURE] Command: %s' % (command_args, ), body=body) time.sleep(self.flags.restart_cooldown_time_interval)
def Exec(self, command_args): """Executes a command-line. Args: command_args: Command-line as a list of string. """ cmd = command.Command(*command_args) if cmd.exit_code != 0: pretty_command = ' \\\n '.join(command_args) logging.error('Command failed:\n%s\n%s', cmd.output_text, cmd.error_text) raise Exception('Command-line failure:\n%s' % pretty_command)
def test_no_collect_log(self): with tempfile.TemporaryDirectory() as temp_dir: logging.debug("Using temporary directory %r", temp_dir) cmd = command.Command( args=['bash', '-c', 'echo -n Hello'], log_dir=temp_dir, collect_log=False, exit_code=0, ) self.assertEqual("Hello", cmd.output_text) self.assertEqual("", cmd.error_text) self.assertEqual(temp_dir, os.path.dirname(cmd.output_path)) self.assertEqual(temp_dir, os.path.dirname(cmd.error_path))
def list_dependencies( coordinates, scope="runtime", local_repo=None, ): """Lists the resolved dependencies. Args: coordinates: Collection of Artifact to examine. scope: Optional Maven scope to determine the classpath for. Default is runtime. local_repo: Optional explicit Maven local repository to use. Returns: An iterable of Maven artifact coordinates. """ with tempfile.NamedTemporaryFile(prefix="pom.", suffix=".xml") as pom_file, \ tempfile.NamedTemporaryFile(prefix="maven-dependency-resolved.", suffix=".txt") as tfile: with open(pom_file.name, "wt") as file: file.write( workflow_task.format_pom_file( artf=artifact.Artifact("unknown", "unknown", "unknown"), compile_deps=coordinates, )) args = [ "mvn", "--batch-mode", "--file={}".format(pom_file.name), ] if local_repo is not None: args += ["-Dmaven.repo.local={}".format(local_repo)] args += [ "dependency:list", "-DoutputFile={}".format(tfile.name), "-Dsort=true", "-DincludeScope={}".format(scope), ] cmd = command.Command(args=args) log_maven_output(cmd.output_lines) with open(tfile.name, "rt") as file: lines = file.readlines() lines = map(str.strip, lines) lines = filter(None, lines) lines = filter( lambda line: (line != "The following files have been resolved:"), lines) lines = map(artifact.parse_artifact, lines) return sorted(lines)
def command(self, *args, exit_code=0, **kwargs): """Runs a Git command on this repository. Args: *args: Git command, eg. ["log"]. exit_code: Required exit code. Defaults to 0. **kwargs: Extra keyword arguments. """ assert self.exists, ("Git repository %r does not exist." % self.path) return command.Command( "git", *args, exit_code=exit_code, work_dir=self.path, **kwargs )
def get_dependency_tree( coordinates, scope=None, local_repo=None, ): """Reports the dependency tree as a text representation. Args: coordinates: Collection of Artifact to examine. scope: Optional Maven scope to determine the classpath for. local_repo: Optional explicit Maven local repository to use. Returns: A text representation of the Maven dependency tree. """ with tempfile.NamedTemporaryFile(prefix="pom.", suffix=".xml") as pom_file, \ tempfile.NamedTemporaryFile(prefix="maven-dependency-tree.", suffix=".txt") as tfile: with open(pom_file.name, "wt") as file: file.write( workflow_task.format_pom_file( artf=artifact.Artifact("root", "root", "0"), compile_deps=coordinates, )) args = [ "mvn", "--batch-mode", "--file={}".format(pom_file.name), ] if local_repo is not None: args += ["-Dmaven.repo.local={}".format(local_repo)] args += [ "dependency:tree", "-DoutputFile={}".format(tfile.name), "-Dverbose", ] if (scope is not None) and (len(scope) > 0): args.append("-Dscope={}".format(scope)) cmd = command.Command(args=args) log_maven_output(cmd.output_lines) with open(tfile.name, "rt") as file: return file.read()
def dump_as_svg(self): dot_source = self.dump_run_state_as_dot() with tempfile.NamedTemporaryFile(suffix='.dot') as dot_file: with tempfile.NamedTemporaryFile(suffix='.svg') as svg_file: dot_file.write(dot_source.encode()) dot_file.flush() cmd = command.Command( args=['dot', '-Tsvg', '-o%s' % svg_file.name, dot_file.name], exit_code=0, wait_for=False, ) # Allow 10s for Graphiz to complete, or kill it: try: cmd.WaitFor(timeout=10.0) except TimeoutError: cmd.Kill(sig=signal.SIGKILL) raise return svg_file.read().decode()
def clone(self, address, recursive=False, depth=None): """Clones a Git repository into this repository. This repository path must not exist already. Args: address: Address of the Git repository to clone. recursive: Whether to clone submodules recursively. depth: Number of commits back in history to pull. If None, pull all. """ assert (not self.exists), ("Git repository %r already exists" % self.path) # Cannot use self.command() as self.path does not exist yet: cmd = ["git", "clone"] if depth is not None: cmd.extend(["--depth", depth]) if recursive: cmd.append("--recursive") cmd.extend(["--", address, self.path]) command.Command(*cmd, exit_code=0)
def list_classpath_entries( coordinates, scope="runtime", local_repo=None, ): """Lists the classpath entries. Args: coordinates: Collection of Artifact to examine. scope: Optional Maven scope to determine the classpath for. Default is runtime. local_repo: Optional explicit Maven local repository to use. Returns: An iterable of classpath entries. """ with tempfile.NamedTemporaryFile(prefix="pom.", suffix=".xml") as pom_file, \ tempfile.NamedTemporaryFile(prefix="maven-classpath.", suffix=".txt") as tfile: with open(pom_file.name, "wt") as file: file.write( workflow_task.format_pom_file( artf=artifact.Artifact("unknown", "unknown", "unknown"), compile_deps=coordinates, )) args = [ "mvn", "--batch-mode", "--file={}".format(pom_file.name), ] if local_repo is not None: args += ["-Dmaven.repo.local={}".format(local_repo)] args += [ "dependency:build-classpath", "-DincludeScope={}".format(scope), "-Dmdep.cpFile={}".format(tfile.name), ] cmd = command.Command(args=args) log_maven_output(cmd.output_lines) with open(tfile.name, "rt") as file: return file.read().split(":")
def Start(self, timeout=10.0): """Starts the KijiREST server. Args: timeout: Timeout in seconds, while waiting for the process to start. Returns: True if the process is running, False otherwise. """ pid = self.pid if pid is not None: logging.info('KijiREST already running as PID %d', pid) return base.MakeDir(self._logs_dir) base.MakeDir(os.path.dirname(self._pid_file_path)) assert os.path.exists(self._conf_dir), self._conf_dir for jar_path in self._jar_paths: assert os.path.exists(jar_path), jar_path # Build environment for the KijiREST daemon: env = dict(os.environ) kiji_classpath = env.get('KIJI_CLASSPATH') if kiji_classpath is None: jar_paths = self._jar_paths else: jar_paths = list(self._jar_paths) jar_paths.extend(kiji_classpath.split(':')) logging.info( 'Starting KijiREST server for HBase cluster %s on %s (admin %s).', self.hbase_uri, 'http://%s:%d' % self.address, 'http://%s:%d' % self.admin_address) env.update( KIJI_CLASSPATH=':'.join(jar_paths), KIJI_REST_CONF_DIR=self._conf_dir, KIJI_REST_JAVA_ARGUMENTS=' '.join(self._jvm_args), KIJI_REST_LOGS_DIR=self._logs_dir, PIDFILE=self._pid_file_path, ) cmd = command.Command( args=[self._kiji_rest_path, 'start'], env=env, ) logging.info('Waiting for the KijiREST process to start') deadline = time.time() + timeout while (self.pid is None) and (time.time() < deadline): sys.stdout.write('.') sys.stdout.flush() time.sleep(0.1) sys.stdout.write('\n') if self.pid is None: logging.error('KijiREST process not started') return False pid = self.pid logging.info('KijiREST started with PID %d', pid) client = self.GetClient() ping_success = client.Ping() while ((not ping_success) and (self.pid is not None) and (time.time() < deadline)): sys.stdout.write('.') sys.stdout.flush() time.sleep(0.1) ping_success = client.Ping() sys.stdout.write('\n') if ping_success: logging.info('KijiREST with PID %d : ping OK', pid) return True elif self.pid is None: logging.info('KijiREST with PID %d died', pid) return False else: logging.info('KijiREST with PID %d : ping not OK after %fs', pid, timeout) return False
def test_exit_code(self): command.Command('false', exit_code=1)
def test_args_list(self): command.Command(args=['false'], exit_code=1)
def test_command(self): cmd = command.Command('/bin/ls', '-ald', '/tmp', exit_code=0) self.assertEqual(0, cmd.exit_code) self.assertTrue('/tmp' in cmd.output_text)