def cli(ctx, paths, **kwds): """Produce diff between local repository and Tool Shed contents. By default, this will produce a diff between this repository and what would be uploaded to the Tool Shed with the `shed_upload` command - but this command can be made to compare other combinations of repositories. Here are some examples:: % # diff for this repository and the main Tool Shed % planemo shed_diff % # diff for this repository and the test Tool Shed % planemo shed_diff --shed_target testtoolshed % # diff for the test Tool Shed and main Tool Shed % planemo shed_diff --shed_target_source testtoolshed % # diff for two an explicitly specified repositories (ignores % # current project's shed YAML file.) % planemo shed_diff --owner peterjc --name blast_rbh --shed_target_source testtoolshed This command will return an exit code of: - 0 if there are no detected differences. - 1 if there are differences. - 2 if the target repository doesn't exist. - >200 if there are errors attempting to perform a diff. **Warning:** ``shed_diff`` doesn't inspect repository metadata, this difference applies only to the file contents of files that would actually be uploaded to the repository. """ def diff(realized_repository): return shed.diff_repo(ctx, realized_repository, **kwds) exit_code = shed.for_each_repository(ctx, diff, paths, **kwds) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Create a repository in a Galaxy Tool Shed. This will read the settings from the ``.shed.yml`` file. """ shed_context = shed.get_shed_context(ctx, **kwds) def create(realized_repository): repo_id = realized_repository.find_repository_id(ctx, shed_context) if repo_id is None: if realized_repository.create(ctx, shed_context): info("Repository created") if not kwds["skip_upload"]: return shed.upload_repository( ctx, realized_repository, **kwds ) else: return 0 else: return 2 else: return 1 exit_code = shed.for_each_repository(ctx, create, paths, **kwds) sys.exit(exit_code)
def cli(ctx, path, **kwds): """Handle possible recursion through paths for uploading files to a toolshed """ def upload(realized_repository): return __handle_upload(ctx, realized_repository, **kwds) exit_code = shed.for_each_repository(upload, path, **kwds) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Check a Tool Shed repository for common problems. """ def lint(realized_repository): return shed_lint.lint_repository(ctx, realized_repository, **kwds) kwds["fail_on_missing"] = False exit_code = shed.for_each_repository(ctx, lint, paths, **kwds) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Update repository in shed from a ``.shed.yml`` file. By default this command will update both repository metadata from ``.shed.yml`` and upload new contents from the repository directory. :: % planemo shed_update This will update the main tool shed with the repository defined by a ``.shed.yml`` file in the current working directory. Both the location of the ``.shed.yml`` and the tool shed to upload to can be easily configured. For instance, the following command can be used if ``.shed.yml`` if contained in ``path/to/repo`` and the desire is to update the test tool shed. :: % planemo shed_update --shed_target testtoolshed path/to/repo Another important option is ``--check_diff`` - this doesn't affect the updating of shed metadata but it will check for differences before uploading new contents to the tool shed. This may important because the tool shed will automatically populate certain attributes in tool shed artifact files (such as ``tool_dependencies.xml``) and this may cause unwanted installable revisions to be created when there are no important changes. The lower-level ``shed_upload`` command should be used instead if the repository doesn't define complete metadata in a ``.shed.yml``. """ tsi = shed.tool_shed_client(ctx, **kwds) def update(realized_repository): upload_ok = True if not kwds["skip_upload"]: upload_ok = not shed.upload_repository( ctx, realized_repository, **kwds ) repo_id = realized_repository.find_repository_id(ctx, tsi) metadata_ok = True if not kwds["skip_metadata"]: metadata_ok = realized_repository.update(ctx, tsi, repo_id) if metadata_ok: info("Repository metadata updated.") else: error("Failed to update repository metadata.") if metadata_ok and upload_ok: return 0 else: error("Failed to update a repository.") return 1 exit_code = shed.for_each_repository(ctx, update, paths, **kwds) sys.exit(exit_code)
def cli(ctx, path, recursive=False, **kwds): """Check a Tool Shed repository for common problems. """ def lint(realized_repository): path = realized_repository.real_path return shed_lint.lint_repository(ctx, path, **kwds) exit_code = shed.for_each_repository(lint, path) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Update repository in shed from a ``.shed.yml`` file. By default this command will update both repository metadata from ``.shed.yml`` and upload new contents from the repository directory. :: % planemo shed_update This will update the main tool shed with the repository defined by a ``.shed.yml`` file in the current working directory. Both the location of the ``.shed.yml`` and the tool shed to upload to can be easily configured. For instance, the following command can be used if ``.shed.yml`` if contained in ``path/to/repo`` and the desire is to update the test tool shed. :: % planemo shed_update --shed_target testtoolshed path/to/repo Another important option is ``--check_diff`` - this doesn't affect the updating of shed metadata but it will check for differences before uploading new contents to the tool shed. This may important because the tool shed will automatically populate certain attributes in tool shed artifact files (such as ``tool_dependencies.xml``) and this may cause unwanted installable revisions to be created when there are no important changes. The lower-level ``shed_upload`` command should be used instead if the repository doesn't define complete metadata in a ``.shed.yml``. """ tsi = shed.tool_shed_client(ctx, **kwds) def update(realized_repository): upload_ok = True if not kwds["skip_upload"]: upload_ok = not shed.upload_repository(ctx, realized_repository, ** kwds) repo_id = realized_repository.find_repository_id(ctx, tsi) metadata_ok = True if not kwds["skip_metadata"]: metadata_ok = realized_repository.update(ctx, tsi, repo_id) if metadata_ok: info("Repository metadata updated.") else: error("Failed to update repository metadata.") if metadata_ok and upload_ok: return 0 else: error("Failed to update a repository.") return 1 exit_code = shed.for_each_repository(ctx, update, paths, **kwds) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Download a tool repository as a tarball from the tool shed and extract to the specified directory. """ shed_context = shed.get_shed_context(ctx, read_only=True, **kwds) def download(realized_repository): return shed.download_tarball(ctx, shed_context, realized_repository, **kwds) exit_code = shed.for_each_repository(ctx, download, paths, **kwds) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Download a tool repository as a tarball from the tool shed and extract to the specified directory. """ tsi = shed.tool_shed_client(ctx, read_only=True, **kwds) def download(realized_repository): return shed.download_tarball(ctx, tsi, realized_repository, **kwds) exit_code = shed.for_each_repository(ctx, download, paths, **kwds) sys.exit(exit_code)
def cli(ctx, path, recursive=False, **kwds): """Check a Tool Shed repository for common problems. """ def lint(path): return shed_lint.lint_repository(ctx, path, **kwds) if recursive: exit_code = shed.for_each_repository(lint, path) else: exit_code = lint(path) sys.exit(exit_code)
def cli(ctx, path, **kwds): """Create a Galaxy tool tarball from a ``.shed.yml`` file. """ def build(realized_repository): tarpath = shed.build_tarball(realized_repository.real_path) outpath = realized_repository.real_path + ".tar.gz" shutil.move(tarpath, outpath) print("Created: %s" % (outpath)) return 0 exit_code = shed.for_each_repository(ctx, build, [path], **kwds) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Download tool from Tool Shed into directory. Download a tool repository as a tarball from the tool shed and extract to the specified directory. """ shed_context = shed.get_shed_context(ctx, read_only=True, **kwds) def download(realized_repository): return shed.download_tarball(ctx, shed_context, realized_repository, **kwds) exit_code = shed.for_each_repository(ctx, download, paths, **kwds) sys.exit(exit_code)
def cli(ctx, path, **kwds): """Create a Galaxy tool tarball. This will use the .shed.yml file to prepare a tarball (which you could upload to the Tool Shed manually). """ def build(realized_repository): tarpath = shed.build_tarball(realized_repository.path) outpath = realized_repository.real_path + ".tar.gz" shutil.move(tarpath, outpath) print("Created: %s" % (outpath)) return 0 exit_code = shed.for_each_repository(ctx, build, [path], **kwds) sys.exit(exit_code)
def cli(ctx, path, **kwds): """Create a repository in a Galaxy Tool Shed from a ``.shed.yml`` file. """ tsi = shed.tool_shed_client(ctx, **kwds) def create(realized_reposiotry): repo_id = realized_reposiotry.find_repository_id(ctx, tsi) if repo_id is None: if realized_reposiotry.create(ctx, tsi): info("Repository created") return 0 else: return 2 else: return 1 exit_code = shed.for_each_repository(create, path, **kwds) sys.exit(exit_code)
def cli(ctx, path, **kwds): """Handle possible recursion through paths for uploading files to a toolshed """ def upload(path): return __handle_upload(ctx, path, **kwds) if kwds['recursive']: if kwds['name'] is not None: error("--name is incompatible with --recursive") return -1 if kwds['tar'] is not None: error("--tar is incompatible with --recursive") return -1 exit_code = shed.for_each_repository(upload, path) else: exit_code = upload(path) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Check a Tool Shed repository for common problems. With the ``--tools`` flag, this command lints actual Galaxy tools in addition to tool shed artifacts. With the ``--urls`` flag, this command searches for ``<package>$URL</package>`` and download actions which specify URLs. Each of those are accessed individually. By default, this tool requests the first hundred or so bytes of each listed URL and validates that a 200 OK was received. In tool XML files, the ``--urls`` option checks through the help text for mentioned URLs and checks those. """ def lint(realized_repository): return shed_lint.lint_repository(ctx, realized_repository, **kwds) kwds["fail_on_missing"] = False exit_code = shed.for_each_repository(ctx, lint, paths, **kwds) ctx.exit(exit_code)
def cli(ctx, paths, **kwds): """Check a Tool Shed repository for common problems. With the ``--tools`` flag, this command lints actual Galaxy tools in addition to tool shed artifacts. With the ``--urls`` flag, this command searches for ``<package>$URL</package>`` and download actions which specify URLs. Each of those are accessed individually. By default, this tool requests the first hundred or so bytes of each listed URL and validates that a 200 OK was received. In tool XML files, the ``--urls`` option checks through the help text for mentioned URLs and checks those. """ def lint(realized_repository): return shed_lint.lint_repository(ctx, realized_repository, **kwds) kwds["fail_on_missing"] = False exit_code = shed.for_each_repository(ctx, lint, paths, **kwds) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Low-level command to upload tarballs. Generally, ``shed_update`` should be used instead since it also updates both tool shed contents (via tar ball generation and upload) as well as metadata (to handle metadata changes in ``.shed.yml`` files). \b % planemo shed_upload --tar_only ~/ % tar -tzf shed_upload.tar.gz test-data/blastdb.loc ... tools/ncbi_blast_plus/tool_dependencies.xml % tar -tzf shed_upload.tar.gz | wc -l 117 """ def upload(realized_repository): return shed.upload_repository(ctx, realized_repository, **kwds) exit_code = shed.for_each_repository(ctx, upload, paths, **kwds) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Produce diff between local repository and Tool Shed contents. By default, this will produce a diff between this repository and what would be uploaded to the Tool Shed with the `shed_upload` command - but this command can be made to compare other combinations of repositories. Here are some examples:: % # diff for this repository and the main Tool Shed % planemo shed_diff % # diff for this repository and the test Tool Shed % planemo shed_diff --shed_target testtoolshed % # diff for the test Tool Shed and main Tool Shed % planemo shed_diff --shed_target_source testtoolshed % # diff for two an explicitly specified repositories (ignores % # current project's shed YAML file.) % planemo shed_diff --owner peterjc --name blast_rbh --shed_target_source testtoolshed """ def diff(realized_repository): return shed.diff_repo(ctx, realized_repository, **kwds) exit_code = shed.for_each_repository(ctx, diff, paths, **kwds) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Update repository in shed from a ``.shed.yml`` file. By default this command will update both repository metadata from ``.shed.yml`` and upload new contents from the repository directory. :: % planemo shed_update This will update the main tool shed with the repository defined by a ``.shed.yml`` file in the current working directory. Both the location of the ``.shed.yml`` and the tool shed to upload to can be easily configured. For instance, the following command can be used if ``.shed.yml`` if contained in ``path/to/repo`` and the desire is to update the test tool shed. :: % planemo shed_update --shed_target testtoolshed path/to/repo Another important option is ``--check_diff`` - this doesn't affect the updating of shed metadata but it will check for differences before uploading new contents to the tool shed. This may important because the tool shed will automatically populate certain attributes in tool shed artifact files (such as ``tool_dependencies.xml``) and this may cause unwanted installable revisions to be created when there are no important changes. The lower-level ``shed_upload`` command should be used instead if the repository doesn't define complete metadata in a ``.shed.yml``. """ # In a little bit of cheating, we're defining this variable here to collect # a "report" on the shed_update command collected_data = { 'results': { 'total': 0, 'errors': 0, 'failures': 0, 'skips': 0, }, 'tests': [], } shed_context = shed.get_shed_context(ctx, **kwds) def update(realized_repository): collected_data['results']['total'] += 1 upload_ret_code = 0 upload_ok = True if not kwds["skip_upload"]: upload_ret_code = shed.upload_repository( ctx, realized_repository, **kwds ) upload_ok = not upload_ret_code if upload_ret_code == 2: collected_data['results']['failures'] += 1 collected_data['tests'].append({ 'classname': realized_repository.name, 'result': 2, }) error("Failed to update repository it does not exist " "in target ToolShed.") return upload_ret_code repo_id = realized_repository.find_repository_id(ctx, shed_context) metadata_ok = True if not kwds["skip_metadata"]: metadata_ok = realized_repository.update(ctx, shed_context, repo_id) if metadata_ok: info("Repository metadata updated.") else: error("Failed to update repository metadata.") if metadata_ok and upload_ok: collected_data['tests'].append({ 'classname': realized_repository.name, 'result': 0, }) return 0 elif upload_ok: collected_data['results']['skips'] += 1 collected_data['tests'].append({ 'classname': realized_repository.name, 'result': 3, }) error("Repo updated but metadata was not.") return 1 else: collected_data['results']['failures'] += 1 collected_data['tests'].append({ 'classname': realized_repository.name, 'result': 1, }) error("Failed to update a repository.") return 1 exit_code = shed.for_each_repository(ctx, update, paths, **kwds) if kwds.get('report_xunit', False): with open(kwds['report_xunit'], 'w') as handle: handle.write(build_report.template_data( collected_data, template_name='update_xunit.tpl')) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Update repository in shed from a ``.shed.yml`` file. By default this command will update both repository metadata from ``.shed.yml`` and upload new contents from the repository directory. :: % planemo shed_update This will update the main tool shed with the repository defined by a ``.shed.yml`` file in the current working directory. Both the location of the ``.shed.yml`` and the tool shed to upload to can be easily configured. For instance, the following command can be used if ``.shed.yml`` if contained in ``path/to/repo`` and the desire is to update the test tool shed. :: % planemo shed_update --shed_target testtoolshed path/to/repo Another important option is ``--check_diff`` - this doesn't affect the updating of shed metadata but it will check for differences before uploading new contents to the tool shed. This may important because the tool shed will automatically populate certain attributes in tool shed artifact files (such as ``tool_dependencies.xml``) and this may cause unwanted installable revisions to be created when there are no important changes. The lower-level ``shed_upload`` command should be used instead if the repository doesn't define complete metadata in a ``.shed.yml``. """ # In a little bit of cheating, we're defining this variable here to collect # a "report" on the shed_update command collected_data = { 'results': { 'total': 0, 'errors': 0, 'failures': 0, 'skips': 0, }, 'tests': [], } shed_context = shed.get_shed_context(ctx, **kwds) def update(realized_repository): collected_data['results']['total'] += 1 upload_ret_code = 0 upload_ok = True if not kwds["skip_upload"]: upload_ret_code = shed.upload_repository(ctx, realized_repository, **kwds) upload_ok = not upload_ret_code if upload_ret_code == 2: collected_data['results']['failures'] += 1 collected_data['tests'].append({ 'classname': realized_repository.name, 'result': 2, }) error("Failed to update repository it does not exist " "in target ToolShed.") return upload_ret_code repo_id = realized_repository.find_repository_id(ctx, shed_context) metadata_ok = True if not kwds["skip_metadata"]: metadata_ok = realized_repository.update(ctx, shed_context, repo_id) if metadata_ok: info("Repository metadata updated.") else: error("Failed to update repository metadata.") if metadata_ok and upload_ok: collected_data['tests'].append({ 'classname': realized_repository.name, 'result': 0, }) return 0 elif upload_ok: collected_data['results']['skips'] += 1 collected_data['tests'].append({ 'classname': realized_repository.name, 'result': 3, }) error("Repo updated but metadata was not.") return 1 else: collected_data['results']['failures'] += 1 collected_data['tests'].append({ 'classname': realized_repository.name, 'result': 1, }) error("Failed to update a repository.") return 1 exit_code = shed.for_each_repository(ctx, update, paths, **kwds) if kwds.get('report_xunit', False): with open(kwds['report_xunit'], 'w') as handle: handle.write( build_report.template_data(collected_data, template_name='update_xunit.tpl')) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """diff between local repository and Tool Shed. By default, this will produce a diff between this repository and what would be uploaded to the Tool Shed with the `shed_upload` command - but this command can be made to compare other combinations of repositories. Here are some examples:: % # diff for this repository and the main Tool Shed % planemo shed_diff % # diff for this repository and the test Tool Shed % planemo shed_diff --shed_target testtoolshed % # diff for the test Tool Shed and main Tool Shed % planemo shed_diff --shed_target_source testtoolshed % # diff for two an explicitly specified repositories (ignores % # current project's shed YAML file.) % planemo shed_diff --owner peterjc --name blast_rbh --shed_target_source testtoolshed This command will return an exit code of: - 0 if there are no detected differences. - 1 if there are differences. - 2 if the target repository doesn't exist. - >200 if there are errors attempting to perform a diff. **Warning:** ``shed_diff`` doesn't inspect repository metadata, this difference applies only to the file contents of files that would actually be uploaded to the repository. """ # In a little bit of cheating, we're defining this variable here to collect # a "report" on our shed_diff collected_data = { 'results': { 'total': 0, 'errors': 0, 'failures': 0, 'skips': 0, }, 'suitename': 'shed_diff', 'tests': [], } def diff(realized_repository): # We create a temporary redirection from kwds's # output to our tempfile. This lets us capture the # diff and redirect it to their requested location as # well as to the XUnit report. diff_output = tempfile.NamedTemporaryFile(mode='r') user_requested_output = kwds.get('output', None) # Replace their output handle with ours kwds['output'] = diff_output.name captured_io = {} with captured_io_for_xunit(kwds, captured_io): result = shed.diff_repo(ctx, realized_repository, **kwds) # May be extraneous but just want to ensure entire file is written # before a copy is made. diff_output.flush() # Redirect a copy to user_requested_output if they did: if user_requested_output is not None: shutil.copy(diff_output.name, user_requested_output) else: with open(diff_output.name, "r") as f: sys.stdout.write(f.read()) # Rewind to the start of the file and read it in its entirety diff_output.seek(0) diff_output_contents = diff_output.read() diff_output.close() # Collect data about what happened collected_data['results']['total'] += 1 xunit_case = { 'name': 'shed-diff', 'classname': realized_repository.name, 'time': captured_io["time"], 'stdout': captured_io["stdout"], 'stderr': captured_io["stderr"], } if result >= 200: collected_data['results']['errors'] += 1 xunit_case.update({ 'errorType': 'DiffError', 'errorMessage': 'Error diffing repositories', 'errorContent': escape(diff_output_contents), 'time': captured_io["time"], }) elif result > 2: collected_data['results']['failures'] += 1 xunit_case.update({ 'errorType': 'PlanemoDiffError', 'errorMessage': 'Planemo error diffing repositories', 'errorContent': escape(diff_output_contents), }) elif result == 2: collected_data['results']['failures'] += 1 xunit_case.update({ 'errorType': 'RepoDoesNotExist', 'errorMessage': 'Target Repository does not exist', 'errorContent': escape(diff_output_contents), }) elif result == 1: collected_data['results']['failures'] += 1 xunit_case.update({ 'errorType': 'Different', 'errorMessage': 'Repository is different', 'errorContent': escape(diff_output_contents), }) # Append our xunit test case collected_data['tests'].append(xunit_case) return result exit_code = shed.for_each_repository(ctx, diff, paths, **kwds) if kwds.get('report_xunit', False): with open(kwds['report_xunit'], 'wb') as handle: template_data = build_report.template_data( collected_data, template_name='xunit.tpl' ) handle.write(template_data.encode('ascii', 'xmlcharrefreplace')) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Update repository in shed from a ``.shed.yml`` file. By default this command will update both repository metadata from ``.shed.yml`` and upload new contents from the repository directory. :: % planemo shed_update This will update the main tool shed with the repository defined by a ``.shed.yml`` file in the current working directory. Both the location of the ``.shed.yml`` and the tool shed to upload to can be easily configured. For instance, the following command can be used if ``.shed.yml`` if contained in ``path/to/repo`` and the desire is to update the test tool shed. :: % planemo shed_update --shed_target testtoolshed path/to/repo Another important option is ``--check_diff`` - this doesn't affect the updating of shed metadata but it will check for differences before uploading new contents to the tool shed. This may important because the tool shed will automatically populate certain attributes in tool shed artifact files (such as ``tool_dependencies.xml``) and this may cause unwanted installable revisions to be created when there are no important changes. The lower-level ``shed_upload`` command should be used instead if the repository doesn't define complete metadata in a ``.shed.yml``. """ # In a little bit of cheating, we're defining this variable here to collect # a "report" on the shed_update command collected_data = { 'results': { 'total': 0, 'errors': 0, 'failures': 0, 'skips': 0, }, 'suitename': 'update', 'tests': [], } shed_context = shed.get_shed_context(ctx, **kwds) def update(realized_repository): collected_data['results']['total'] += 1 skip_upload = kwds["skip_upload"] skip_metadata = kwds["skip_metadata"] upload_ret_code = 0 upload_ok = True captured_io = {} if not skip_upload: with captured_io_for_xunit(kwds, captured_io): upload_ret_code = shed.upload_repository( ctx, realized_repository, **kwds ) upload_ok = not upload_ret_code repo_result = { 'classname': realized_repository.name, 'time': captured_io.get("time", None), 'name': 'shed-update', 'stdout': captured_io.get("stdout", None), 'stderr': captured_io.get("stderr", None), } # Now that we've uploaded (or skipped appropriately), collect results. if upload_ret_code == 2: collected_data['results']['failures'] += 1 repo_result.update({ 'errorType': 'FailedUpdate', 'errorMessage': 'Failed to update repository as it does not exist in target ToolShed', }) collected_data['tests'].append(repo_result) error("Failed to update repository it does not exist " "in target ToolShed.") return upload_ret_code exit = 0 metadata_ok = True if not skip_metadata: repo_id = shed.handle_force_create(realized_repository, ctx, shed_context, **kwds) # failing to create the repo, give up if repo_id is None: exit = shed.report_non_existent_repository(realized_repository) metadata_ok = False else: metadata_ok = realized_repository.update(ctx, shed_context, repo_id) else: info("Skipping repository metadata update.") if not metadata_ok: error("Failed to update repository metadata.") if metadata_ok and upload_ok: pass elif upload_ok: collected_data['results']['skips'] += 1 repo_result.update({ 'errorType': 'FailedMetadata', 'errorMessage': 'Failed to update repository metadata', }) if not skip_upload: error("Repo updated but metadata was not.") exit = exit or 1 else: collected_data['results']['failures'] += 1 repo_result.update({ 'errorType': 'FailedUpdate', 'errorMessage': 'Failed to update repository', }) error("Failed to update a repository.") exit = exit or 1 collected_data['tests'].append(repo_result) return exit exit_code = shed.for_each_repository(ctx, update, paths, **kwds) if kwds.get('report_xunit', False): with open(kwds['report_xunit'], 'w') as handle: handle.write(build_report.template_data( collected_data, template_name='xunit.tpl') .encode('ascii', 'xmlcharrefreplace')) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Update repository in shed from a ``.shed.yml`` file. By default this command will update both repository metadata from ``.shed.yml`` and upload new contents from the repository directory. :: % planemo shed_update This will update the main tool shed with the repository defined by a ``.shed.yml`` file in the current working directory. Both the location of the ``.shed.yml`` and the tool shed to upload to can be easily configured. For instance, the following command can be used if ``.shed.yml`` if contained in ``path/to/repo`` and the desire is to update the test tool shed. :: % planemo shed_update --shed_target testtoolshed path/to/repo Another important option is ``--check_diff`` - this doesn't affect the updating of shed metadata but it will check for differences before uploading new contents to the tool shed. This may important because the tool shed will automatically populate certain attributes in tool shed artifact files (such as ``tool_dependencies.xml``) and this may cause unwanted installable revisions to be created when there are no important changes. The lower-level ``shed_upload`` command should be used instead if the repository doesn't define complete metadata in a ``.shed.yml``. """ # In a little bit of cheating, we're defining this variable here to collect # a "report" on the shed_update command collected_data = { 'results': { 'total': 0, 'errors': 0, 'failures': 0, 'skips': 0, }, 'suitename': 'update', 'tests': [], } shed_context = shed.get_shed_context(ctx, **kwds) def update(realized_repository): collected_data['results']['total'] += 1 skip_upload = kwds["skip_upload"] skip_metadata = kwds["skip_metadata"] upload_ret_code = 0 upload_ok = True captured_io = {} if not skip_upload: with captured_io_for_xunit(kwds, captured_io): upload_ret_code = shed.upload_repository( ctx, realized_repository, **kwds) upload_ok = not upload_ret_code repo_result = { 'classname': realized_repository.name, 'time': captured_io.get("time", None), 'name': 'shed-update', 'stdout': captured_io.get("stdout", None), 'stderr': captured_io.get("stderr", None), } # Now that we've uploaded (or skipped appropriately), collect results. if upload_ret_code == 2: collected_data['results']['failures'] += 1 repo_result.update({ 'errorType': 'FailedUpdate', 'errorMessage': 'Failed to update repository as it does not exist in target ToolShed', }) collected_data['tests'].append(repo_result) error("Failed to update repository it does not exist " "in target ToolShed.") return upload_ret_code exit = 0 metadata_ok = True if not skip_metadata: repo_id = shed.handle_force_create(realized_repository, ctx, shed_context, **kwds) # failing to create the repo, give up if repo_id is None: exit = shed.report_non_existent_repository(realized_repository) metadata_ok = False else: metadata_ok = realized_repository.update( ctx, shed_context, repo_id) else: info("Skipping repository metadata update.") if not metadata_ok: error("Failed to update repository metadata.") if metadata_ok and upload_ok: pass elif upload_ok: collected_data['results']['skips'] += 1 repo_result.update({ 'errorType': 'FailedMetadata', 'errorMessage': 'Failed to update repository metadata', }) if not skip_upload: error("Repo updated but metadata was not.") exit = exit or 1 else: collected_data['results']['failures'] += 1 repo_result.update({ 'errorType': 'FailedUpdate', 'errorMessage': 'Failed to update repository', }) error("Failed to update a repository.") exit = exit or 1 collected_data['tests'].append(repo_result) return exit exit_code = shed.for_each_repository(ctx, update, paths, **kwds) if kwds.get('report_xunit', False): with open(kwds['report_xunit'], 'w') as handle: handle.write( build_report.template_data(collected_data, template_name='xunit.tpl').encode( 'ascii', 'xmlcharrefreplace')) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """diff between local repository and Tool Shed. By default, this will produce a diff between this repository and what would be uploaded to the Tool Shed with the `shed_upload` command - but this command can be made to compare other combinations of repositories. Here are some examples \b $ # diff for this repository and the main Tool Shed $ planemo shed_diff $ # diff for this repository and the test Tool Shed $ planemo shed_diff --shed_target testtoolshed $ # diff for the test Tool Shed and main Tool Shed $ planemo shed_diff --shed_target_source testtoolshed $ # diff for two an explicitly specified repositories (ignores $ # current project's shed YAML file.) $ planemo shed_diff --owner peterjc --name blast_rbh --shed_target_source testtoolshed This command will return an exit code of: - 0 if there are no detected differences. - 1 if there are differences. - 2 if the target repository doesn't exist. - >200 if there are errors attempting to perform a diff. **Warning:** ``shed_diff`` doesn't inspect repository metadata, this difference applies only to the file contents of files that would actually be uploaded to the repository. """ # In a little bit of cheating, we're defining this variable here to collect # a "report" on our shed_diff collected_data = { 'results': { 'total': 0, 'errors': 0, 'failures': 0, 'skips': 0, }, 'suitename': 'shed_diff', 'tests': [], } def diff(realized_repository): # We create a temporary redirection from kwds's # output to our tempfile. This lets us capture the # diff and redirect it to their requested location as # well as to the XUnit report. diff_output = tempfile.NamedTemporaryFile(mode='r') user_requested_output = kwds.get('output', None) # Replace their output handle with ours kwds['output'] = diff_output.name captured_io = {} with captured_io_for_xunit(kwds, captured_io): result = shed.diff_repo(ctx, realized_repository, **kwds) # May be extraneous but just want to ensure entire file is written # before a copy is made. diff_output.flush() # Redirect a copy to user_requested_output if they did: if user_requested_output is not None: shutil.copy(diff_output.name, user_requested_output) else: with open(diff_output.name, "r") as f: sys.stdout.write(f.read()) # Rewind to the start of the file and read it in its entirety diff_output.seek(0) diff_output_contents = diff_output.read() diff_output.close() # Collect data about what happened collected_data['results']['total'] += 1 xunit_case = { 'name': 'shed-diff', 'classname': realized_repository.name, 'time': captured_io["time"], 'stdout': captured_io["stdout"], 'stderr': captured_io["stderr"], } if result >= 200: collected_data['results']['errors'] += 1 xunit_case.update({ 'errorType': 'DiffError', 'errorMessage': 'Error diffing repositories', 'errorContent': escape(diff_output_contents), 'time': captured_io["time"], }) elif result > 2: collected_data['results']['failures'] += 1 xunit_case.update({ 'errorType': 'PlanemoDiffError', 'errorMessage': 'Planemo error diffing repositories', 'errorContent': escape(diff_output_contents), }) elif result == 2: collected_data['results']['failures'] += 1 xunit_case.update({ 'errorType': 'RepoDoesNotExist', 'errorMessage': 'Target Repository does not exist', 'errorContent': escape(diff_output_contents), }) elif result == 1: collected_data['results']['failures'] += 1 xunit_case.update({ 'errorType': 'Different', 'errorMessage': 'Repository is different', 'errorContent': escape(diff_output_contents), }) # Append our xunit test case collected_data['tests'].append(xunit_case) return result exit_code = shed.for_each_repository(ctx, diff, paths, **kwds) handle_report_xunit_kwd(kwds, collected_data) sys.exit(exit_code)
def cli(ctx, paths, **kwds): """Produce diff between local repository and Tool Shed contents. By default, this will produce a diff between this repository and what would be uploaded to the Tool Shed with the `shed_upload` command - but this command can be made to compare other combinations of repositories. Here are some examples:: % # diff for this repository and the main Tool Shed % planemo shed_diff % # diff for this repository and the test Tool Shed % planemo shed_diff --shed_target testtoolshed % # diff for the test Tool Shed and main Tool Shed % planemo shed_diff --shed_target_source testtoolshed % # diff for two an explicitly specified repositories (ignores % # current project's shed YAML file.) % planemo shed_diff --owner peterjc --name blast_rbh --shed_target_source testtoolshed This command will return an exit code of: - 0 if there are no detected differences. - 1 if there are differences. - 2 if the target repository doesn't exist. - >200 if there are errors attempting to perform a diff. **Warning:** ``shed_diff`` doesn't inspect repository metadata, this difference applies only to the file contents of files that would actually be uploaded to the repository. """ # In a little bit of cheating, we're defining this variable here to collect # a "report" on our shed_diff collected_data = { 'results': { 'total': 0, 'errors': 0, 'failures': 0, 'skips': 0, }, 'tests': [], } def diff(realized_repository): result = shed.diff_repo(ctx, realized_repository, **kwds) # Collect data about what happened collected_data['results']['total'] += 1 if result >= 200: collected_data['results']['errors'] += 1 elif result > 0: collected_data['results']['failures'] += 1 collected_data['tests'].append({ 'classname': realized_repository.name, 'result': result, }) return result exit_code = shed.for_each_repository(ctx, diff, paths, **kwds) if kwds.get('report_xunit', False): with open(kwds['report_xunit'], 'w') as handle: handle.write( build_report.template_data(collected_data, template_name='diff_xunit.tpl')) sys.exit(exit_code)