launchable 1.82.4__tar.gz → 1.83.0__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 (327) hide show
  1. {launchable-1.82.4 → launchable-1.83.0}/.github/workflows/bazel-test.yml +2 -2
  2. {launchable-1.82.4 → launchable-1.83.0}/.github/workflows/python-package.yml +1 -1
  3. {launchable-1.82.4 → launchable-1.83.0}/.github/workflows/update_maven_install_json.yml +1 -1
  4. {launchable-1.82.4 → launchable-1.83.0}/PKG-INFO +1 -1
  5. {launchable-1.82.4 → launchable-1.83.0}/WORKSPACE +2 -2
  6. launchable-1.83.0/launchable/commands/inspect/subset.py +144 -0
  7. launchable-1.83.0/launchable/commands/inspect/tests.py +195 -0
  8. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/record/tests.py +3 -1
  9. {launchable-1.82.4 → launchable-1.83.0}/launchable/jar/exe_deploy.jar +0 -0
  10. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/launchable.py +1 -0
  11. {launchable-1.82.4 → launchable-1.83.0}/launchable.egg-info/PKG-INFO +1 -1
  12. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/CommitGraphCollector.java +14 -1
  13. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/CountingDiffFormatter.java +2 -6
  14. {launchable-1.82.4 → launchable-1.83.0}/src/maven_install.json +11 -11
  15. launchable-1.83.0/tests/commands/inspect/test_subset.py +75 -0
  16. launchable-1.83.0/tests/commands/inspect/test_tests.py +170 -0
  17. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/test_api_error.py +20 -2
  18. {launchable-1.82.4 → launchable-1.83.0}/tests/test_plugin.py +22 -0
  19. launchable-1.82.4/launchable/commands/inspect/subset.py +0 -72
  20. launchable-1.82.4/launchable/commands/inspect/tests.py +0 -62
  21. launchable-1.82.4/tests/commands/inspect/test_subset.py +0 -41
  22. launchable-1.82.4/tests/commands/inspect/test_tests.py +0 -82
  23. {launchable-1.82.4 → launchable-1.83.0}/.bazelrc +0 -0
  24. {launchable-1.82.4 → launchable-1.83.0}/.bazelversion +0 -0
  25. {launchable-1.82.4 → launchable-1.83.0}/.editorconfig +0 -0
  26. {launchable-1.82.4 → launchable-1.83.0}/.github/release.yml +0 -0
  27. {launchable-1.82.4 → launchable-1.83.0}/.github/workflows/e2e.yml +0 -0
  28. {launchable-1.82.4 → launchable-1.83.0}/.github/workflows/python-publish.yml +0 -0
  29. {launchable-1.82.4 → launchable-1.83.0}/.gitignore +0 -0
  30. {launchable-1.82.4 → launchable-1.83.0}/.pre-commit-config.yaml +0 -0
  31. {launchable-1.82.4 → launchable-1.83.0}/.python-version +0 -0
  32. {launchable-1.82.4 → launchable-1.83.0}/.tagpr +0 -0
  33. {launchable-1.82.4 → launchable-1.83.0}/CONTRIBUTING.md +0 -0
  34. {launchable-1.82.4 → launchable-1.83.0}/Dockerfile +0 -0
  35. {launchable-1.82.4 → launchable-1.83.0}/LICENSE.txt +0 -0
  36. {launchable-1.82.4 → launchable-1.83.0}/Pipfile +0 -0
  37. {launchable-1.82.4 → launchable-1.83.0}/README.md +0 -0
  38. {launchable-1.82.4 → launchable-1.83.0}/launchable/__init__.py +0 -0
  39. {launchable-1.82.4 → launchable-1.83.0}/launchable/__main__.py +0 -0
  40. {launchable-1.82.4 → launchable-1.83.0}/launchable/app.py +0 -0
  41. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/__init__.py +0 -0
  42. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/helper.py +0 -0
  43. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/inspect/__init__.py +0 -0
  44. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/record/__init__.py +0 -0
  45. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/record/attachment.py +0 -0
  46. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/record/build.py +0 -0
  47. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/record/case_event.py +0 -0
  48. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/record/commit.py +0 -0
  49. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/record/session.py +0 -0
  50. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/split_subset.py +0 -0
  51. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/stats/__init__.py +0 -0
  52. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/stats/test_sessions.py +0 -0
  53. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/subset.py +0 -0
  54. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/test_path_writer.py +0 -0
  55. {launchable-1.82.4 → launchable-1.83.0}/launchable/commands/verify.py +0 -0
  56. {launchable-1.82.4 → launchable-1.83.0}/launchable/plugins/__init__.py +0 -0
  57. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/__init__.py +0 -0
  58. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/adb.py +0 -0
  59. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/ant.py +0 -0
  60. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/bazel.py +0 -0
  61. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/behave.py +0 -0
  62. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/ctest.py +0 -0
  63. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/cts.py +0 -0
  64. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/cucumber.py +0 -0
  65. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/cypress.py +0 -0
  66. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/dotnet.py +0 -0
  67. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/file.py +0 -0
  68. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/go_test.py +0 -0
  69. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/googletest.py +0 -0
  70. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/gradle.py +0 -0
  71. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/jest.py +0 -0
  72. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/maven.py +0 -0
  73. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/minitest.py +0 -0
  74. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/nunit.py +0 -0
  75. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/playwright.py +0 -0
  76. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/prove.py +0 -0
  77. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/pytest.py +0 -0
  78. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/raw.py +0 -0
  79. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/robot.py +0 -0
  80. {launchable-1.82.4 → launchable-1.83.0}/launchable/test_runners/rspec.py +0 -0
  81. {launchable-1.82.4 → launchable-1.83.0}/launchable/testpath.py +0 -0
  82. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/__init__.py +0 -0
  83. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/authentication.py +0 -0
  84. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/ci_provider.py +0 -0
  85. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/click.py +0 -0
  86. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/commit_ingester.py +0 -0
  87. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/env_keys.py +0 -0
  88. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/exceptions.py +0 -0
  89. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/file_name_pattern.py +0 -0
  90. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/git_log_parser.py +0 -0
  91. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/glob.py +0 -0
  92. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/gzipgen.py +0 -0
  93. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/http_client.py +0 -0
  94. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/java.py +0 -0
  95. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/key_value_type.py +0 -0
  96. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/launchable_client.py +0 -0
  97. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/link.py +0 -0
  98. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/logger.py +0 -0
  99. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/no_build.py +0 -0
  100. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/sax.py +0 -0
  101. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/session.py +0 -0
  102. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/subprocess.py +0 -0
  103. {launchable-1.82.4 → launchable-1.83.0}/launchable/utils/tracking.py +0 -0
  104. {launchable-1.82.4 → launchable-1.83.0}/launchable/version.py +0 -0
  105. {launchable-1.82.4 → launchable-1.83.0}/launchable.egg-info/SOURCES.txt +0 -0
  106. {launchable-1.82.4 → launchable-1.83.0}/launchable.egg-info/dependency_links.txt +0 -0
  107. {launchable-1.82.4 → launchable-1.83.0}/launchable.egg-info/entry_points.txt +0 -0
  108. {launchable-1.82.4 → launchable-1.83.0}/launchable.egg-info/requires.txt +0 -0
  109. {launchable-1.82.4 → launchable-1.83.0}/launchable.egg-info/top_level.txt +0 -0
  110. {launchable-1.82.4 → launchable-1.83.0}/pyproject.toml +0 -0
  111. {launchable-1.82.4 → launchable-1.83.0}/renovate.json +0 -0
  112. {launchable-1.82.4 → launchable-1.83.0}/setup.cfg +0 -0
  113. {launchable-1.82.4 → launchable-1.83.0}/setup.py +0 -0
  114. {launchable-1.82.4 → launchable-1.83.0}/src/BUILD +0 -0
  115. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/Authenticator.java +0 -0
  116. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/BUILD +0 -0
  117. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/CommitIngester.java +0 -0
  118. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/GitHubActionsAuthenticator.java +0 -0
  119. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/GitHubIdTokenAuthenticator.java +0 -0
  120. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/JSCommit.java +0 -0
  121. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/JSFileChange.java +0 -0
  122. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/ObjectRevFilter.java +0 -0
  123. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/SSLBypass.java +0 -0
  124. {launchable-1.82.4 → launchable-1.83.0}/src/main/java/com/launchableinc/ingest/commits/TokenAuthenticator.java +0 -0
  125. {launchable-1.82.4 → launchable-1.83.0}/src/test/java/com/launchableinc/ingest/commits/AllTests.java +0 -0
  126. {launchable-1.82.4 → launchable-1.83.0}/src/test/java/com/launchableinc/ingest/commits/BUILD +0 -0
  127. {launchable-1.82.4 → launchable-1.83.0}/src/test/java/com/launchableinc/ingest/commits/CommitGraphCollectorTest.java +0 -0
  128. {launchable-1.82.4 → launchable-1.83.0}/src/test/java/com/launchableinc/ingest/commits/CommitIngesterTest.java +0 -0
  129. {launchable-1.82.4 → launchable-1.83.0}/src/test/java/com/launchableinc/ingest/commits/SSLBypassTest.java +0 -0
  130. {launchable-1.82.4 → launchable-1.83.0}/src/test/java/com/launchableinc/ingest/commits/java8-compat.sh +0 -0
  131. {launchable-1.82.4 → launchable-1.83.0}/test-runner/__main__.py +0 -0
  132. {launchable-1.82.4 → launchable-1.83.0}/tests/__init__.py +0 -0
  133. {launchable-1.82.4 → launchable-1.83.0}/tests/cli_test_case.py +0 -0
  134. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/__init__.py +0 -0
  135. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/inspect/__init__.py +0 -0
  136. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/record/__init__.py +0 -0
  137. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/record/test_attachment.py +0 -0
  138. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/record/test_build.py +0 -0
  139. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/record/test_commit.py +0 -0
  140. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/record/test_session.py +0 -0
  141. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/record/test_tests.py +0 -0
  142. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/test_helper.py +0 -0
  143. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/test_split_subset.py +0 -0
  144. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/test_subset.py +0 -0
  145. {launchable-1.82.4 → launchable-1.83.0}/tests/commands/test_verify.py +0 -0
  146. {launchable-1.82.4 → launchable-1.83.0}/tests/data/adb/subset_result.json +0 -0
  147. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ant/junitreport/TEST-com.launchable.HelloWorldTest.xml +0 -0
  148. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ant/junitreport/TEST-com.launchable.library.CacheTest.xml +0 -0
  149. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ant/junitreport/TESTS-TestSuites.xml +0 -0
  150. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ant/record_test_result.json +0 -0
  151. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ant/src/com/launchable/HelloWorld.java +0 -0
  152. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ant/src/com/launchable/HelloWorldTest.java +0 -0
  153. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ant/src/com/launchable/library/Cache.java +0 -0
  154. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ant/src/com/launchable/library/CacheTest.java +0 -0
  155. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ant/subset_result.json +0 -0
  156. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test1/test.cache_status +0 -0
  157. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test1/test.xml +0 -0
  158. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test2/test.cache_status +0 -0
  159. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test2/test.xml +0 -0
  160. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test3/test.cache_status +0 -0
  161. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test3/test.xml +0 -0
  162. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test4/test.cache_status +0 -0
  163. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test4/test.xml +0 -0
  164. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test5/test.cache_status +0 -0
  165. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test5/test.xml +0 -0
  166. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test6/test.cache_status +0 -0
  167. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test6/test.xml +0 -0
  168. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test7/test.cache_status +0 -0
  169. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test7/test.xml +0 -0
  170. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test8/test.cache_status +0 -0
  171. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test8/test.xml +0 -0
  172. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test9/test.cache_status +0 -0
  173. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test9/test.xml +0 -0
  174. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/build_event.json +0 -0
  175. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/build_event_rest.json +0 -0
  176. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/record_test_result.json +0 -0
  177. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/record_test_with_build_event_json_result.json +0 -0
  178. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/record_test_with_multiple_build_event_json_result.json +0 -0
  179. {launchable-1.82.4 → launchable-1.83.0}/tests/data/bazel/subset_result.json +0 -0
  180. {launchable-1.82.4 → launchable-1.83.0}/tests/data/behave/record_test_result.json +0 -0
  181. {launchable-1.82.4 → launchable-1.83.0}/tests/data/behave/reports/report.xml +0 -0
  182. {launchable-1.82.4 → launchable-1.83.0}/tests/data/behave/subset_result.json +0 -0
  183. {launchable-1.82.4 → launchable-1.83.0}/tests/data/broken_xml/broken.xml +0 -0
  184. {launchable-1.82.4 → launchable-1.83.0}/tests/data/broken_xml/normal.xml +0 -0
  185. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ctest/Testing/latest/Test.xml +0 -0
  186. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ctest/ctest_list.json +0 -0
  187. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ctest/record_test_result.json +0 -0
  188. {launchable-1.82.4 → launchable-1.83.0}/tests/data/ctest/subset_result.json +0 -0
  189. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cts/record_test_result.json +0 -0
  190. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cts/subset_result.json +0 -0
  191. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cts/test_result.xml +0 -0
  192. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/features/foo/bar.feature +0 -0
  193. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/features/foo/is_it_friday_yet.feature +0 -0
  194. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/features/foo-bar.feature +0 -0
  195. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/features/is_it_friday_yet.feature +0 -0
  196. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/record_test_json_result.json +0 -0
  197. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/record_test_result.json +0 -0
  198. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/report/TEST-features-foo-bar.xml +0 -0
  199. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/report/TEST-features-foo-is_it_friday_yet.xml +0 -0
  200. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/report/TEST-features-is_it_friday_yet.xml +0 -0
  201. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/report/dummy.xml +0 -0
  202. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cucumber/report/result.json +0 -0
  203. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cypress/empty.json +0 -0
  204. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cypress/empty.xml +0 -0
  205. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cypress/record_test_result.json +0 -0
  206. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cypress/subset_result.json +0 -0
  207. {launchable-1.82.4 → launchable-1.83.0}/tests/data/cypress/test-result.xml +0 -0
  208. {launchable-1.82.4 → launchable-1.83.0}/tests/data/dotnet/record_test_result.json +0 -0
  209. {launchable-1.82.4 → launchable-1.83.0}/tests/data/dotnet/test-result.xml +0 -0
  210. {launchable-1.82.4 → launchable-1.83.0}/tests/data/git_log_ingest/sample.out +0 -0
  211. {launchable-1.82.4 → launchable-1.83.0}/tests/data/go_test/record_test_result.json +0 -0
  212. {launchable-1.82.4 → launchable-1.83.0}/tests/data/go_test/reportv1/reportv1.xml +0 -0
  213. {launchable-1.82.4 → launchable-1.83.0}/tests/data/go_test/reportv2/reportv2.xml +0 -0
  214. {launchable-1.82.4 → launchable-1.83.0}/tests/data/go_test/subset_result.json +0 -0
  215. {launchable-1.82.4 → launchable-1.83.0}/tests/data/googletest/fail/output.xml +0 -0
  216. {launchable-1.82.4 → launchable-1.83.0}/tests/data/googletest/fail/record_test_result.json +0 -0
  217. {launchable-1.82.4 → launchable-1.83.0}/tests/data/googletest/output_a.xml +0 -0
  218. {launchable-1.82.4 → launchable-1.83.0}/tests/data/googletest/output_b.xml +0 -0
  219. {launchable-1.82.4 → launchable-1.83.0}/tests/data/googletest/record_test_result.json +0 -0
  220. {launchable-1.82.4 → launchable-1.83.0}/tests/data/googletest/subset_result.json +0 -0
  221. {launchable-1.82.4 → launchable-1.83.0}/tests/data/gradle/java/app/src/test/java/com/launchableinc/rocket_car_gradle/App2Test.java +0 -0
  222. {launchable-1.82.4 → launchable-1.83.0}/tests/data/gradle/java/app/src/test/java/com/launchableinc/rocket_car_gradle/AppTest.java +0 -0
  223. {launchable-1.82.4 → launchable-1.83.0}/tests/data/gradle/java/app/src/test/java/com/launchableinc/rocket_car_gradle/sub/App3Test.java +0 -0
  224. {launchable-1.82.4 → launchable-1.83.0}/tests/data/gradle/recursion/expected.json +0 -0
  225. {launchable-1.82.4 → launchable-1.83.0}/tests/data/gradle/recursion/foo/bar/reports/1.xml +0 -0
  226. {launchable-1.82.4 → launchable-1.83.0}/tests/data/jest/junit.xml +0 -0
  227. {launchable-1.82.4 → launchable-1.83.0}/tests/data/jest/record_test_result.json +0 -0
  228. {launchable-1.82.4 → launchable-1.83.0}/tests/data/jest/subset_result.json +0 -0
  229. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/createdFile_1.lst +0 -0
  230. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/createdFile_2.lst +0 -0
  231. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/java/test/src/java/com/launchableinc/rocket_car_maven/App2Test.java +0 -0
  232. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/java/test/src/java/com/launchableinc/rocket_car_maven/AppTest.java +0 -0
  233. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/list.lst +0 -0
  234. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/record_test_result.json +0 -0
  235. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/reports/TEST-1.xml +0 -0
  236. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/reports/TEST-2.xml +0 -0
  237. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/reports/dummy.xml +0 -0
  238. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/subset_by_absolute_time_result.json +0 -0
  239. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/subset_by_confidence_result.json +0 -0
  240. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/subset_from_file_result.json +0 -0
  241. {launchable-1.82.4 → launchable-1.83.0}/tests/data/maven/subset_result.json +0 -0
  242. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/TEST-Admin_UserTest.xml +0 -0
  243. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/TEST-Admin_UserTest_ChildlenTest.xml +0 -0
  244. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/TEST-UserControllerTest.xml +0 -0
  245. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/TEST-UserCopyTest.xml +0 -0
  246. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/TEST-UserTest.xml +0 -0
  247. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/record_test_result.json +0 -0
  248. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/record_test_result_chunk1.json +0 -0
  249. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/record_test_result_chunk2.json +0 -0
  250. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/subset_result.json +0 -0
  251. {launchable-1.82.4 → launchable-1.83.0}/tests/data/minitest/test/example_test.rb +0 -0
  252. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/list.xml +0 -0
  253. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/nunit-reporter-bug-with-nested-type.json +0 -0
  254. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/nunit-reporter-bug-with-nested-type.xml +0 -0
  255. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/output-linux.xml +0 -0
  256. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/output-windows.xml +0 -0
  257. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/record_test_result-linux.json +0 -0
  258. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/record_test_result-windows.json +0 -0
  259. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/src/.gitignore +0 -0
  260. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/src/Program.cs +0 -0
  261. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/src/README.md +0 -0
  262. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/src/Test.cs +0 -0
  263. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/src/calc.csproj +0 -0
  264. {launchable-1.82.4 → launchable-1.83.0}/tests/data/nunit/subset_result.json +0 -0
  265. {launchable-1.82.4 → launchable-1.83.0}/tests/data/playwright/record_test_result.json +0 -0
  266. {launchable-1.82.4 → launchable-1.83.0}/tests/data/playwright/report.xml +0 -0
  267. {launchable-1.82.4 → launchable-1.83.0}/tests/data/prove/record_test_result.json +0 -0
  268. {launchable-1.82.4 → launchable-1.83.0}/tests/data/prove/report.xml +0 -0
  269. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/record_test_result.json +0 -0
  270. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/record_test_result_json.json +0 -0
  271. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/report.json +0 -0
  272. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/report.xml +0 -0
  273. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/subset_result.json +0 -0
  274. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/tests/conftest.py +0 -0
  275. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/tests/fooo/__init__.py +0 -0
  276. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/tests/fooo/filenameonly_test.py +0 -0
  277. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/tests/fooo/func4_test.py +0 -0
  278. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/tests/funcs3_test.py +0 -0
  279. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/tests/test_funcs1.py +0 -0
  280. {launchable-1.82.4 → launchable-1.83.0}/tests/data/pytest/tests/test_funcs2.py +0 -0
  281. {launchable-1.82.4 → launchable-1.83.0}/tests/data/robot/dryrun.xml +0 -0
  282. {launchable-1.82.4 → launchable-1.83.0}/tests/data/robot/output.xml +0 -0
  283. {launchable-1.82.4 → launchable-1.83.0}/tests/data/robot/record_test_executed_only_one_file_result.json +0 -0
  284. {launchable-1.82.4 → launchable-1.83.0}/tests/data/robot/record_test_result.json +0 -0
  285. {launchable-1.82.4 → launchable-1.83.0}/tests/data/robot/single-output.xml +0 -0
  286. {launchable-1.82.4 → launchable-1.83.0}/tests/data/robot/subset_result.json +0 -0
  287. {launchable-1.82.4 → launchable-1.83.0}/tests/data/rspec/record_test_result.json +0 -0
  288. {launchable-1.82.4 → launchable-1.83.0}/tests/data/rspec/rspec.xml +0 -0
  289. {launchable-1.82.4 → launchable-1.83.0}/tests/helper.py +0 -0
  290. {launchable-1.82.4 → launchable-1.83.0}/tests/plugins/foo.py +0 -0
  291. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/__init__.py +0 -0
  292. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_adb.py +0 -0
  293. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_ant.py +0 -0
  294. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_bazel.py +0 -0
  295. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_behave.py +0 -0
  296. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_ctest.py +0 -0
  297. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_cts.py +0 -0
  298. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_cucumber.py +0 -0
  299. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_cypress.py +0 -0
  300. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_dotnet.py +0 -0
  301. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_go_test.py +0 -0
  302. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_googletest.py +0 -0
  303. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_gradle.py +0 -0
  304. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_jest.py +0 -0
  305. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_maven.py +0 -0
  306. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_minitest.py +0 -0
  307. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_nunit.py +0 -0
  308. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_playwright.py +0 -0
  309. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_prove.py +0 -0
  310. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_pytest.py +0 -0
  311. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_raw.py +0 -0
  312. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_robot.py +0 -0
  313. {launchable-1.82.4 → launchable-1.83.0}/tests/test_runners/test_rspec.py +0 -0
  314. {launchable-1.82.4 → launchable-1.83.0}/tests/test_session.py +0 -0
  315. {launchable-1.82.4 → launchable-1.83.0}/tests/test_testpath.py +0 -0
  316. {launchable-1.82.4 → launchable-1.83.0}/tests/test_version.py +0 -0
  317. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/__init__.py +0 -0
  318. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_authentication.py +0 -0
  319. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_click.py +0 -0
  320. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_file_name_pattern.py +0 -0
  321. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_git_log_parser.py +0 -0
  322. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_glob.py +0 -0
  323. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_gzipgen.py +0 -0
  324. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_http_client.py +0 -0
  325. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_key_value_type.py +0 -0
  326. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_link.py +0 -0
  327. {launchable-1.82.4 → launchable-1.83.0}/tests/utils/test_logger.py +0 -0
@@ -18,14 +18,14 @@ jobs:
18
18
  steps:
19
19
  - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
20
20
  - name: Set up JDK 8
21
- uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0
21
+ uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0
22
22
  with:
23
23
  distribution: temurin
24
24
  java-version: '8'
25
25
  - name: Setup Bazel
26
26
  uses: bazelbuild/setup-bazelisk@b39c379c82683a5f25d34f0d062761f62693e0b2 # v3.0.0
27
27
  - name: Cache Bazel outputs
28
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
28
+ uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
29
29
  with:
30
30
  path: "~/.cache/bazel"
31
31
  key: bazel
@@ -47,7 +47,7 @@ jobs:
47
47
  with:
48
48
  python-version: ${{ matrix.python-version }}
49
49
  - name: Set up JDK 1.8
50
- uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0
50
+ uses: actions/setup-java@9704b39bf258b59bc04b50fa2dd55e9ed76b47a8 # v4.1.0
51
51
  with:
52
52
  java-version: 8
53
53
  distribution: 'temurin'
@@ -21,7 +21,7 @@ jobs:
21
21
  - name: Setup Bazel
22
22
  uses: bazelbuild/setup-bazelisk@b39c379c82683a5f25d34f0d062761f62693e0b2 # v3.0.0
23
23
  - name: Cache Bazel outputs
24
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
24
+ uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
25
25
  with:
26
26
  path: "~/.cache/bazel"
27
27
  key: bazel
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: launchable
3
- Version: 1.82.4
3
+ Version: 1.83.0
4
4
  Summary: Launchable CLI
5
5
  Home-page: https://launchableinc.com/
6
6
  Author: Launchable, Inc.
@@ -20,7 +20,7 @@ load("@rules_jvm_external//:specs.bzl", "maven")
20
20
  # "bazel run @unpinned_maven//:pin" to apply these changes
21
21
  maven_install(
22
22
  artifacts = [
23
- "args4j:args4j:2.33",
23
+ "args4j:args4j:2.37",
24
24
  "ch.qos.logback:logback-classic:1.2.11",
25
25
  "com.fasterxml.jackson.core:jackson-annotations:2.16.1",
26
26
  "com.fasterxml.jackson.core:jackson-core:2.16.1",
@@ -43,7 +43,7 @@ maven_install(
43
43
  testonly = 1,
44
44
  artifact = "truth",
45
45
  group = "com.google.truth",
46
- version = "1.4.0",
46
+ version = "1.4.2",
47
47
  ),
48
48
  ],
49
49
  maven_install_json = "//src:maven_install.json",
@@ -0,0 +1,144 @@
1
+ import json
2
+ import os
3
+ import sys
4
+ from abc import ABCMeta, abstractmethod
5
+ from http import HTTPStatus
6
+ from typing import Dict, List
7
+
8
+ import click
9
+ from tabulate import tabulate
10
+
11
+ from ...utils.env_keys import REPORT_ERROR_KEY
12
+ from ...utils.launchable_client import LaunchableClient
13
+
14
+
15
+ class SubsetResult (object):
16
+ def __init__(self, result: dict, is_subset: bool):
17
+ self._estimated_duration_sec = result.get("duration", 0.0) / 1000 # convert to sec from msec
18
+ self._test_path = "#".join([path["type"] + "=" + path["name"]
19
+ for path in result["testPath"] if path.keys() >= {"type", "name"}])
20
+ self._is_subset = is_subset
21
+
22
+
23
+ class SubsetResults(object):
24
+ def __init__(self, results: List[SubsetResult]):
25
+ self._results = results
26
+
27
+ def add_subset(self, subset: List):
28
+ for result in subset:
29
+ self._results.append(SubsetResult(result, True))
30
+
31
+ def add_rest(self, rest: List):
32
+ for result in rest:
33
+ self._results.append(SubsetResult(result, False))
34
+
35
+ def list(self) -> List[SubsetResult]:
36
+ return self.list_subset() + self.list_rest()
37
+
38
+ def list_subset(self) -> List[SubsetResult]:
39
+ return [result for result in self._results if result._is_subset]
40
+
41
+ def list_rest(self) -> List[SubsetResult]:
42
+ return [result for result in self._results if not result._is_subset]
43
+
44
+
45
+ class SubsetResultAbstractDisplay(metaclass=ABCMeta):
46
+ def __init__(self, results: SubsetResults):
47
+ self._results = results
48
+
49
+ @abstractmethod
50
+ def display(self):
51
+ raise NotImplementedError("display method is not implemented")
52
+
53
+
54
+ class SubsetResultTableDisplay(SubsetResultAbstractDisplay):
55
+ def __init__(self, results: SubsetResults):
56
+ super().__init__(results)
57
+
58
+ def display(self):
59
+ header = ["Order", "Test Path", "In Subset", "Estimated duration (sec)"]
60
+ rows = []
61
+ for idx, result in enumerate(self._results.list()):
62
+ rows.append(
63
+ [
64
+ idx + 1,
65
+ result._test_path,
66
+ "✔" if result._is_subset else "",
67
+ result._estimated_duration_sec,
68
+ ]
69
+ )
70
+ click.echo(tabulate(rows, header, tablefmt="github", floatfmt=".2f"))
71
+
72
+
73
+ class SubsetResultJSONDisplay(SubsetResultAbstractDisplay):
74
+ def __init__(self, results: SubsetResults):
75
+ super().__init__(results)
76
+
77
+ def display(self):
78
+ result_json = {
79
+ "subset": [],
80
+ "rest": []
81
+ }
82
+ for result in self._results.list_subset():
83
+ result_json["subset"].append({
84
+ "test_path": result._test_path,
85
+ "estimated_duration_sec": round(result._estimated_duration_sec, 2),
86
+ })
87
+ for result in self._results.list_rest():
88
+ result_json["rest"].append({
89
+ "test_path": result._test_path,
90
+ "estimated_duration_sec": round(result._estimated_duration_sec, 2),
91
+ })
92
+
93
+ click.echo(json.dumps(result_json, indent=2))
94
+
95
+
96
+ @click.command()
97
+ @click.option(
98
+ '--subset-id',
99
+ 'subset_id',
100
+ help='subest id',
101
+ required=True,
102
+ )
103
+ @click.option(
104
+ '--json',
105
+ 'is_json_format',
106
+ help='display JSON format',
107
+ is_flag=True
108
+ )
109
+ @click.pass_context
110
+ def subset(context: click.core.Context, subset_id: int, is_json_format: bool):
111
+ subset = []
112
+ rest = []
113
+ try:
114
+ client = LaunchableClient(app=context.obj)
115
+ res = client.request("get", "subset/{}".format(subset_id))
116
+
117
+ if res.status_code == HTTPStatus.NOT_FOUND:
118
+ click.echo(click.style(
119
+ "Subset {} not found. Check subset ID and try again.".format(subset_id), 'yellow'), err=True)
120
+ sys.exit(1)
121
+
122
+ res.raise_for_status()
123
+ subset = res.json()["testPaths"]
124
+ rest = res.json()["rest"]
125
+ except Exception as e:
126
+ if os.getenv(REPORT_ERROR_KEY):
127
+ raise e
128
+ else:
129
+ click.echo(e, err=True)
130
+ click.echo(click.style(
131
+ "Warning: failed to inspect subset", fg='yellow'),
132
+ err=True)
133
+
134
+ results = SubsetResults([])
135
+ results.add_subset(subset)
136
+ results.add_rest(rest)
137
+
138
+ displayer: SubsetResultAbstractDisplay
139
+ if is_json_format:
140
+ displayer = SubsetResultJSONDisplay(results)
141
+ else:
142
+ displayer = SubsetResultTableDisplay(results)
143
+
144
+ displayer.display()
@@ -0,0 +1,195 @@
1
+ import json
2
+ import os
3
+ import sys
4
+ from abc import ABCMeta, abstractmethod
5
+ from http import HTTPStatus
6
+ from typing import List
7
+
8
+ import click
9
+ from tabulate import tabulate
10
+
11
+ from ...utils.authentication import ensure_org_workspace
12
+ from ...utils.env_keys import REPORT_ERROR_KEY
13
+ from ...utils.launchable_client import LaunchableClient
14
+ from ...utils.session import parse_session
15
+ from ..helper import require_session
16
+
17
+
18
+ class TestResult(object):
19
+ def __init__(self, result: dict):
20
+ self._status = result.get("status", "")
21
+ self._duration_sec = result.get("duration", 0.0)
22
+ self._created_at = result.get("createdAt", None)
23
+ self._test_path = "#".join([path["type"] + "=" + path["name"]
24
+ for path in result["testPath"] if path.keys() >= {"type", "name"}])
25
+
26
+
27
+ class TestResults(object):
28
+ def __init__(self, test_session_id: int, results: List[TestResult]):
29
+ self._test_session_id = test_session_id
30
+ self._results = results
31
+
32
+ def add(self, result: TestResult):
33
+ self._results.append(result)
34
+
35
+ def list(self) -> List[TestResult]:
36
+ return self._results
37
+
38
+ def total_duration_sec(self) -> float:
39
+ return sum([result._duration_sec for result in self._results])
40
+
41
+ def total_duration_min(self) -> float:
42
+ return (sum([result._duration_sec for result in self._results]) / 60)
43
+
44
+ def total_count(self) -> int:
45
+ return len(self._results)
46
+
47
+ def filter_by_status(self, status: str) -> 'TestResults':
48
+ return TestResults(self._test_session_id, [result for result in self._results if result._status == status])
49
+
50
+
51
+ class TestResultAbstractDisplay(metaclass=ABCMeta):
52
+ def __init__(self, results: TestResults):
53
+ self._results = results
54
+
55
+ @abstractmethod
56
+ def display(self):
57
+ raise NotImplementedError("display method is not implemented")
58
+
59
+
60
+ class TestResultJSONDisplay(TestResultAbstractDisplay):
61
+ def __init__(self, results: TestResults):
62
+ super().__init__(results)
63
+
64
+ def display(self):
65
+ result_json = {}
66
+ result_json["summary"] = {
67
+ "total": {
68
+ "report_count": self._results.total_count(),
69
+ "duration_min": round(self._results.total_duration_min(), 2),
70
+ },
71
+ "success": {
72
+ "report_count": self._results.filter_by_status("SUCCESS").total_count(),
73
+ "duration_min": round(self._results.filter_by_status("SUCCESS").total_duration_min(), 2)
74
+ },
75
+ "failure": {
76
+ "report_count": self._results.filter_by_status("FAILURE").total_count(),
77
+ "duration_min": round(self._results.filter_by_status("FAILURE").total_duration_min(), 2)
78
+ },
79
+ "skip": {
80
+ "report_count": self._results.filter_by_status("SKIPPED").total_count(),
81
+ "duration_min": round(self._results.filter_by_status("SKIPPED").total_duration_min(), 2)
82
+ }
83
+ }
84
+ result_json["results"] = []
85
+ for result in self._results.list():
86
+ result_json["results"].append({
87
+ "test_path": result._test_path,
88
+ "duration_sec": result._duration_sec,
89
+ "status": result._status,
90
+ "created_at": result._created_at
91
+ })
92
+
93
+ org, workspace = ensure_org_workspace()
94
+ result_json["test_session_app_url"] = "https://app.launchableinc.com/organizations/{}/workspaces/{}/test-sessions/{}".format( # noqa: E501
95
+ org, workspace, self._results._test_session_id)
96
+
97
+ click.echo(json.dumps(result_json, indent=2))
98
+
99
+
100
+ class TestResultTableDisplay(TestResultAbstractDisplay):
101
+ def __init__(self, results: TestResults):
102
+ super().__init__(results)
103
+
104
+ def display(self):
105
+ header = ["Test Path",
106
+ "Duration (sec)", "Status", "Uploaded At"]
107
+ rows = []
108
+ for result in self._results.list():
109
+ rows.append(
110
+ [
111
+ result._test_path,
112
+ result._duration_sec,
113
+ result._status,
114
+ result._created_at,
115
+ ]
116
+ )
117
+ click.echo(tabulate(rows, header, tablefmt="github", floatfmt=".2f"))
118
+
119
+ summary_header = ["Summary", "Report Count", "Total Duration (min)"]
120
+ summary_rows = [
121
+ ["Total", self._results.total_count(),
122
+ self._results.total_duration_min()],
123
+ ["Success", self._results.filter_by_status("SUCCESS").total_count(),
124
+ self._results.filter_by_status("SUCCESS").total_duration_min()],
125
+ ["Failure", self._results.filter_by_status("FAILURE").total_count(),
126
+ self._results.filter_by_status("FAILURE").total_duration_min()],
127
+ ["Skip", self._results.filter_by_status("SKIPPED").total_count(),
128
+ self._results.filter_by_status("SKIPPED").total_duration_min()]]
129
+
130
+ click.echo(tabulate(summary_rows, summary_header, tablefmt="grid", floatfmt=["", ".0f", ".2f"]))
131
+
132
+
133
+ @click.command()
134
+ @click.option(
135
+ '--test-session-id',
136
+ 'test_session_id',
137
+ help='test session id',
138
+ )
139
+ @click.option(
140
+ '--json',
141
+ 'is_json_format',
142
+ help='display JSON format',
143
+ is_flag=True
144
+ )
145
+ @click.pass_context
146
+ def tests(context: click.core.Context, test_session_id: int, is_json_format: bool):
147
+ if (test_session_id is None):
148
+ try:
149
+ session = require_session(None)
150
+ _, test_session_id = parse_session(session)
151
+ except Exception:
152
+ click.echo(
153
+ click.style(
154
+ "test session id requires.\n"
155
+ "Use the --test-session-id option or execute after `launchable record tests` command.",
156
+ fg="yellow"))
157
+ return
158
+
159
+ try:
160
+ client = LaunchableClient(app=context.obj)
161
+ res = client.request(
162
+ "get", "/test_sessions/{}/events".format(test_session_id))
163
+
164
+ if res.status_code == HTTPStatus.NOT_FOUND:
165
+ click.echo(click.style(
166
+ "Test session {} not found. Check test session ID and try again.".format(test_session_id), 'yellow'),
167
+ err=True,
168
+ )
169
+ sys.exit(1)
170
+
171
+ res.raise_for_status()
172
+ results = res.json()
173
+ except Exception as e:
174
+ if os.getenv(REPORT_ERROR_KEY):
175
+ raise e
176
+ else:
177
+ click.echo(e, err=True)
178
+ click.echo(click.style(
179
+ "Warning: failed to inspect tests", fg='yellow'),
180
+ err=True)
181
+
182
+ return
183
+
184
+ test_results = TestResults(test_session_id=test_session_id, results=[])
185
+ for result in results:
186
+ if result.keys() >= {"testPath"}:
187
+ test_results.add(TestResult(result))
188
+
189
+ displayer: TestResultAbstractDisplay
190
+ if is_json_format:
191
+ displayer = TestResultJSONDisplay(test_results)
192
+ else:
193
+ displayer = TestResultTableDisplay(test_results)
194
+
195
+ displayer.display()
@@ -241,7 +241,9 @@ def tests(
241
241
  raise e
242
242
  else:
243
243
  traceback.print_exc()
244
- return
244
+ # To prevent users from stopping the CI pipeline, the cli exits with a
245
+ # status code of 0, indicating that the program terminated successfully.
246
+ exit(0)
245
247
 
246
248
  # TODO: placed here to minimize invasion in this PR to reduce the likelihood of
247
249
  # PR merge hell. This should be moved to a top-level class
@@ -5,6 +5,7 @@ import types
5
5
 
6
6
  import click
7
7
 
8
+ from launchable.app import Application
8
9
  from launchable.commands.record.tests import tests as record_tests_cmd
9
10
  from launchable.commands.split_subset import split_subset as split_subset_cmd
10
11
  from launchable.commands.subset import subset as subset_cmd
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: launchable
3
- Version: 1.82.4
3
+ Version: 1.83.0
4
4
  Summary: Launchable CLI
5
5
  Home-page: https://launchableinc.com/
6
6
  Author: Launchable, Inc.
@@ -80,6 +80,8 @@ public class CommitGraphCollector {
80
80
 
81
81
  private boolean dryRun;
82
82
 
83
+ private boolean warnMissingObject;
84
+
83
85
  private String dryRunPrefix() {
84
86
  if (!dryRun) {
85
87
  return "";
@@ -408,7 +410,18 @@ public class CommitGraphCollector {
408
410
  for (DiffEntry de : files) {
409
411
  try {
410
412
  changes.add(diff.process(de));
411
- } catch (UncheckedIOException e) {
413
+ } catch (MissingObjectException e) {
414
+ // in a partially cloned repository, BLOBs might be unavailable and that'd result in MissingObjectException
415
+ System.err.printf("Warning: %s is missing. Skipping diff calculation for %s -> %s%n",
416
+ e.getObjectId().abbreviate(7).name(),
417
+ p.abbreviate(7).name(),
418
+ r.abbreviate(7).name()
419
+ );
420
+ if (!warnMissingObject) {
421
+ warnMissingObject = true;
422
+ System.err.println("See https://www.launchableinc.com/missing-git-object-during-commit-collection");
423
+ }
424
+ } catch (IOException e) {
412
425
  logger.warn("Failed to process a change to a file", e);
413
426
  }
414
427
  }
@@ -26,17 +26,13 @@ class CountingDiffFormatter extends DiffFormatter {
26
26
  }
27
27
 
28
28
  /** Entry point to compute a file level change. */
29
- JSFileChange process(DiffEntry de) {
29
+ JSFileChange process(DiffEntry de) throws IOException {
30
30
  add = 0;
31
31
  del = 0;
32
32
 
33
33
  // This call internally eventually reaches to format(EditList, RawTest, RawText) that counts the
34
34
  // numbers.
35
- try {
36
- format(de);
37
- } catch (IOException e) {
38
- throw new UncheckedIOException(e);
39
- }
35
+ format(de);
40
36
 
41
37
  JSFileChange fc = new JSFileChange();
42
38
  fc.setLinesAdded(add);
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
3
- "__INPUT_ARTIFACTS_HASH": -1687359741,
4
- "__RESOLVED_ARTIFACTS_HASH": 123369317,
3
+ "__INPUT_ARTIFACTS_HASH": -1425112319,
4
+ "__RESOLVED_ARTIFACTS_HASH": 1206395311,
5
5
  "artifacts": {
6
6
  "args4j:args4j": {
7
7
  "shasums": {
8
- "jar": "91ddeaba0b24adce72291c618c00bbdce1c884755f6c4dba9c5c46e871c69ed6",
9
- "sources": "a337a37bc6fc9a2d81c952f4c6ebd5db12351e994d00e112d7fe87a4dd707204"
8
+ "jar": "5a13b0f7ff519183e55b8f453b8faaa23b92ccf0443f1fac515fedf2246bdc18",
9
+ "sources": "179ee53818ef244600238091c7c6333340e86bb83c605b2fb104a427571e0d1e"
10
10
  },
11
- "version": "2.33"
11
+ "version": "2.37"
12
12
  },
13
13
  "asm:asm-all": {
14
14
  "shasums": {
@@ -75,10 +75,10 @@
75
75
  },
76
76
  "com.google.errorprone:error_prone_annotations": {
77
77
  "shasums": {
78
- "jar": "19fe2f7155d20ea093168527999da98108103ee546d1e8b726bc4b27c31a3c30",
79
- "sources": "d0d63b507b92b36d38d938e96daf260baa55e739fe9e0d642519b8fac823d288"
78
+ "jar": "47d91c141efd6b1d9231a322deca8f4c32dac8e940c6c38d768b36add221700d",
79
+ "sources": "fceb685146fad483d70fe78247e5e9b2a24af14fbae1f5ca940f58f8d2b05034"
80
80
  },
81
- "version": "2.24.1"
81
+ "version": "2.25.0"
82
82
  },
83
83
  "com.google.guava:failureaccess": {
84
84
  "shasums": {
@@ -110,10 +110,10 @@
110
110
  },
111
111
  "com.google.truth:truth": {
112
112
  "shasums": {
113
- "jar": "235c28e96ee6701ab01cc852fb294cb0f34756f636a8154b9aef08fb1215bbc4",
114
- "sources": "f2834e7abdd08f5ab31defe409f601e0863b31f3f47105ab3c5ae8df4a687318"
113
+ "jar": "14c297bc64ca8bc15b6baf67f160627e4562ec91624797e312e907b431113508",
114
+ "sources": "9e6e49a3d2eefcadc0294878cb19fa6c6da305f2939c422f3cbd8caf9efe80bb"
115
115
  },
116
- "version": "1.4.0"
116
+ "version": "1.4.2"
117
117
  },
118
118
  "com.googlecode.javaewah:JavaEWAH": {
119
119
  "shasums": {
@@ -0,0 +1,75 @@
1
+ import os
2
+ from unittest import mock
3
+
4
+ import responses # type: ignore
5
+
6
+ from launchable.utils.http_client import get_base_url
7
+ from tests.cli_test_case import CliTestCase
8
+
9
+
10
+ class SubsetTest(CliTestCase):
11
+ mock_json = {
12
+ "testPaths": [
13
+ {"testPath": [
14
+ {"type": "file", "name": "test_file1.py"}], "duration": 1200},
15
+ {"testPath": [
16
+ {"type": "file", "name": "test_file3.py"}], "duration": 600},
17
+ ],
18
+ "rest": [
19
+ {"testPath": [
20
+ {"type": "file", "name": "test_file4.py"}], "duration": 1800},
21
+ {"testPath": [
22
+ {"type": "file", "name": "test_file2.py"}], "duration": 100}
23
+
24
+ ]
25
+ }
26
+
27
+ @responses.activate
28
+ @mock.patch.dict(os.environ, {"LAUNCHABLE_TOKEN": CliTestCase.launchable_token})
29
+ def test_subset(self):
30
+ responses.replace(responses.GET, "{}/intake/organizations/{}/workspaces/{}/subset/{}".format(
31
+ get_base_url(), self.organization, self.workspace, self.subsetting_id), json=self.mock_json, status=200)
32
+
33
+ result = self.cli('inspect', 'subset', '--subset-id', self.subsetting_id, mix_stderr=False)
34
+ expect = """| Order | Test Path | In Subset | Estimated duration (sec) |
35
+ |---------|--------------------|-------------|----------------------------|
36
+ | 1 | file=test_file1.py | ✔ | 1.20 |
37
+ | 2 | file=test_file3.py | ✔ | 0.60 |
38
+ | 3 | file=test_file4.py | | 1.80 |
39
+ | 4 | file=test_file2.py | | 0.10 |
40
+ """
41
+
42
+ self.assertEqual(result.stdout, expect)
43
+
44
+ @responses.activate
45
+ @mock.patch.dict(os.environ, {"LAUNCHABLE_TOKEN": CliTestCase.launchable_token})
46
+ def test_subset_json_format(self):
47
+ responses.replace(responses.GET, "{}/intake/organizations/{}/workspaces/{}/subset/{}".format(
48
+ get_base_url(), self.organization, self.workspace, self.subsetting_id), json=self.mock_json, status=200)
49
+
50
+ result = self.cli('inspect', 'subset', '--subset-id', self.subsetting_id, "--json", mix_stderr=False)
51
+ expect = """{
52
+ "subset": [
53
+ {
54
+ "test_path": "file=test_file1.py",
55
+ "estimated_duration_sec": 1.2
56
+ },
57
+ {
58
+ "test_path": "file=test_file3.py",
59
+ "estimated_duration_sec": 0.6
60
+ }
61
+ ],
62
+ "rest": [
63
+ {
64
+ "test_path": "file=test_file4.py",
65
+ "estimated_duration_sec": 1.8
66
+ },
67
+ {
68
+ "test_path": "file=test_file2.py",
69
+ "estimated_duration_sec": 0.1
70
+ }
71
+ ]
72
+ }
73
+ """
74
+
75
+ self.assertEqual(result.stdout, expect)