launchable 1.98.3__tar.gz → 1.99.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 (330) hide show
  1. {launchable-1.98.3 → launchable-1.99.0}/PKG-INFO +1 -1
  2. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/helper.py +3 -0
  3. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/record/build.py +12 -3
  4. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/record/session.py +11 -0
  5. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/record/tests.py +21 -3
  6. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/click.py +17 -0
  7. {launchable-1.98.3 → launchable-1.99.0}/launchable.egg-info/PKG-INFO +1 -1
  8. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/record/test_build.py +53 -7
  9. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/record/test_session.py +27 -0
  10. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/test_click.py +29 -1
  11. {launchable-1.98.3 → launchable-1.99.0}/.bazelrc +0 -0
  12. {launchable-1.98.3 → launchable-1.99.0}/.bazelversion +0 -0
  13. {launchable-1.98.3 → launchable-1.99.0}/.editorconfig +0 -0
  14. {launchable-1.98.3 → launchable-1.99.0}/.github/release.yml +0 -0
  15. {launchable-1.98.3 → launchable-1.99.0}/.github/workflows/bazel-test.yml +0 -0
  16. {launchable-1.98.3 → launchable-1.99.0}/.github/workflows/e2e.yml +0 -0
  17. {launchable-1.98.3 → launchable-1.99.0}/.github/workflows/python-package.yml +0 -0
  18. {launchable-1.98.3 → launchable-1.99.0}/.github/workflows/python-publish.yml +0 -0
  19. {launchable-1.98.3 → launchable-1.99.0}/.github/workflows/update_maven_install_json.yml +0 -0
  20. {launchable-1.98.3 → launchable-1.99.0}/.gitignore +0 -0
  21. {launchable-1.98.3 → launchable-1.99.0}/.pre-commit-config.yaml +0 -0
  22. {launchable-1.98.3 → launchable-1.99.0}/.python-version +0 -0
  23. {launchable-1.98.3 → launchable-1.99.0}/.tagpr +0 -0
  24. {launchable-1.98.3 → launchable-1.99.0}/CONTRIBUTING.md +0 -0
  25. {launchable-1.98.3 → launchable-1.99.0}/Dockerfile +0 -0
  26. {launchable-1.98.3 → launchable-1.99.0}/LICENSE.txt +0 -0
  27. {launchable-1.98.3 → launchable-1.99.0}/Pipfile +0 -0
  28. {launchable-1.98.3 → launchable-1.99.0}/README.md +0 -0
  29. {launchable-1.98.3 → launchable-1.99.0}/WORKSPACE +0 -0
  30. {launchable-1.98.3 → launchable-1.99.0}/build-java.sh +0 -0
  31. {launchable-1.98.3 → launchable-1.99.0}/launchable/__init__.py +0 -0
  32. {launchable-1.98.3 → launchable-1.99.0}/launchable/__main__.py +0 -0
  33. {launchable-1.98.3 → launchable-1.99.0}/launchable/app.py +0 -0
  34. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/__init__.py +0 -0
  35. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/inspect/__init__.py +0 -0
  36. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/inspect/subset.py +0 -0
  37. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/inspect/tests.py +0 -0
  38. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/record/__init__.py +0 -0
  39. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/record/attachment.py +0 -0
  40. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/record/case_event.py +0 -0
  41. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/record/commit.py +0 -0
  42. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/split_subset.py +0 -0
  43. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/stats/__init__.py +0 -0
  44. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/stats/test_sessions.py +0 -0
  45. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/subset.py +0 -0
  46. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/test_path_writer.py +0 -0
  47. {launchable-1.98.3 → launchable-1.99.0}/launchable/commands/verify.py +0 -0
  48. {launchable-1.98.3 → launchable-1.99.0}/launchable/jar/exe_deploy.jar +0 -0
  49. {launchable-1.98.3 → launchable-1.99.0}/launchable/plugins/__init__.py +0 -0
  50. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/__init__.py +0 -0
  51. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/adb.py +0 -0
  52. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/ant.py +0 -0
  53. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/bazel.py +0 -0
  54. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/behave.py +0 -0
  55. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/ctest.py +0 -0
  56. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/cts.py +0 -0
  57. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/cucumber.py +0 -0
  58. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/cypress.py +0 -0
  59. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/dotnet.py +0 -0
  60. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/file.py +0 -0
  61. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/flutter.py +0 -0
  62. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/go_test.py +0 -0
  63. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/googletest.py +0 -0
  64. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/gradle.py +0 -0
  65. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/jest.py +0 -0
  66. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/launchable.py +0 -0
  67. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/maven.py +0 -0
  68. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/minitest.py +0 -0
  69. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/nunit.py +0 -0
  70. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/playwright.py +0 -0
  71. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/prove.py +0 -0
  72. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/pytest.py +0 -0
  73. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/raw.py +0 -0
  74. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/robot.py +0 -0
  75. {launchable-1.98.3 → launchable-1.99.0}/launchable/test_runners/rspec.py +0 -0
  76. {launchable-1.98.3 → launchable-1.99.0}/launchable/testpath.py +0 -0
  77. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/__init__.py +0 -0
  78. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/authentication.py +0 -0
  79. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/ci_provider.py +0 -0
  80. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/commit_ingester.py +0 -0
  81. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/env_keys.py +0 -0
  82. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/exceptions.py +0 -0
  83. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/file_name_pattern.py +0 -0
  84. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/git_log_parser.py +0 -0
  85. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/glob.py +0 -0
  86. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/gzipgen.py +0 -0
  87. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/http_client.py +0 -0
  88. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/java.py +0 -0
  89. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/launchable_client.py +0 -0
  90. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/link.py +0 -0
  91. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/logger.py +0 -0
  92. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/no_build.py +0 -0
  93. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/sax.py +0 -0
  94. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/session.py +0 -0
  95. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/subprocess.py +0 -0
  96. {launchable-1.98.3 → launchable-1.99.0}/launchable/utils/tracking.py +0 -0
  97. {launchable-1.98.3 → launchable-1.99.0}/launchable/version.py +0 -0
  98. {launchable-1.98.3 → launchable-1.99.0}/launchable.egg-info/SOURCES.txt +0 -0
  99. {launchable-1.98.3 → launchable-1.99.0}/launchable.egg-info/dependency_links.txt +0 -0
  100. {launchable-1.98.3 → launchable-1.99.0}/launchable.egg-info/entry_points.txt +0 -0
  101. {launchable-1.98.3 → launchable-1.99.0}/launchable.egg-info/requires.txt +0 -0
  102. {launchable-1.98.3 → launchable-1.99.0}/launchable.egg-info/top_level.txt +0 -0
  103. {launchable-1.98.3 → launchable-1.99.0}/pyproject.toml +0 -0
  104. {launchable-1.98.3 → launchable-1.99.0}/renovate.json +0 -0
  105. {launchable-1.98.3 → launchable-1.99.0}/setup.cfg +0 -0
  106. {launchable-1.98.3 → launchable-1.99.0}/setup.py +0 -0
  107. {launchable-1.98.3 → launchable-1.99.0}/src/BUILD +0 -0
  108. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/Authenticator.java +0 -0
  109. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/BUILD +0 -0
  110. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/CommitGraphCollector.java +0 -0
  111. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/CommitIngester.java +0 -0
  112. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/CountingDiffFormatter.java +0 -0
  113. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/GitHubActionsAuthenticator.java +0 -0
  114. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/GitHubIdTokenAuthenticator.java +0 -0
  115. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/JSCommit.java +0 -0
  116. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/JSFileChange.java +0 -0
  117. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/ObjectRevFilter.java +0 -0
  118. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/SSLBypass.java +0 -0
  119. {launchable-1.98.3 → launchable-1.99.0}/src/main/java/com/launchableinc/ingest/commits/TokenAuthenticator.java +0 -0
  120. {launchable-1.98.3 → launchable-1.99.0}/src/maven_install.json +0 -0
  121. {launchable-1.98.3 → launchable-1.99.0}/src/test/java/com/launchableinc/ingest/commits/AllTests.java +0 -0
  122. {launchable-1.98.3 → launchable-1.99.0}/src/test/java/com/launchableinc/ingest/commits/BUILD +0 -0
  123. {launchable-1.98.3 → launchable-1.99.0}/src/test/java/com/launchableinc/ingest/commits/CommitGraphCollectorTest.java +0 -0
  124. {launchable-1.98.3 → launchable-1.99.0}/src/test/java/com/launchableinc/ingest/commits/CommitIngesterTest.java +0 -0
  125. {launchable-1.98.3 → launchable-1.99.0}/src/test/java/com/launchableinc/ingest/commits/SSLBypassTest.java +0 -0
  126. {launchable-1.98.3 → launchable-1.99.0}/src/test/java/com/launchableinc/ingest/commits/java8-compat.sh +0 -0
  127. {launchable-1.98.3 → launchable-1.99.0}/test-runner/__main__.py +0 -0
  128. {launchable-1.98.3 → launchable-1.99.0}/tests/__init__.py +0 -0
  129. {launchable-1.98.3 → launchable-1.99.0}/tests/cli_test_case.py +0 -0
  130. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/__init__.py +0 -0
  131. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/inspect/__init__.py +0 -0
  132. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/inspect/test_subset.py +0 -0
  133. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/inspect/test_tests.py +0 -0
  134. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/record/__init__.py +0 -0
  135. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/record/test_attachment.py +0 -0
  136. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/record/test_commit.py +0 -0
  137. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/record/test_tests.py +0 -0
  138. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/test_api_error.py +0 -0
  139. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/test_helper.py +0 -0
  140. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/test_split_subset.py +0 -0
  141. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/test_subset.py +0 -0
  142. {launchable-1.98.3 → launchable-1.99.0}/tests/commands/test_verify.py +0 -0
  143. {launchable-1.98.3 → launchable-1.99.0}/tests/data/adb/subset_result.json +0 -0
  144. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ant/junitreport/TEST-com.launchable.HelloWorldTest.xml +0 -0
  145. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ant/junitreport/TEST-com.launchable.library.CacheTest.xml +0 -0
  146. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ant/junitreport/TESTS-TestSuites.xml +0 -0
  147. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ant/record_test_result.json +0 -0
  148. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ant/src/com/launchable/HelloWorld.java +0 -0
  149. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ant/src/com/launchable/HelloWorldTest.java +0 -0
  150. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ant/src/com/launchable/library/Cache.java +0 -0
  151. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ant/src/com/launchable/library/CacheTest.java +0 -0
  152. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ant/subset_result.json +0 -0
  153. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test1/test.cache_status +0 -0
  154. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test1/test.xml +0 -0
  155. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test2/test.cache_status +0 -0
  156. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test2/test.xml +0 -0
  157. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test3/test.cache_status +0 -0
  158. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test3/test.xml +0 -0
  159. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test4/test.cache_status +0 -0
  160. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test4/test.xml +0 -0
  161. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test5/test.cache_status +0 -0
  162. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test5/test.xml +0 -0
  163. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test6/test.cache_status +0 -0
  164. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test6/test.xml +0 -0
  165. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test7/test.cache_status +0 -0
  166. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test7/test.xml +0 -0
  167. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test8/test.cache_status +0 -0
  168. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test8/test.xml +0 -0
  169. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test9/test.cache_status +0 -0
  170. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test9/test.xml +0 -0
  171. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/build_event.json +0 -0
  172. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/build_event_rest.json +0 -0
  173. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/record_test_result.json +0 -0
  174. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/record_test_with_build_event_json_result.json +0 -0
  175. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/record_test_with_multiple_build_event_json_result.json +0 -0
  176. {launchable-1.98.3 → launchable-1.99.0}/tests/data/bazel/subset_result.json +0 -0
  177. {launchable-1.98.3 → launchable-1.99.0}/tests/data/behave/record_test_result.json +0 -0
  178. {launchable-1.98.3 → launchable-1.99.0}/tests/data/behave/reports/report.xml +0 -0
  179. {launchable-1.98.3 → launchable-1.99.0}/tests/data/behave/subset_result.json +0 -0
  180. {launchable-1.98.3 → launchable-1.99.0}/tests/data/broken_xml/broken.xml +0 -0
  181. {launchable-1.98.3 → launchable-1.99.0}/tests/data/broken_xml/normal.xml +0 -0
  182. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ctest/Testing/latest/Test.xml +0 -0
  183. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ctest/ctest_list.json +0 -0
  184. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ctest/record_test_result.json +0 -0
  185. {launchable-1.98.3 → launchable-1.99.0}/tests/data/ctest/subset_result.json +0 -0
  186. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cts/record_test_result.json +0 -0
  187. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cts/subset_result.json +0 -0
  188. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cts/test_result.xml +0 -0
  189. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/features/foo/bar.feature +0 -0
  190. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/features/foo/is_it_friday_yet.feature +0 -0
  191. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/features/foo-bar.feature +0 -0
  192. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/features/is_it_friday_yet.feature +0 -0
  193. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/record_test_json_result.json +0 -0
  194. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/record_test_result.json +0 -0
  195. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/report/TEST-features-foo-bar.xml +0 -0
  196. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/report/TEST-features-foo-is_it_friday_yet.xml +0 -0
  197. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/report/TEST-features-is_it_friday_yet.xml +0 -0
  198. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/report/dummy.xml +0 -0
  199. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cucumber/report/result.json +0 -0
  200. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cypress/empty.json +0 -0
  201. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cypress/empty.xml +0 -0
  202. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cypress/record_test_result.json +0 -0
  203. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cypress/subset_result.json +0 -0
  204. {launchable-1.98.3 → launchable-1.99.0}/tests/data/cypress/test-result.xml +0 -0
  205. {launchable-1.98.3 → launchable-1.99.0}/tests/data/dotnet/record_test_result.json +0 -0
  206. {launchable-1.98.3 → launchable-1.99.0}/tests/data/dotnet/test-result.xml +0 -0
  207. {launchable-1.98.3 → launchable-1.99.0}/tests/data/flutter/record_test_result.json +0 -0
  208. {launchable-1.98.3 → launchable-1.99.0}/tests/data/flutter/report.json +0 -0
  209. {launchable-1.98.3 → launchable-1.99.0}/tests/data/git_log_ingest/sample.out +0 -0
  210. {launchable-1.98.3 → launchable-1.99.0}/tests/data/go_test/record_test_result.json +0 -0
  211. {launchable-1.98.3 → launchable-1.99.0}/tests/data/go_test/reportv1/reportv1.xml +0 -0
  212. {launchable-1.98.3 → launchable-1.99.0}/tests/data/go_test/reportv2/reportv2.xml +0 -0
  213. {launchable-1.98.3 → launchable-1.99.0}/tests/data/go_test/subset_result.json +0 -0
  214. {launchable-1.98.3 → launchable-1.99.0}/tests/data/googletest/fail/output.xml +0 -0
  215. {launchable-1.98.3 → launchable-1.99.0}/tests/data/googletest/fail/record_test_result.json +0 -0
  216. {launchable-1.98.3 → launchable-1.99.0}/tests/data/googletest/output_a.xml +0 -0
  217. {launchable-1.98.3 → launchable-1.99.0}/tests/data/googletest/output_b.xml +0 -0
  218. {launchable-1.98.3 → launchable-1.99.0}/tests/data/googletest/record_test_result.json +0 -0
  219. {launchable-1.98.3 → launchable-1.99.0}/tests/data/googletest/subset_result.json +0 -0
  220. {launchable-1.98.3 → launchable-1.99.0}/tests/data/gradle/java/app/src/test/java/com/launchableinc/rocket_car_gradle/App2Test.java +0 -0
  221. {launchable-1.98.3 → launchable-1.99.0}/tests/data/gradle/java/app/src/test/java/com/launchableinc/rocket_car_gradle/AppTest.java +0 -0
  222. {launchable-1.98.3 → launchable-1.99.0}/tests/data/gradle/java/app/src/test/java/com/launchableinc/rocket_car_gradle/sub/App3Test.java +0 -0
  223. {launchable-1.98.3 → launchable-1.99.0}/tests/data/gradle/recursion/expected.json +0 -0
  224. {launchable-1.98.3 → launchable-1.99.0}/tests/data/gradle/recursion/foo/bar/reports/1.xml +0 -0
  225. {launchable-1.98.3 → launchable-1.99.0}/tests/data/jest/junit.xml +0 -0
  226. {launchable-1.98.3 → launchable-1.99.0}/tests/data/jest/record_test_result.json +0 -0
  227. {launchable-1.98.3 → launchable-1.99.0}/tests/data/jest/subset_result.json +0 -0
  228. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/createdFile_1.lst +0 -0
  229. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/createdFile_2.lst +0 -0
  230. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/java/test/src/java/com/launchableinc/rocket_car_maven/App2Test.java +0 -0
  231. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/java/test/src/java/com/launchableinc/rocket_car_maven/AppTest.java +0 -0
  232. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/list.lst +0 -0
  233. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/record_test_result.json +0 -0
  234. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/reports/TEST-1.xml +0 -0
  235. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/reports/TEST-2.xml +0 -0
  236. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/reports/TEST-nested.xml +0 -0
  237. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/reports/dummy.xml +0 -0
  238. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/subset_by_absolute_time_result.json +0 -0
  239. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/subset_by_confidence_result.json +0 -0
  240. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/subset_from_file_result.json +0 -0
  241. {launchable-1.98.3 → launchable-1.99.0}/tests/data/maven/subset_result.json +0 -0
  242. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/TEST-Admin_UserTest.xml +0 -0
  243. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/TEST-Admin_UserTest_ChildlenTest.xml +0 -0
  244. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/TEST-UserControllerTest.xml +0 -0
  245. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/TEST-UserCopyTest.xml +0 -0
  246. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/TEST-UserTest.xml +0 -0
  247. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/record_test_result.json +0 -0
  248. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/record_test_result_chunk1.json +0 -0
  249. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/record_test_result_chunk2.json +0 -0
  250. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/subset_result.json +0 -0
  251. {launchable-1.98.3 → launchable-1.99.0}/tests/data/minitest/test/example_test.rb +0 -0
  252. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/list.xml +0 -0
  253. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/nunit-reporter-bug-with-nested-type.json +0 -0
  254. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/nunit-reporter-bug-with-nested-type.xml +0 -0
  255. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/output-linux.xml +0 -0
  256. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/output-windows.xml +0 -0
  257. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/record_test_result-linux.json +0 -0
  258. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/record_test_result-windows.json +0 -0
  259. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/src/.gitignore +0 -0
  260. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/src/Program.cs +0 -0
  261. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/src/README.md +0 -0
  262. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/src/Test.cs +0 -0
  263. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/src/calc.csproj +0 -0
  264. {launchable-1.98.3 → launchable-1.99.0}/tests/data/nunit/subset_result.json +0 -0
  265. {launchable-1.98.3 → launchable-1.99.0}/tests/data/playwright/record_test_result.json +0 -0
  266. {launchable-1.98.3 → launchable-1.99.0}/tests/data/playwright/record_test_result_with_json.json +0 -0
  267. {launchable-1.98.3 → launchable-1.99.0}/tests/data/playwright/report.json +0 -0
  268. {launchable-1.98.3 → launchable-1.99.0}/tests/data/playwright/report.xml +0 -0
  269. {launchable-1.98.3 → launchable-1.99.0}/tests/data/prove/record_test_result.json +0 -0
  270. {launchable-1.98.3 → launchable-1.99.0}/tests/data/prove/report.xml +0 -0
  271. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/pytest.ini +0 -0
  272. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/record_test_result.json +0 -0
  273. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/record_test_result_json.json +0 -0
  274. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/report.json +0 -0
  275. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/report.xml +0 -0
  276. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/subset_result.json +0 -0
  277. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/tests/conftest.py +0 -0
  278. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/tests/fooo/__init__.py +0 -0
  279. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/tests/fooo/filenameonly_test.py +0 -0
  280. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/tests/fooo/func4_test.py +0 -0
  281. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/tests/funcs3_test.py +0 -0
  282. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/tests/test_funcs1.py +0 -0
  283. {launchable-1.98.3 → launchable-1.99.0}/tests/data/pytest/tests/test_funcs2.py +0 -0
  284. {launchable-1.98.3 → launchable-1.99.0}/tests/data/robot/dryrun.xml +0 -0
  285. {launchable-1.98.3 → launchable-1.99.0}/tests/data/robot/output.xml +0 -0
  286. {launchable-1.98.3 → launchable-1.99.0}/tests/data/robot/record_test_executed_only_one_file_result.json +0 -0
  287. {launchable-1.98.3 → launchable-1.99.0}/tests/data/robot/record_test_result.json +0 -0
  288. {launchable-1.98.3 → launchable-1.99.0}/tests/data/robot/single-output.xml +0 -0
  289. {launchable-1.98.3 → launchable-1.99.0}/tests/data/robot/subset_result.json +0 -0
  290. {launchable-1.98.3 → launchable-1.99.0}/tests/data/rspec/record_test_result.json +0 -0
  291. {launchable-1.98.3 → launchable-1.99.0}/tests/data/rspec/rspec.xml +0 -0
  292. {launchable-1.98.3 → launchable-1.99.0}/tests/helper.py +0 -0
  293. {launchable-1.98.3 → launchable-1.99.0}/tests/plugins/foo.py +0 -0
  294. {launchable-1.98.3 → launchable-1.99.0}/tests/test_cli_test_case.py +0 -0
  295. {launchable-1.98.3 → launchable-1.99.0}/tests/test_plugin.py +0 -0
  296. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/__init__.py +0 -0
  297. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_adb.py +0 -0
  298. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_ant.py +0 -0
  299. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_bazel.py +0 -0
  300. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_behave.py +0 -0
  301. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_ctest.py +0 -0
  302. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_cts.py +0 -0
  303. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_cucumber.py +0 -0
  304. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_cypress.py +0 -0
  305. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_dotnet.py +0 -0
  306. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_go_test.py +0 -0
  307. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_googletest.py +0 -0
  308. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_gradle.py +0 -0
  309. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_jest.py +0 -0
  310. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_maven.py +0 -0
  311. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_minitest.py +0 -0
  312. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_nunit.py +0 -0
  313. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_playwright.py +0 -0
  314. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_prove.py +0 -0
  315. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_pytest.py +0 -0
  316. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_raw.py +0 -0
  317. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_robot.py +0 -0
  318. {launchable-1.98.3 → launchable-1.99.0}/tests/test_runners/test_rspec.py +0 -0
  319. {launchable-1.98.3 → launchable-1.99.0}/tests/test_session.py +0 -0
  320. {launchable-1.98.3 → launchable-1.99.0}/tests/test_testpath.py +0 -0
  321. {launchable-1.98.3 → launchable-1.99.0}/tests/test_version.py +0 -0
  322. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/__init__.py +0 -0
  323. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/test_authentication.py +0 -0
  324. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/test_file_name_pattern.py +0 -0
  325. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/test_git_log_parser.py +0 -0
  326. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/test_glob.py +0 -0
  327. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/test_gzipgen.py +0 -0
  328. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/test_http_client.py +0 -0
  329. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/test_link.py +0 -0
  330. {launchable-1.98.3 → launchable-1.99.0}/tests/utils/test_logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: launchable
3
- Version: 1.98.3
3
+ Version: 1.99.0
4
4
  Summary: Launchable CLI
5
5
  Home-page: https://launchableinc.com/
6
6
  Author: Launchable, Inc.
@@ -1,3 +1,4 @@
1
+ import datetime
1
2
  from time import time
2
3
  from typing import Optional, Sequence, Tuple
3
4
 
@@ -64,6 +65,7 @@ def find_or_create_session(
64
65
  is_no_build: bool = False,
65
66
  lineage: Optional[str] = None,
66
67
  test_suite: Optional[str] = None,
68
+ timestamp: Optional[datetime.datetime] = None,
67
69
  ) -> Optional[str]:
68
70
  """Determine the test session ID to be used.
69
71
 
@@ -134,6 +136,7 @@ def find_or_create_session(
134
136
  is_no_build=is_no_build,
135
137
  lineage=lineage,
136
138
  test_suite=test_suite,
139
+ timestamp=timestamp,
137
140
  )
138
141
  return read_session(saved_build_name)
139
142
 
@@ -1,3 +1,4 @@
1
+ import datetime
1
2
  import os
2
3
  import re
3
4
  import sys
@@ -11,7 +12,7 @@ from launchable.utils.tracking import Tracking, TrackingClient
11
12
 
12
13
  from ...utils import subprocess
13
14
  from ...utils.authentication import get_org_workspace
14
- from ...utils.click import KEY_VALUE
15
+ from ...utils.click import DATETIME_WITH_TZ, KEY_VALUE
15
16
  from ...utils.launchable_client import LaunchableClient
16
17
  from ...utils.session import clean_session_files, write_build
17
18
  from .commit import commit
@@ -96,13 +97,20 @@ CODE_BUILD_WEBHOOK_HEAD_REF_KEY = "CODEBUILD_WEBHOOK_HEAD_REF"
96
97
  'lineage',
97
98
  hidden=True,
98
99
  )
100
+ @click.option(
101
+ '--timestamp',
102
+ 'timestamp',
103
+ help='Used to overwrite the build time when importing historical data. Note: Format must be `YYYY-MM-DDThh:mm:ssTZD` or `YYYY-MM-DDThh:mm:ss` (local timezone applied)', # noqa: E501
104
+ type=DATETIME_WITH_TZ,
105
+ default=None,
106
+ )
99
107
  @click.pass_context
100
108
  def build(
101
109
  ctx: click.core.Context, build_name: str, source: List[str],
102
110
  max_days: int, no_submodules: bool, no_commit_collection: bool, scrub_pii: bool,
103
111
  commits: Sequence[Tuple[str, str]],
104
112
  links: Sequence[Tuple[str, str]],
105
- branches: Sequence[str], lineage: str):
113
+ branches: Sequence[str], lineage: str, timestamp: Optional[datetime.datetime]):
106
114
 
107
115
  if "/" in build_name or "%2f" in build_name.lower():
108
116
  sys.exit("--name must not contain a slash and an encoded slash")
@@ -326,7 +334,8 @@ def build(
326
334
  'commitHash': w.commit_hash,
327
335
  'branchName': w.branch or ""
328
336
  } for w in ws],
329
- "links": compute_links()
337
+ "links": compute_links(),
338
+ "timestamp": timestamp.isoformat() if timestamp else None,
330
339
  }
331
340
 
332
341
  res = client.request("post", "builds", payload=payload)
@@ -1,3 +1,4 @@
1
+ import datetime
1
2
  import os
2
3
  import re
3
4
  import sys
@@ -6,6 +7,7 @@ from typing import Optional, Sequence, Tuple
6
7
 
7
8
  import click
8
9
 
10
+ from launchable.utils.click import DATETIME_WITH_TZ
9
11
  from launchable.utils.link import LinkKind, capture_link
10
12
  from launchable.utils.tracking import Tracking, TrackingClient
11
13
 
@@ -98,6 +100,13 @@ def _validate_session_name(ctx, param, value):
98
100
  type=str,
99
101
  metavar='TEST_SUITE',
100
102
  )
103
+ @click.option(
104
+ '--timestamp',
105
+ 'timestamp',
106
+ help='Used to overwrite the session time when importing historical data. Note: Format must be `YYYY-MM-DDThh:mm:ssTZD` or `YYYY-MM-DDThh:mm:ss` (local timezone applied)', # noqa: E501
107
+ type=DATETIME_WITH_TZ,
108
+ default=None,
109
+ )
101
110
  @click.pass_context
102
111
  def session(
103
112
  ctx: click.core.Context,
@@ -111,6 +120,7 @@ def session(
111
120
  session_name: Optional[str] = None,
112
121
  lineage: Optional[str] = None,
113
122
  test_suite: Optional[str] = None,
123
+ timestamp: Optional[datetime.datetime] = None,
114
124
  ):
115
125
  """
116
126
  print_session is for backward compatibility.
@@ -166,6 +176,7 @@ def session(
166
176
  "noBuild": is_no_build,
167
177
  "lineage": lineage,
168
178
  "testSuite": test_suite,
179
+ "timestamp": timestamp.isoformat() if timestamp else None,
169
180
  }
170
181
 
171
182
  _links = capture_link(os.environ)
@@ -16,7 +16,7 @@ from launchable.utils.authentication import ensure_org_workspace
16
16
  from launchable.utils.tracking import Tracking, TrackingClient
17
17
 
18
18
  from ...testpath import FilePathNormalizer, TestPathComponent, unparse_test_path
19
- from ...utils.click import KEY_VALUE
19
+ from ...utils.click import DATETIME_WITH_TZ, KEY_VALUE
20
20
  from ...utils.exceptions import InvalidJUnitXMLException
21
21
  from ...utils.launchable_client import LaunchableClient
22
22
  from ...utils.logger import Logger
@@ -159,6 +159,13 @@ def _validate_group(ctx, param, value):
159
159
  type=str,
160
160
  metavar='TEST_SUITE',
161
161
  )
162
+ @click.option(
163
+ '--timestamp',
164
+ 'timestamp',
165
+ help='Used to overwrite the test executed times when importing historical data. Note: Format must be `YYYY-MM-DDThh:mm:ssTZD` or `YYYY-MM-DDThh:mm:ss` (local timezone applied)', # noqa: E501
166
+ type=DATETIME_WITH_TZ,
167
+ default=None,
168
+ )
162
169
  @click.pass_context
163
170
  def tests(
164
171
  context: click.core.Context,
@@ -177,6 +184,7 @@ def tests(
177
184
  session_name: Optional[str] = None,
178
185
  lineage: Optional[str] = None,
179
186
  test_suite: Optional[str] = None,
187
+ timestamp: Optional[datetime.datetime] = None,
180
188
  ):
181
189
  logger = Logger()
182
190
 
@@ -236,6 +244,7 @@ def tests(
236
244
  links=links,
237
245
  lineage=lineage,
238
246
  test_suite=test_suite,
247
+ timestamp=timestamp,
239
248
  tracking_client=tracking_client))
240
249
  build_name = read_build()
241
250
  record_start_at = get_record_start_at(session_id, client)
@@ -404,8 +413,13 @@ def tests(
404
413
  ctime = datetime.datetime.fromtimestamp(
405
414
  os.path.getctime(junit_report_file))
406
415
 
407
- if not self.is_allow_test_before_build and not self.is_no_build and (
408
- self.check_timestamp and ctime.timestamp() < record_start_at.timestamp()):
416
+ if (
417
+ not self.is_allow_test_before_build # nlqa: W503
418
+ and not self.is_no_build # noqa: W503
419
+ and timestamp is None # noqa: W503
420
+ and self.check_timestamp # noqa: W503
421
+ and ctime.timestamp() < record_start_at.timestamp() # noqa: W503
422
+ ):
409
423
  format = "%Y-%m-%d %H:%M:%S"
410
424
  logger.warning("skip: {} is too old to report. start_record_at: {} file_created_at: {}".format(
411
425
  junit_report_file, record_start_at.strftime(format), ctime.strftime(format)))
@@ -437,6 +451,10 @@ def tests(
437
451
  if len(tc.get('testPath', [])) == 0:
438
452
  continue
439
453
 
454
+ # Set specific time for importing historical data
455
+ if timestamp is not None:
456
+ tc["createdAt"] = timestamp.isoformat()
457
+
440
458
  yield tc
441
459
 
442
460
  except Exception as e:
@@ -3,7 +3,9 @@ import sys
3
3
  from typing import Dict, Optional, Tuple
4
4
 
5
5
  import click
6
+ import dateutil.parser
6
7
  from click import ParamType
8
+ from dateutil.tz import tzlocal
7
9
 
8
10
  # click.Group has the notion of hidden commands but it doesn't allow us to easily add
9
11
  # the same command under multiple names and hide all but one.
@@ -94,10 +96,25 @@ class FractionType(ParamType):
94
96
  self.fail("Expected fraction like 1/2 but got '{}'".format(value), param, ctx)
95
97
 
96
98
 
99
+ class DateTimeWithTimezoneType(ParamType):
100
+ name = "datetime"
101
+
102
+ def convert(self, value: str, param: Optional[click.core.Parameter], ctx: Optional[click.core.Context]):
103
+
104
+ try:
105
+ dt = dateutil.parser.parse(value)
106
+ if dt.tzinfo is None:
107
+ return dt.replace(tzinfo=tzlocal())
108
+ return dt
109
+ except ValueError:
110
+ self.fail("Expected datetime like 2023-10-01T12:00:00 but got '{}'".format(value), param, ctx)
111
+
112
+
97
113
  PERCENTAGE = PercentageType()
98
114
  DURATION = DurationType()
99
115
  FRACTION = FractionType()
100
116
  KEY_VALUE = KeyValueType()
117
+ DATETIME_WITH_TZ = DateTimeWithTimezoneType()
101
118
 
102
119
  # Can the output deal with Unicode emojis?
103
120
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: launchable
3
- Version: 1.98.3
3
+ Version: 1.99.0
4
4
  Summary: Launchable CLI
5
5
  Home-page: https://launchableinc.com/
6
6
  Author: Launchable, Inc.
@@ -59,7 +59,8 @@ class BuildTest(CliTestCase):
59
59
  "branchName": ""
60
60
  },
61
61
  ],
62
- "links": []
62
+ "links": [],
63
+ "timestamp": None
63
64
  }, payload)
64
65
 
65
66
  self.assertEqual(read_build(), self.build_name)
@@ -93,7 +94,8 @@ class BuildTest(CliTestCase):
93
94
  "branchName": ""
94
95
  },
95
96
  ],
96
- "links": []
97
+ "links": [],
98
+ "timestamp": None
97
99
  }, payload)
98
100
 
99
101
  self.assertEqual(read_build(), self.build_name)
@@ -124,7 +126,8 @@ class BuildTest(CliTestCase):
124
126
  "branchName": "",
125
127
  },
126
128
  ],
127
- "links": []
129
+ "links": [],
130
+ "timestamp": None
128
131
  }, payload)
129
132
 
130
133
  self.assertEqual(read_build(), self.build_name)
@@ -153,7 +156,8 @@ class BuildTest(CliTestCase):
153
156
  "branchName": ""
154
157
  },
155
158
  ],
156
- "links": []
159
+ "links": [],
160
+ 'timestamp': None
157
161
  }, payload)
158
162
  responses.calls.reset()
159
163
 
@@ -182,7 +186,8 @@ class BuildTest(CliTestCase):
182
186
  "branchName": "feature-xxx"
183
187
  },
184
188
  ],
185
- "links": []
189
+ "links": [],
190
+ "timestamp": None
186
191
  }, payload)
187
192
  responses.calls.reset()
188
193
 
@@ -211,7 +216,8 @@ class BuildTest(CliTestCase):
211
216
  "branchName": ""
212
217
  },
213
218
  ],
214
- "links": []
219
+ "links": [],
220
+ "timestamp": None
215
221
  }, payload)
216
222
  responses.calls.reset()
217
223
  self.assertIn("Invalid repository name B in a --branch option. ", result.output)
@@ -250,7 +256,8 @@ class BuildTest(CliTestCase):
250
256
  "branchName": "feature-yyy"
251
257
  },
252
258
  ],
253
- "links": []
259
+ "links": [],
260
+ "timestamp": None
254
261
  }, payload)
255
262
  responses.calls.reset()
256
263
 
@@ -260,3 +267,42 @@ class BuildTest(CliTestCase):
260
267
 
261
268
  result = self.cli("record", "build", "--no-commit-collection", "--name", "foo%2Fhoge")
262
269
  self.assert_exit_code(result, 1)
270
+
271
+ # make sure the output of git-submodule is properly parsed
272
+ @responses.activate
273
+ @mock.patch.dict(os.environ, {"LAUNCHABLE_TOKEN": CliTestCase.launchable_token})
274
+ # to tests on GitHub Actions
275
+ @mock.patch.dict(os.environ, {"GITHUB_ACTIONS": ""})
276
+ @mock.patch.dict(os.environ, {"GITHUB_PULL_REQUEST_URL": ""})
277
+ @mock.patch('launchable.utils.subprocess.check_output')
278
+ def test_with_timestamp(self, mock_check_output):
279
+ self.assertEqual(read_build(), None)
280
+ result = self.cli(
281
+ "record",
282
+ "build",
283
+ "--no-commit-collection",
284
+ "--commit",
285
+ "repo=abc12",
286
+ "--name",
287
+ self.build_name,
288
+ '--timestamp',
289
+ "2025-01-23 12:34:56Z")
290
+ self.assert_success(result)
291
+
292
+ payload = json.loads(responses.calls[0].request.body.decode())
293
+ self.assert_json_orderless_equal(
294
+ {
295
+ "buildNumber": "123",
296
+ "lineage": None,
297
+ "commitHashes": [
298
+ {
299
+ "repositoryName": "repo",
300
+ "commitHash": "abc12",
301
+ "branchName": ""
302
+ },
303
+ ],
304
+ "links": [],
305
+ "timestamp": "2025-01-23T12:34:56+00:00"
306
+ }, payload)
307
+
308
+ self.assertEqual(read_build(), self.build_name)
@@ -34,6 +34,7 @@ class SessionTest(CliTestCase):
34
34
  "noBuild": False,
35
35
  "lineage": None,
36
36
  "testSuite": None,
37
+ "timestamp": None,
37
38
  }, payload)
38
39
 
39
40
  @responses.activate
@@ -58,6 +59,7 @@ class SessionTest(CliTestCase):
58
59
  "noBuild": False,
59
60
  "lineage": None,
60
61
  "testSuite": None,
62
+ "timestamp": None,
61
63
  }, payload)
62
64
 
63
65
  result = self.cli("record", "session", "--build", self.build_name, "--flavor", "only-key")
@@ -82,6 +84,7 @@ class SessionTest(CliTestCase):
82
84
  "noBuild": False,
83
85
  "lineage": None,
84
86
  "testSuite": None,
87
+ "timestamp": None,
85
88
  }, payload)
86
89
 
87
90
  @responses.activate
@@ -120,6 +123,7 @@ class SessionTest(CliTestCase):
120
123
  "noBuild": False,
121
124
  "lineage": None,
122
125
  "testSuite": None,
126
+ "timestamp": None,
123
127
  }, payload)
124
128
 
125
129
  @responses.activate
@@ -140,6 +144,7 @@ class SessionTest(CliTestCase):
140
144
  "noBuild": False,
141
145
  "lineage": "example-lineage",
142
146
  "testSuite": None,
147
+ "timestamp": None,
143
148
  }, payload)
144
149
 
145
150
  @responses.activate
@@ -160,4 +165,26 @@ class SessionTest(CliTestCase):
160
165
  "noBuild": False,
161
166
  "lineage": None,
162
167
  "testSuite": "example-test-suite",
168
+ "timestamp": None,
169
+ }, payload)
170
+
171
+ @responses.activate
172
+ @mock.patch.dict(os.environ, {
173
+ "LAUNCHABLE_TOKEN": CliTestCase.launchable_token,
174
+ 'LANG': 'C.UTF-8',
175
+ }, clear=True)
176
+ def test_run_session_with_timestamp(self):
177
+ result = self.cli("record", "session", "--build", self.build_name,
178
+ "--timestamp", "2023-10-01T12:00:00Z")
179
+ self.assert_success(result)
180
+
181
+ payload = json.loads(responses.calls[0].request.body.decode())
182
+ self.assert_json_orderless_equal({
183
+ "flavors": {},
184
+ "isObservation": False,
185
+ "links": [],
186
+ "noBuild": False,
187
+ "lineage": None,
188
+ "testSuite": None,
189
+ "timestamp": "2023-10-01T12:00:00+00:00",
163
190
  }, payload)
@@ -1,10 +1,13 @@
1
+ import datetime
2
+ from datetime import timezone
1
3
  from typing import Sequence, Tuple
2
4
  from unittest import TestCase
3
5
 
4
6
  import click
5
7
  from click.testing import CliRunner
8
+ from dateutil.tz import tzlocal
6
9
 
7
- from launchable.utils.click import KEY_VALUE, convert_to_seconds
10
+ from launchable.utils.click import DATETIME_WITH_TZ, KEY_VALUE, convert_to_seconds
8
11
 
9
12
 
10
13
  class DurationTypeTest(TestCase):
@@ -42,3 +45,28 @@ class KeyValueTypeTest(TestCase):
42
45
  scenario([])
43
46
  scenario([('bar', 'zot')], '-f', 'bar=zot')
44
47
  scenario([('bar', 'zot'), ('a', 'b')], '-f', 'bar=zot', '-f', 'a=b')
48
+
49
+
50
+ class TimestampTypeTest(TestCase):
51
+ def test_conversion(self):
52
+ def scenario(expected: str, *args):
53
+ actual: datetime.datetime = datetime.datetime.now()
54
+
55
+ @click.command()
56
+ @click.option(
57
+ '-t',
58
+ 'timestamp',
59
+ type=DATETIME_WITH_TZ,
60
+ )
61
+ def time(timestamp: datetime.datetime):
62
+ nonlocal actual
63
+ actual = timestamp
64
+
65
+ result = CliRunner().invoke(time, args)
66
+
67
+ self.assertEqual(0, result.exit_code, result.stdout)
68
+ self.assertEqual(expected, actual)
69
+
70
+ scenario(datetime.datetime(2023, 10, 1, 12, 0, 0, tzinfo=tzlocal()), '-t', '2023-10-01 12:00:00')
71
+ scenario(datetime.datetime(2023, 10, 1, 20, 0, 0, tzinfo=timezone.utc), '-t', '2023-10-01 20:00:00+00:00')
72
+ scenario(datetime.datetime(2023, 10, 1, 20, 0, 0, tzinfo=timezone.utc), '-t', '2023-10-01T20:00:00Z')
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes