eva-sub-cli 0.6.0__tar.gz → 0.6.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. eva_sub_cli-0.6.2/.github/workflows/integration-tests.yml +56 -0
  2. {eva_sub_cli-0.6.0/eva_sub_cli.egg-info → eva_sub_cli-0.6.2}/PKG-INFO +1 -1
  3. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/docker/Dockerfile +1 -1
  4. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/docs/input_file_overview.md +2 -1
  5. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/_version.py +3 -3
  6. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/etc/eva_schema.json +1 -2
  7. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/etc/spreadsheet2json_conf.yaml +1 -0
  8. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/executables/check_metadata_semantics.py +8 -3
  9. eva_sub_cli-0.6.2/eva_sub_cli/executables/format_metadata.py +42 -0
  10. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/executables/samples_checker.py +13 -12
  11. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/executables/xlsx2json.py +5 -4
  12. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/file_utils.py +0 -23
  13. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/nextflow/validation.nf +52 -6
  14. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/semantic_metadata.py +15 -1
  15. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/validators/docker_validator.py +1 -1
  16. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/validators/validator.py +12 -10
  17. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2/eva_sub_cli.egg-info}/PKG-INFO +1 -1
  18. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli.egg-info/SOURCES.txt +13 -0
  19. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli.egg-info/entry_points.txt +1 -0
  20. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/pyproject.toml +1 -0
  21. eva_sub_cli-0.6.2/tests/resources/EVA_Submission_test_with_links.xlsx +0 -0
  22. eva_sub_cli-0.6.2/tests/resources/sample_checker/evidence_type.yaml +6 -0
  23. eva_sub_cli-0.6.2/tests/resources/sample_in_vcf_check/allele_freq.vcf +9 -0
  24. eva_sub_cli-0.6.2/tests/resources/sample_in_vcf_check/fake_fasta.fa +2 -0
  25. eva_sub_cli-0.6.2/tests/resources/sample_in_vcf_check/genotype.vcf +7 -0
  26. eva_sub_cli-0.6.2/tests/resources/sample_in_vcf_check/metadata_af_no_sample_in_vcf.json +1 -0
  27. eva_sub_cli-0.6.2/tests/resources/sample_in_vcf_check/metadata_af_with_sample_in_vcf.json +1 -0
  28. eva_sub_cli-0.6.2/tests/resources/sample_in_vcf_check/metadata_genotype_no_sample_in_vcf.json +1 -0
  29. eva_sub_cli-0.6.2/tests/resources/sample_in_vcf_check/metadata_genotype_with_sample_in_vcf.json +1 -0
  30. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_file_utils.py +1 -32
  31. eva_sub_cli-0.6.2/tests/test_format_metadata.py +64 -0
  32. eva_sub_cli-0.6.2/tests/test_native_validator_sample_in_vcf.py +96 -0
  33. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_samples_checker.py +2 -1
  34. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_semantic_metadata.py +43 -17
  35. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_utils.py +3 -1
  36. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_validator.py +33 -2
  37. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_xlsx2json.py +29 -0
  38. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/.github/workflows/publish.yml +0 -0
  39. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/.github/workflows/publish_docs.yml +0 -0
  40. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/.github/workflows/tests.yml +0 -0
  41. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/.github/workflows/trigger-eva-sub-cli-integration-tests.yml +0 -0
  42. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/.gitignore +0 -0
  43. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/LICENSE +0 -0
  44. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/README.md +0 -0
  45. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/conda/build.sh +0 -0
  46. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/conda/meta.yaml +0 -0
  47. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/docs/README.md +0 -0
  48. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/docs/_config.yml +0 -0
  49. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/docs/how_to_submit.md +0 -0
  50. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/docs/installation.md +0 -0
  51. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/docs/using_nextflow.md +0 -0
  52. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/docs/validation_overview.md +0 -0
  53. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/__init__.py +0 -0
  54. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/auth.py +0 -0
  55. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/call_home.py +0 -0
  56. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/date_utils.py +0 -0
  57. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/etc/EVA_Submission_Example.xlsx +0 -0
  58. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/etc/EVA_Submission_template.xlsx +0 -0
  59. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/etc/call_home_payload_schema.json +0 -0
  60. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/etc/eva-biosamples.json +0 -0
  61. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/etc/eva_logo.png +0 -0
  62. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/etc/spreadsheet2json_conf_V2.yaml +0 -0
  63. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/exceptions/__init__.py +0 -0
  64. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/exceptions/invalid_file_type_exception.py +0 -0
  65. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/exceptions/metadata_template_version_exception.py +0 -0
  66. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/exceptions/submission_not_found_exception.py +0 -0
  67. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/exceptions/submission_status_exception.py +0 -0
  68. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/exceptions/submission_upload_exception.py +0 -0
  69. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/executables/__init__.py +0 -0
  70. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/executables/check_fasta_insdc.py +0 -0
  71. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/executables/cli.py +0 -0
  72. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/executables/evidence_type_checker.py +0 -0
  73. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/executables/trim_down.py +0 -0
  74. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/html/fasta_check.html +0 -0
  75. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/html/file_validation.html +0 -0
  76. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/html/metadata_validation.html +0 -0
  77. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/html/project_details.html +0 -0
  78. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/html/report.html +0 -0
  79. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/html/sample_name_check.html +0 -0
  80. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/html/shallow_validation.html +0 -0
  81. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/text/fasta_check.txt +0 -0
  82. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/text/file_validation.txt +0 -0
  83. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/text/metadata_validation.txt +0 -0
  84. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/text/project_details.txt +0 -0
  85. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/text/report.txt +0 -0
  86. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/text/sample_name_check.txt +0 -0
  87. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/jinja_templates/text/shallow_validation.txt +0 -0
  88. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/metadata.py +0 -0
  89. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/orchestrator.py +0 -0
  90. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/report.py +0 -0
  91. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/submission_ws.py +0 -0
  92. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/submit.py +0 -0
  93. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/utils.py +0 -0
  94. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/validators/__init__.py +0 -0
  95. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/validators/native_validator.py +0 -0
  96. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli/validators/validation_results_parsers.py +0 -0
  97. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli.egg-info/dependency_links.txt +0 -0
  98. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli.egg-info/requires.txt +0 -0
  99. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/eva_sub_cli.egg-info/top_level.txt +0 -0
  100. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/pytest.ini +0 -0
  101. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/requirements.txt +0 -0
  102. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/setup.cfg +0 -0
  103. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/setup.py +0 -0
  104. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/build_and_test_docker_locally.py +0 -0
  105. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/ignore_test_nextflow_validation.yml +0 -0
  106. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_Docker_Test.xlsx +0 -0
  107. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test.json +0 -0
  108. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test.xlsx +0 -0
  109. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test_V2.xlsx +0 -0
  110. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test_fails.xlsx +0 -0
  111. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test_version_missing.xlsx +0 -0
  112. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test_with_asm_report.json +0 -0
  113. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test_with_non_vcf_files.json +0 -0
  114. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test_with_non_vcf_files.xlsx +0 -0
  115. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test_with_project_accession.json +0 -0
  116. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/EVA_Submission_test_with_project_accession.xlsx +0 -0
  117. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/assembly_check/invalid.vcf.assembly_check.log +0 -0
  118. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/assembly_check/invalid.vcf.text_assembly_report.txt +0 -0
  119. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/assembly_reports/input_passed.txt +0 -0
  120. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/fasta_files/Saccharomyces_cerevisiae_I.fa +0 -0
  121. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/fasta_files/input_passed.fa +0 -0
  122. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/fasta_files/multi_seq.fa +0 -0
  123. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/metadata_with_filename.json +0 -0
  124. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/sample_checker/example1.vcf.gz +0 -0
  125. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/sample_checker/example2.vcf +0 -0
  126. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/sample_checker/example3.vcf +0 -0
  127. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/sample_checker/metadata.json +0 -0
  128. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/expected_metadata_json_report.html +0 -0
  129. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/expected_metadata_json_report.txt +0 -0
  130. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/expected_metadata_xlsx_report.html +0 -0
  131. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/expected_metadata_xlsx_report.txt +0 -0
  132. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/expected_report_metadata_json_process_not_run.html +0 -0
  133. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/expected_report_metadata_json_process_not_run.txt +0 -0
  134. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/expected_shallow_metadata_xlsx_report.html +0 -0
  135. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/expected_shallow_metadata_xlsx_report.txt +0 -0
  136. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.assembly_check.log +0 -0
  137. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.text_assembly_report.1680102476700.txt +0 -0
  138. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/assembly_check/input_passed.vcf.valid_assembly_report.1680102476700.txt +0 -0
  139. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/metadata.json +0 -0
  140. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/other_validations/evidence_type_checker.yml +0 -0
  141. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/other_validations/file_info.txt +0 -0
  142. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/other_validations/input_passed.fa_check.yml +0 -0
  143. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/other_validations/input_passed_trim_down.yml +0 -0
  144. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/other_validations/metadata_conversion_errors.yml +0 -0
  145. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/other_validations/metadata_semantic_check.yml +0 -0
  146. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/other_validations/metadata_validation.txt +0 -0
  147. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/other_validations/sample_checker.yml +0 -0
  148. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.errors.1680102476854.db +0 -0
  149. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.errors.1680102476854.txt +0 -0
  150. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/validation_reports/validation_output/vcf_format/input_passed.vcf.vcf_format.log +0 -0
  151. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/vcf_files/example2.vcf.gz +0 -0
  152. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/vcf_files/example2.vcf.gz.tbi +0 -0
  153. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/resources/vcf_files/input_passed.vcf +0 -0
  154. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_auth.py +0 -0
  155. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_call_home.py +0 -0
  156. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_check_fasta_insdc.py +0 -0
  157. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_cli.py +0 -0
  158. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_docker_validator.py +0 -0
  159. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_evidence_type_checker.py +0 -0
  160. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_metadata.py +0 -0
  161. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_orchestrator.py +0 -0
  162. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_report.py +0 -0
  163. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_submit.py +0 -0
  164. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_trim_down.py +0 -0
  165. {eva_sub_cli-0.6.0 → eva_sub_cli-0.6.2}/tests/test_validaton_results_parsers.py +0 -0
@@ -0,0 +1,56 @@
1
+ name: Integration tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main]
8
+
9
+ env:
10
+ VCF_VALIDATOR_VERSION: "0.10.2"
11
+ NXF_VER: "23.10.0"
12
+
13
+ jobs:
14
+ integration-tests:
15
+ runs-on: ubuntu-latest
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python 3.11
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.11"
24
+
25
+ - name: Install Java and Node
26
+ run: sudo apt update && sudo apt install -y default-jdk nodejs npm git curl
27
+
28
+ - name: Install vcf-validator and vcf-assembly-checker
29
+ run: |
30
+ curl -LJo /usr/local/bin/vcf_validator \
31
+ https://github.com/EBIvariation/vcf-validator/releases/download/v${VCF_VALIDATOR_VERSION}/vcf_validator_linux
32
+ curl -LJo /usr/local/bin/vcf_assembly_checker \
33
+ https://github.com/EBIvariation/vcf-validator/releases/download/v${VCF_VALIDATOR_VERSION}/vcf_assembly_checker_linux
34
+ chmod 755 /usr/local/bin/vcf_validator /usr/local/bin/vcf_assembly_checker
35
+
36
+ - name: Install biovalidator
37
+ run: |
38
+ git clone https://github.com/elixir-europe/biovalidator.git
39
+ cd biovalidator
40
+ npm install
41
+ sudo npm link
42
+
43
+ - name: Install Nextflow
44
+ run: |
45
+ curl -L "https://github.com/nextflow-io/nextflow/releases/download/v${NXF_VER}/nextflow-${NXF_VER}-all" | bash
46
+ sudo mv nextflow /usr/local/bin/
47
+
48
+ - name: Install Python dependencies
49
+ run: |
50
+ python -m pip install --upgrade pip
51
+ pip install pytest
52
+ python -m pip install .
53
+
54
+ - name: Run integration tests
55
+ run: |
56
+ PYTHONPATH=. pytest tests -m integration
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eva_sub_cli
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: EBI EVA - validation and submission command line tool
5
5
  Classifier: Development Status :: 5 - Production/Stable
6
6
  Classifier: Environment :: Console
@@ -1,4 +1,4 @@
1
- FROM --platform=linux/amd64 python:3.10
1
+ FROM python:3.10
2
2
 
3
3
  ENV vcf_validator_version=0.10.2
4
4
  ENV NXF_VER=23.10.0
@@ -98,7 +98,8 @@ alias, which is a shortened identifier you must provide for each analysis.
98
98
 
99
99
  This is where you describe the biological samples used for your analyses. Each row describes one sample and must include
100
100
  the Analysis Alias to indicate which analysis it belongs to, and "Sample Name in VCF" which is the exact name of the
101
- sample as it appears in the VCF file.
101
+ sample as it appears in the VCF file. If you are submitting a VCF without sample names (containing only allele frequencies),
102
+ then you can omit the "Sample Name in VCF" column.
102
103
 
103
104
  We accept preregistered samples, which should be provided using BioSamples sample or sampleset accessions. Please
104
105
  ensure these are publicly accessible, as otherwise EVA will not be able to validate them.
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.6.0'
32
- __version_tuple__ = version_tuple = (0, 6, 0)
31
+ __version__ = version = '0.6.2'
32
+ __version_tuple__ = version_tuple = (0, 6, 2)
33
33
 
34
- __commit_id__ = commit_id = 'g9b7431423'
34
+ __commit_id__ = commit_id = 'g1dbfe4351'
@@ -318,7 +318,6 @@
318
318
  {
319
319
  "required": [
320
320
  "analysisAlias",
321
- "sampleInVCF",
322
321
  "bioSampleObject"
323
322
  ]
324
323
  }
@@ -334,7 +333,7 @@
334
333
  },
335
334
  "sampleInVCF": {
336
335
  "type": "string",
337
- "description": "Sample Name used in the VCF file"
336
+ "description": "Sample Name used in the VCF file. It is a required field when genotypes are provided."
338
337
  },
339
338
  "bioSampleAccession": {
340
339
  "type": "string",
@@ -77,6 +77,7 @@ Analysis:
77
77
  Phasing: boolean
78
78
  Date: date
79
79
  Software: list
80
+ Link(s): list
80
81
 
81
82
  Sample:
82
83
  header_row: 3
@@ -1,18 +1,23 @@
1
1
  import argparse
2
2
  import json
3
3
 
4
+ import yaml
5
+
4
6
  from eva_sub_cli.semantic_metadata import SemanticMetadataChecker
5
7
 
6
8
 
7
9
  def main():
8
10
  arg_parser = argparse.ArgumentParser(description='Perform semantic checks on the metadata')
9
11
  arg_parser.add_argument('--metadata_json', required=True, dest='metadata_json', help='EVA metadata json file')
12
+ arg_parser.add_argument('--evidence_type_results', required=True, dest='evidence_type_results', help='Results of the evidence check')
10
13
  arg_parser.add_argument('--output_yaml', required=True, dest='output_yaml',
11
14
  help='Path to the location of the results')
12
15
  args = arg_parser.parse_args()
13
16
 
14
17
  with open(args.metadata_json) as open_json:
15
18
  metadata = json.load(open_json)
16
- checker = SemanticMetadataChecker(metadata)
17
- checker.check_all()
18
- checker.write_result_yaml(args.output_yaml)
19
+ with open(args.evidence_type_results) as open_yaml:
20
+ evidence_type_results = yaml.safe_load(open_yaml)
21
+ checker = SemanticMetadataChecker(metadata, evidence_type_results)
22
+ checker.check_all()
23
+ checker.write_result_yaml(args.output_yaml)
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env python3
2
+ import argparse
3
+ import json
4
+ import shutil
5
+
6
+ from ebi_eva_common_pyutils.logger import logging_config
7
+ logger = logging_config.get_logger(__name__)
8
+
9
+ def format_experiment_type(json_file_input, json_file_output):
10
+ try:
11
+ with open(json_file_input, 'r') as input:
12
+ json_data = json.load(input)
13
+
14
+ for analysis_item in json_data.get("analysis", []):
15
+ original_experiment_type = analysis_item.get("experimentType", "")
16
+ logger.info(f"Formatting metadata - experiment type to capitalized - {original_experiment_type}")
17
+ experiment_type_capital = original_experiment_type.capitalize()
18
+ analysis_item["experimentType"] = experiment_type_capital or ""
19
+
20
+ with open(json_file_output, 'w') as output:
21
+ json.dump(json_data, output, indent=4)
22
+ return json_file_output
23
+
24
+ except (FileNotFoundError, json.JSONDecodeError, KeyError) as e:
25
+ # if the try block fails, copy the input file (because nextflow is expecting the output file).
26
+ logger.error(f"Failed to process JSON: {e}")
27
+ shutil.copy(json_file_input, json_file_output)
28
+ return None
29
+
30
+
31
+ def main():
32
+ arg_parser = argparse.ArgumentParser(
33
+ description='Formats experiment type for the metadata.')
34
+ arg_parser.add_argument('--metadata_json_input', required=True, dest='metadata_json_input',
35
+ help='EVA metadata json file INPUT')
36
+ arg_parser.add_argument('--metadata_json_output', required=True, dest='metadata_json_output',
37
+ help='EVA metadata json file OUTPUT')
38
+ args = arg_parser.parse_args()
39
+ format_experiment_type(args.metadata_json_input, args.metadata_json_output)
40
+
41
+ if __name__ == "__main__":
42
+ main()
@@ -54,7 +54,7 @@ def compare_names_in_files_and_samples(sample_name_in_analysis, sample_name_per_
54
54
  more_metadata_submitted_files)
55
55
 
56
56
 
57
- def compare_all_analysis(metadata, files_per_analysis):
57
+ def compare_all_analysis(metadata, files_per_analysis, evidence_type_results):
58
58
  overall_differences = False
59
59
  results_per_analysis_alias = {}
60
60
  all_analysis_alias = set(metadata.samples_per_analysis) | set(files_per_analysis)
@@ -65,7 +65,7 @@ def compare_all_analysis(metadata, files_per_analysis):
65
65
  for file_path in files_per_analysis.get(analysis_alias, [])
66
66
  }
67
67
 
68
- if need_to_check_samples(sample_name_per_file):
68
+ if need_to_check_samples(evidence_type_results, analysis_alias):
69
69
  (
70
70
  has_difference, more_per_submitted_files_metadata,
71
71
  more_submitted_files_metadata, more_metadata_submitted_files
@@ -89,13 +89,9 @@ def compare_all_analysis(metadata, files_per_analysis):
89
89
  return overall_differences, results_per_analysis_alias
90
90
 
91
91
 
92
- def need_to_check_samples(sample_name_per_file):
93
- no_samples_in_vcf = all(len(v) == 0 for v in sample_name_per_file.values())
94
- if no_samples_in_vcf:
95
- evidence_types_for_vcf_files = [detect_vcf_evidence_type(vcf_file) for vcf_file in sample_name_per_file.keys()]
96
- if set(evidence_types_for_vcf_files) == {'allele_frequency'}:
97
- return False
98
-
92
+ def need_to_check_samples(evidence_type_results, analysis_alias):
93
+ if evidence_type_results.get(analysis_alias, {}).get('evidence_type') == 'allele_frequency':
94
+ return False
99
95
  return True
100
96
 
101
97
 
@@ -107,14 +103,16 @@ def write_result_yaml(output_yaml, overall_differences, results_per_analysis_ali
107
103
  }, stream=open_yaml)
108
104
 
109
105
 
110
- def check_sample_name_concordance(metadata_json, vcf_files, output_yaml):
106
+ def check_sample_name_concordance(metadata_json, vcf_files, output_yaml, evidence_type_result_file):
111
107
  """
112
108
  Take the metadata following EVA standard and formatted in JSON then compare the sample names in it to the ones
113
109
  found in the VCF files
114
110
  """
115
111
  metadata = EvaMetadataJson(metadata_json)
112
+ with open(evidence_type_result_file) as open_yaml:
113
+ evidence_type_results = yaml.safe_load(open_yaml)
116
114
  file_path_per_analysis = associate_vcf_path_with_analysis(metadata, vcf_files)
117
- overall_differences, results_per_analysis_alias = compare_all_analysis(metadata, file_path_per_analysis)
115
+ overall_differences, results_per_analysis_alias = compare_all_analysis(metadata, file_path_per_analysis, evidence_type_results)
118
116
  write_result_yaml(output_yaml, overall_differences, results_per_analysis_alias)
119
117
 
120
118
 
@@ -127,7 +125,10 @@ def main():
127
125
  help='Path to the vcf files to compare to the metadata')
128
126
  arg_parser.add_argument('--output_yaml', required=True, dest='output_yaml',
129
127
  help='Path to the location of the results')
128
+ arg_parser.add_argument('--evidence_type_results', required=True, dest='evidence_type_results',
129
+ help='Results of the evidence check')
130
+
130
131
 
131
132
  args = arg_parser.parse_args()
132
133
  logging_config.add_stdout_handler()
133
- check_sample_name_concordance(args.metadata_json, args.vcf_files, args.output_yaml)
134
+ check_sample_name_concordance(args.metadata_json, args.vcf_files, args.output_yaml, args.evidence_type_results)
@@ -225,8 +225,9 @@ class XlsxParser:
225
225
  return str(value)
226
226
 
227
227
  def get_sample_data_with_split_analysis_alias(self, data, analysis_alias, sample_name_in_vcf):
228
- analysis_alias_list = data[analysis_alias].split(',')
229
- sample_in_vcf_val = data[sample_name_in_vcf]
228
+ analysis_alias_val = data.get(analysis_alias)
229
+ analysis_alias_list = analysis_alias_val.split(',') if analysis_alias_val else []
230
+ sample_in_vcf_val = data.get(sample_name_in_vcf)
230
231
  return {analysis_alias: analysis_alias_list, sample_name_in_vcf: sample_in_vcf_val}
231
232
 
232
233
  def get_sample_json_data(self):
@@ -245,8 +246,8 @@ class XlsxParser:
245
246
  sample_data.update(bioSampleAccession=json_value[bio_sample_acc])
246
247
  sample_json[json_key].append(sample_data)
247
248
  else:
248
- json_value.pop(analysis_alias)
249
- json_value.pop(sample_name_in_vcf)
249
+ json_value.pop(analysis_alias, None)
250
+ json_value.pop(sample_name_in_vcf, None)
250
251
 
251
252
  biosample_obj = self.get_biosample_object(json_value)
252
253
  sample_data.update(bioSampleObject=biosample_obj)
@@ -1,7 +1,6 @@
1
1
  import glob
2
2
  import gzip
3
3
  import os
4
- import shutil
5
4
  import time
6
5
  from itertools import groupby
7
6
 
@@ -132,28 +131,6 @@ def _assess_vcf_evidence_type_manual(vcf_file):
132
131
  open_file.close()
133
132
 
134
133
 
135
- def backup_file_or_directory(file_name, max_backups=None):
136
- """
137
- Rename a file or directory by adding a '.1' at the end. If the '.1' file exists it move it to a '.2' and so on.
138
- Keep at most the specified number of backups, if None will keep all.
139
- """
140
- suffix = 1
141
- backup_name = f'{file_name}.{suffix}'
142
- while os.path.exists(backup_name):
143
- suffix += 1
144
- backup_name = f'{file_name}.{suffix}'
145
-
146
- for i in range(suffix, 1, -1):
147
- if max_backups and i > max_backups:
148
- if os.path.isfile(file_name):
149
- os.remove(f'{file_name}.{i - 1}')
150
- else:
151
- shutil.rmtree(f'{file_name}.{i - 1}')
152
- else:
153
- os.rename(f'{file_name}.{i - 1}', f'{file_name}.{i}')
154
- os.rename(file_name, file_name + '.1')
155
-
156
-
157
134
  def open_gzip_if_required(input_file, mode='r'):
158
135
  """Open a file in read mode using gzip if the file extension says .gz"""
159
136
  if input_file.endswith('.gz'):
@@ -42,7 +42,8 @@ params.python_scripts = [
42
42
  "fasta_checker": "check_fasta_insdc.py",
43
43
  "xlsx2json": "xlsx2json.py",
44
44
  "semantic_checker": "check_metadata_semantics.py",
45
- "trim_down": "trim_down.py"
45
+ "trim_down": "trim_down.py",
46
+ "format_metadata": "format_metadata.py"
46
47
  ]
47
48
  // prefix to prepend to all provided path
48
49
  params.base_dir = ""
@@ -98,27 +99,41 @@ workflow {
98
99
  convert_xlsx_2_json(joinBasePath(params.metadata_xlsx))
99
100
  metadata_json = convert_xlsx_2_json.out.metadata_json
100
101
  } else {
101
- metadata_json = joinBasePath(params.metadata_json)
102
+ metadata_json = file(joinBasePath(params.metadata_json), checkIfExists:true)
102
103
  }
104
+
105
+ metadata_json_format(metadata_json)
106
+ metadata_json = metadata_json_format.out.metadata_formatted_json
103
107
  // File size and MD5
104
108
  generate_file_size_and_md5_digests(vcf_files)
105
109
  collect_file_size_and_md5(generate_file_size_and_md5_digests.out.file_size_and_digest_info.collect())
106
110
 
107
111
  // Task-specific processing
112
+ evidence_type_results = null
113
+
108
114
  if (params.tasks.contains(VCF_CHECK)) {
109
115
  check_vcf_valid(vcf_and_ref_ch)
110
116
  evidence_type_check(metadata_json, vcf_files.collect())
117
+ evidence_type_results = evidence_type_check.out.evidence_type_checker_yml
111
118
  }
112
119
  if (params.tasks.contains(ASSEMBLY_CHECK)) {
113
120
  check_vcf_reference(vcf_and_ref_ch)
114
121
  insdc_checker(metadata_json, fasta_to_vcfs)
115
122
  }
116
123
  if (params.tasks.contains(METADATA_CHECK)) {
124
+ if (!evidence_type_results) {
125
+ evidence_type_check(metadata_json, vcf_files.collect())
126
+ evidence_type_results = evidence_type_check.out.evidence_type_checker_yml
127
+ }
117
128
  metadata_json_validation(metadata_json)
118
- metadata_semantic_check(metadata_json)
129
+ metadata_semantic_check(metadata_json, evidence_type_results)
119
130
  }
120
131
  if (params.tasks.contains(SAMPLE_CHECK)) {
121
- sample_name_concordance(metadata_json, vcf_files.collect())
132
+ if (!evidence_type_results){
133
+ evidence_type_check(metadata_json, vcf_files.collect())
134
+ evidence_type_results = evidence_type_check.out.evidence_type_checker_yml
135
+ }
136
+ sample_name_concordance(metadata_json, vcf_files.collect(), evidence_type_results)
122
137
  }
123
138
  }
124
139
 
@@ -166,6 +181,7 @@ process check_vcf_valid {
166
181
  """
167
182
  trap 'if [[ \$? == 1 ]]; then exit 0; fi' EXIT
168
183
 
184
+ rm -rf ${output_dir}/vcf_format
169
185
  mkdir -p vcf_format
170
186
  $params.executable.vcf_validator -i $vcf -r text -o vcf_format --require-evidence > vcf_format/${vcf}.vcf_format.log 2>&1
171
187
  """
@@ -195,6 +211,7 @@ process check_vcf_reference {
195
211
  """
196
212
  trap 'if [[ \$? == 1 || \$? == 139 ]]; then exit 0; fi' EXIT
197
213
 
214
+ rm -rf ${output_dir}/assembly_check
198
215
  mkdir -p assembly_check
199
216
  $params.executable.vcf_assembly_checker -i $vcf -f $fasta $report_opt -r summary,text -o assembly_check --require-genbank > assembly_check/${vcf}.assembly_check.log 2>&1
200
217
  """
@@ -263,6 +280,28 @@ process convert_xlsx_2_json {
263
280
  """
264
281
  }
265
282
 
283
+ process metadata_json_format {
284
+
285
+ label 'short_time', 'small_mem'
286
+
287
+ publishDir output_dir,
288
+ overwrite: true,
289
+ mode: "copy"
290
+
291
+ input:
292
+ path(metadata_json)
293
+
294
+ output:
295
+ path "metadata_formatted.log", emit: metadata_formatted
296
+ path "metadata_formatted_case_insensitive.json", emit: metadata_formatted_json
297
+
298
+ script:
299
+ def output_json = "metadata_formatted_case_insensitive.json"
300
+ """
301
+ $params.python_scripts.format_metadata --metadata_json_input $metadata_json --metadata_json_output $output_json > metadata_formatted.log 2>&1
302
+ """
303
+ }
304
+
266
305
  process metadata_json_validation {
267
306
 
268
307
  label 'short_time', 'small_mem'
@@ -294,6 +333,7 @@ process sample_name_concordance {
294
333
  input:
295
334
  path(metadata_json)
296
335
  path(vcf_files)
336
+ path(evidence_type_results)
297
337
 
298
338
  output:
299
339
  path "sample_checker.yml", emit: sample_checker_yml
@@ -301,7 +341,9 @@ process sample_name_concordance {
301
341
 
302
342
  script:
303
343
  """
304
- $params.python_scripts.samples_checker --metadata_json $metadata_json --vcf_files $vcf_files --output_yaml sample_checker.yml > sample_checker.log 2>&1
344
+ $params.python_scripts.samples_checker --metadata_json $metadata_json \
345
+ --vcf_files $vcf_files --output_yaml sample_checker.yml \
346
+ --evidence_type_results $evidence_type_results > sample_checker.log 2>&1
305
347
  """
306
348
  }
307
349
 
@@ -362,6 +404,7 @@ process metadata_semantic_check {
362
404
 
363
405
  input:
364
406
  path(metadata_json)
407
+ path(evidence_type_results)
365
408
 
366
409
  output:
367
410
  path "metadata_semantic_check.yml", emit: metadata_semantic_check_yml
@@ -369,6 +412,9 @@ process metadata_semantic_check {
369
412
 
370
413
  script:
371
414
  """
372
- $params.python_scripts.semantic_checker --metadata_json $metadata_json --output_yaml metadata_semantic_check.yml > semantic_checker.log 2>&1
415
+ $params.python_scripts.semantic_checker \
416
+ --metadata_json $metadata_json \
417
+ --evidence_type_results $evidence_type_results \
418
+ --output_yaml metadata_semantic_check.yml > semantic_checker.log 2>&1
373
419
  """
374
420
  }
@@ -20,6 +20,7 @@ PROJECT_ACCESSION_KEY = 'projectAccession'
20
20
  PARENT_PROJECT_KEY = 'parentProject'
21
21
  CHILD_PROJECTS_KEY = 'childProjects'
22
22
  PEER_PROJECTS_KEY = 'peerProjects'
23
+ SAMPLE_IN_VCF_KEY = 'sampleInVCF'
23
24
  BIOSAMPLE_OBJECT_KEY = 'bioSampleObject'
24
25
  BIOSAMPLE_ACCESSION_KEY = 'bioSampleAccession'
25
26
  CHARACTERISTICS_KEY = 'characteristics'
@@ -40,9 +41,10 @@ def cast_list(l, type_to_cast=str):
40
41
 
41
42
  class SemanticMetadataChecker(AppLogger):
42
43
 
43
- def __init__(self, metadata, sample_checklist='ERC000011'):
44
+ def __init__(self, metadata, evidence_type_results, sample_checklist='ERC000011'):
44
45
  self.sample_checklist = sample_checklist
45
46
  self.metadata = metadata
47
+ self.evidence_type_results = evidence_type_results
46
48
  self.errors = []
47
49
  # Caches whether taxonomy code is valid or not, and maps to scientific name if valid
48
50
  self.taxonomy_valid = {}
@@ -60,6 +62,7 @@ class SemanticMetadataChecker(AppLogger):
60
62
  self.check_all_analysis_run_accessions()
61
63
  self.check_analysis_alias_coherence()
62
64
  self.check_all_analysis_contain_samples()
65
+ self.check_all_samples_have_sample_in_vcf()
63
66
  self.check_hold_date()
64
67
 
65
68
  def check_hold_date(self):
@@ -316,3 +319,14 @@ class SemanticMetadataChecker(AppLogger):
316
319
  json_path = f'/{ANALYSIS_KEY}/{idx}'
317
320
  self.add_error(property=json_path,
318
321
  description=f'No sample found for the analysis. Should have at the least one sample.')
322
+
323
+ def check_all_samples_have_sample_in_vcf(self):
324
+ for idx, sample in enumerate(self.metadata[SAMPLE_KEY]):
325
+ json_path = f'/{SAMPLE_KEY}/{idx}/{SAMPLE_IN_VCF_KEY}'
326
+ analysis_aliases = sample.get(ANALYSIS_ALIAS_KEY, [])
327
+ if any([self.evidence_type_results.get(analysis_alias, {}).get('evidence_type') != 'allele_frequency' for
328
+ analysis_alias in analysis_aliases]):
329
+ # SampleInVCF is required
330
+ if sample.get(SAMPLE_IN_VCF_KEY) is None or sample.get(SAMPLE_IN_VCF_KEY) == '':
331
+ self.add_error(json_path, f'{SAMPLE_IN_VCF_KEY} must be provided when Genotypes are present in the VCF file')
332
+
@@ -9,7 +9,7 @@ from retry import retry
9
9
  from eva_sub_cli.validators.validator import Validator, ALL_VALIDATION_TASKS
10
10
 
11
11
  default_container_image = 'ebivariation/eva-sub-cli'
12
- default_container_tag = 'v0.0.11'
12
+ default_container_tag = 'v0.0.13'
13
13
  container_validation_dir = '/opt/vcf_validation'
14
14
  container_validation_output_dir = 'vcf_validation_output'
15
15
 
@@ -3,17 +3,18 @@ import csv
3
3
  import datetime
4
4
  import logging
5
5
  import os
6
+ import shutil
6
7
  from functools import lru_cache, cached_property
7
8
 
8
9
  import yaml
9
10
  from ebi_eva_common_pyutils.command_utils import run_command_with_output
10
11
  from ebi_eva_common_pyutils.config import WritableConfig
11
- from ebi_eva_common_pyutils.logger import logging_config, AppLogger
12
+ from ebi_eva_common_pyutils.logger import AppLogger
12
13
  from packaging import version
13
14
 
14
15
  import eva_sub_cli
15
16
  from eva_sub_cli import ETC_DIR, SUB_CLI_CONFIG_FILE, __version__
16
- from eva_sub_cli.file_utils import backup_file_or_directory, resolve_single_file_path
17
+ from eva_sub_cli.file_utils import resolve_single_file_path
17
18
  from eva_sub_cli.metadata import EvaMetadataJson
18
19
  from eva_sub_cli.report import generate_html_report, generate_text_report
19
20
  from eva_sub_cli.validators.validation_results_parsers import parse_assembly_check_log, parse_assembly_check_report, \
@@ -43,7 +44,6 @@ RUN_STATUS_KEY = 'run_status'
43
44
  PASS = 'pass'
44
45
 
45
46
 
46
-
47
47
  class Validator(AppLogger):
48
48
 
49
49
  def __init__(self, mapping_file, submission_dir, project_title=None, metadata_json=None, metadata_xlsx=None,
@@ -54,6 +54,7 @@ class Validator(AppLogger):
54
54
  self.tasks = validation_tasks
55
55
  self.submission_dir = submission_dir
56
56
  self.output_dir = os.path.join(submission_dir, VALIDATION_OUTPUT_DIR)
57
+ self.nextflow_work_dir = os.path.join(self.submission_dir, 'work') # Default location when we chdir in self.submission_dir
57
58
  self.validation_result_file = os.path.join(submission_dir, VALIDATION_RESULTS_FILE)
58
59
  self.mapping_file = mapping_file
59
60
  vcf_files, fasta_files = self._find_vcf_and_fasta_files()
@@ -130,20 +131,22 @@ class Validator(AppLogger):
130
131
  raise NotImplementedError
131
132
 
132
133
  def set_up_output_dir(self):
133
- if os.path.exists(self.output_dir):
134
- backup_file_or_directory(self.output_dir, max_backups=9)
135
- os.makedirs(self.output_dir, exist_ok=True)
134
+ if not os.path.exists(self.output_dir):
135
+ os.makedirs(self.output_dir, exist_ok=True)
136
136
 
137
137
  def clean_up_output_dir(self):
138
138
  # Move intermediate validation outputs into a subdir except metadata.json
139
139
  subdir = os.path.join(self.output_dir, 'other_validations')
140
- os.mkdir(subdir)
140
+ os.makedirs(subdir, exist_ok=True)
141
141
  for file_name in os.listdir(self.output_dir):
142
- if file_name == 'metadata.json':
142
+ if file_name in ['metadata.json', 'report.txt', 'report.html']:
143
143
  continue
144
144
  file_path = os.path.join(self.output_dir, file_name)
145
145
  if os.path.isfile(file_path):
146
146
  os.rename(file_path, os.path.join(subdir, file_name))
147
+ # Remove the nextflow work directory if it exists
148
+ if os.path.exists(self.nextflow_work_dir):
149
+ shutil.rmtree(self.nextflow_work_dir)
147
150
 
148
151
  @staticmethod
149
152
  def _validation_file_path_for(file_path):
@@ -210,7 +213,6 @@ class Validator(AppLogger):
210
213
  del self.results[SHALLOW_VALIDATION]['required']
211
214
  del self.results[SHALLOW_VALIDATION]['requested']
212
215
 
213
-
214
216
  def _collect_validation_workflow_results(self):
215
217
  # Collect information from the output and summarise in the config
216
218
  if self.shallow_validation:
@@ -550,7 +552,7 @@ class Validator(AppLogger):
550
552
  file_path_2_file_size[vcf_file] = file_size
551
553
  file_name_2_file_size[os.path.basename(vcf_file)] = file_size
552
554
  else:
553
- error_txt = f"Cannot locate file_info.txt at {os.path.join(self.output_dir, 'other_validations', 'file_info.txt')}"
555
+ error_txt = f"Cannot locate file_info.txt at {os.path.join(self.output_dir, 'other_validations', 'file_info.txt')}"
554
556
  self.error(error_txt)
555
557
  raise FileNotFoundError(error_txt)
556
558
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eva_sub_cli
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: EBI EVA - validation and submission command line tool
5
5
  Classifier: Development Status :: 5 - Production/Stable
6
6
  Classifier: Environment :: Console
@@ -6,6 +6,7 @@ pytest.ini
6
6
  requirements.txt
7
7
  setup.cfg
8
8
  setup.py
9
+ .github/workflows/integration-tests.yml
9
10
  .github/workflows/publish.yml
10
11
  .github/workflows/publish_docs.yml
11
12
  .github/workflows/tests.yml
@@ -58,6 +59,7 @@ eva_sub_cli/executables/check_fasta_insdc.py
58
59
  eva_sub_cli/executables/check_metadata_semantics.py
59
60
  eva_sub_cli/executables/cli.py
60
61
  eva_sub_cli/executables/evidence_type_checker.py
62
+ eva_sub_cli/executables/format_metadata.py
61
63
  eva_sub_cli/executables/samples_checker.py
62
64
  eva_sub_cli/executables/trim_down.py
63
65
  eva_sub_cli/executables/xlsx2json.py
@@ -90,7 +92,9 @@ tests/test_cli.py
90
92
  tests/test_docker_validator.py
91
93
  tests/test_evidence_type_checker.py
92
94
  tests/test_file_utils.py
95
+ tests/test_format_metadata.py
93
96
  tests/test_metadata.py
97
+ tests/test_native_validator_sample_in_vcf.py
94
98
  tests/test_orchestrator.py
95
99
  tests/test_report.py
96
100
  tests/test_samples_checker.py
@@ -108,6 +112,7 @@ tests/resources/EVA_Submission_test_V2.xlsx
108
112
  tests/resources/EVA_Submission_test_fails.xlsx
109
113
  tests/resources/EVA_Submission_test_version_missing.xlsx
110
114
  tests/resources/EVA_Submission_test_with_asm_report.json
115
+ tests/resources/EVA_Submission_test_with_links.xlsx
111
116
  tests/resources/EVA_Submission_test_with_non_vcf_files.json
112
117
  tests/resources/EVA_Submission_test_with_non_vcf_files.xlsx
113
118
  tests/resources/EVA_Submission_test_with_project_accession.json
@@ -119,10 +124,18 @@ tests/resources/assembly_reports/input_passed.txt
119
124
  tests/resources/fasta_files/Saccharomyces_cerevisiae_I.fa
120
125
  tests/resources/fasta_files/input_passed.fa
121
126
  tests/resources/fasta_files/multi_seq.fa
127
+ tests/resources/sample_checker/evidence_type.yaml
122
128
  tests/resources/sample_checker/example1.vcf.gz
123
129
  tests/resources/sample_checker/example2.vcf
124
130
  tests/resources/sample_checker/example3.vcf
125
131
  tests/resources/sample_checker/metadata.json
132
+ tests/resources/sample_in_vcf_check/allele_freq.vcf
133
+ tests/resources/sample_in_vcf_check/fake_fasta.fa
134
+ tests/resources/sample_in_vcf_check/genotype.vcf
135
+ tests/resources/sample_in_vcf_check/metadata_af_no_sample_in_vcf.json
136
+ tests/resources/sample_in_vcf_check/metadata_af_with_sample_in_vcf.json
137
+ tests/resources/sample_in_vcf_check/metadata_genotype_no_sample_in_vcf.json
138
+ tests/resources/sample_in_vcf_check/metadata_genotype_with_sample_in_vcf.json
126
139
  tests/resources/validation_reports/expected_metadata_json_report.html
127
140
  tests/resources/validation_reports/expected_metadata_json_report.txt
128
141
  tests/resources/validation_reports/expected_metadata_xlsx_report.html
@@ -3,6 +3,7 @@ check_fasta_insdc.py = eva_sub_cli.executables.check_fasta_insdc:main
3
3
  check_metadata_semantics.py = eva_sub_cli.executables.check_metadata_semantics:main
4
4
  eva-sub-cli.py = eva_sub_cli.executables.cli:main
5
5
  evidence_type_checker.py = eva_sub_cli.executables.evidence_type_checker:main
6
+ format_metadata.py = eva_sub_cli.executables.format_metadata:main
6
7
  samples_checker.py = eva_sub_cli.executables.samples_checker:main
7
8
  trim_down.py = eva_sub_cli.executables.trim_down:main
8
9
  xlsx2json.py = eva_sub_cli.executables.xlsx2json:main