smart-tests-cli 2.0.0__py3-none-any.whl

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 (96) hide show
  1. smart_tests/__init__.py +0 -0
  2. smart_tests/__main__.py +60 -0
  3. smart_tests/app.py +67 -0
  4. smart_tests/args4p/README.md +102 -0
  5. smart_tests/args4p/__init__.py +13 -0
  6. smart_tests/args4p/argument.py +45 -0
  7. smart_tests/args4p/command.py +593 -0
  8. smart_tests/args4p/converters/__init__.py +75 -0
  9. smart_tests/args4p/decorators.py +98 -0
  10. smart_tests/args4p/exceptions.py +12 -0
  11. smart_tests/args4p/option.py +85 -0
  12. smart_tests/args4p/parameter.py +84 -0
  13. smart_tests/args4p/typer/__init__.py +42 -0
  14. smart_tests/commands/__init__.py +0 -0
  15. smart_tests/commands/compare/__init__.py +11 -0
  16. smart_tests/commands/compare/subsets.py +58 -0
  17. smart_tests/commands/detect_flakes.py +105 -0
  18. smart_tests/commands/inspect/__init__.py +13 -0
  19. smart_tests/commands/inspect/model.py +52 -0
  20. smart_tests/commands/inspect/subset.py +138 -0
  21. smart_tests/commands/record/__init__.py +19 -0
  22. smart_tests/commands/record/attachment.py +38 -0
  23. smart_tests/commands/record/build.py +356 -0
  24. smart_tests/commands/record/case_event.py +190 -0
  25. smart_tests/commands/record/commit.py +157 -0
  26. smart_tests/commands/record/session.py +120 -0
  27. smart_tests/commands/record/tests.py +498 -0
  28. smart_tests/commands/stats/__init__.py +11 -0
  29. smart_tests/commands/stats/test_sessions.py +45 -0
  30. smart_tests/commands/subset.py +567 -0
  31. smart_tests/commands/test_path_writer.py +51 -0
  32. smart_tests/commands/verify.py +153 -0
  33. smart_tests/jar/exe_deploy.jar +0 -0
  34. smart_tests/plugins/__init__.py +0 -0
  35. smart_tests/test_runners/__init__.py +0 -0
  36. smart_tests/test_runners/adb.py +24 -0
  37. smart_tests/test_runners/ant.py +35 -0
  38. smart_tests/test_runners/bazel.py +103 -0
  39. smart_tests/test_runners/behave.py +62 -0
  40. smart_tests/test_runners/codeceptjs.py +33 -0
  41. smart_tests/test_runners/ctest.py +164 -0
  42. smart_tests/test_runners/cts.py +189 -0
  43. smart_tests/test_runners/cucumber.py +451 -0
  44. smart_tests/test_runners/cypress.py +46 -0
  45. smart_tests/test_runners/dotnet.py +106 -0
  46. smart_tests/test_runners/file.py +20 -0
  47. smart_tests/test_runners/flutter.py +251 -0
  48. smart_tests/test_runners/go_test.py +99 -0
  49. smart_tests/test_runners/googletest.py +34 -0
  50. smart_tests/test_runners/gradle.py +96 -0
  51. smart_tests/test_runners/jest.py +52 -0
  52. smart_tests/test_runners/maven.py +149 -0
  53. smart_tests/test_runners/minitest.py +40 -0
  54. smart_tests/test_runners/nunit.py +190 -0
  55. smart_tests/test_runners/playwright.py +252 -0
  56. smart_tests/test_runners/prove.py +74 -0
  57. smart_tests/test_runners/pytest.py +358 -0
  58. smart_tests/test_runners/raw.py +238 -0
  59. smart_tests/test_runners/robot.py +125 -0
  60. smart_tests/test_runners/rspec.py +5 -0
  61. smart_tests/test_runners/smart_tests.py +235 -0
  62. smart_tests/test_runners/vitest.py +49 -0
  63. smart_tests/test_runners/xctest.py +79 -0
  64. smart_tests/testpath.py +154 -0
  65. smart_tests/utils/__init__.py +0 -0
  66. smart_tests/utils/authentication.py +78 -0
  67. smart_tests/utils/ci_provider.py +7 -0
  68. smart_tests/utils/commands.py +14 -0
  69. smart_tests/utils/commit_ingester.py +59 -0
  70. smart_tests/utils/common_tz.py +12 -0
  71. smart_tests/utils/edit_distance.py +11 -0
  72. smart_tests/utils/env_keys.py +19 -0
  73. smart_tests/utils/exceptions.py +34 -0
  74. smart_tests/utils/fail_fast_mode.py +99 -0
  75. smart_tests/utils/file_name_pattern.py +4 -0
  76. smart_tests/utils/git_log_parser.py +53 -0
  77. smart_tests/utils/glob.py +44 -0
  78. smart_tests/utils/gzipgen.py +46 -0
  79. smart_tests/utils/http_client.py +169 -0
  80. smart_tests/utils/java.py +61 -0
  81. smart_tests/utils/link.py +149 -0
  82. smart_tests/utils/logger.py +53 -0
  83. smart_tests/utils/no_build.py +2 -0
  84. smart_tests/utils/sax.py +119 -0
  85. smart_tests/utils/session.py +73 -0
  86. smart_tests/utils/smart_tests_client.py +134 -0
  87. smart_tests/utils/subprocess.py +12 -0
  88. smart_tests/utils/tracking.py +95 -0
  89. smart_tests/utils/typer_types.py +241 -0
  90. smart_tests/version.py +7 -0
  91. smart_tests_cli-2.0.0.dist-info/METADATA +168 -0
  92. smart_tests_cli-2.0.0.dist-info/RECORD +96 -0
  93. smart_tests_cli-2.0.0.dist-info/WHEEL +5 -0
  94. smart_tests_cli-2.0.0.dist-info/entry_points.txt +2 -0
  95. smart_tests_cli-2.0.0.dist-info/licenses/LICENSE.txt +202 -0
  96. smart_tests_cli-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,95 @@
1
+ from enum import Enum
2
+ from typing import Any, Dict, Union
3
+
4
+ from requests import Session
5
+
6
+ from smart_tests.app import Application
7
+ from smart_tests.utils.authentication import get_org_workspace
8
+ from smart_tests.utils.http_client import _HttpClient, _join_paths
9
+ from smart_tests.version import __version__
10
+
11
+ from .commands import Command
12
+
13
+
14
+ class Tracking:
15
+ # General events
16
+ class Event(Enum):
17
+ SHALLOW_CLONE = 'SHALLOW_CLONE' # this event is an example
18
+ PERFORMANCE = 'PERFORMANCE'
19
+
20
+ # Error events
21
+ class ErrorEvent(Enum):
22
+ UNKNOWN_ERROR = 'UNKNOWN_ERROR'
23
+ INTERNAL_CLI_ERROR = 'INTERNAL_CLI_ERROR'
24
+ WARNING_ERROR = 'WARNING_ERROR'
25
+ USER_ERROR = 'USER_ERROR'
26
+ # Errors related to requests package
27
+ NETWORK_ERROR = 'NETWORK_ERROR'
28
+ TIMEOUT_ERROR = 'TIMEOUT_ERROR'
29
+ INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR'
30
+ UNEXPECTED_HTTP_STATUS_ERROR = 'UNEXPECTED_HTTP_STATUS_ERROR'
31
+
32
+
33
+ class TrackingClient:
34
+ def __init__(self, command: Command, base_url: str = "", session: Session | None = None,
35
+ app: Application | None = None):
36
+ self.http_client = _HttpClient(
37
+ base_url=base_url,
38
+ session=session,
39
+ app=app
40
+ )
41
+ self.command = command
42
+
43
+ def send_event(
44
+ self,
45
+ event_name: Tracking.Event,
46
+ metadata: Dict[str, Any] | None = None
47
+ ):
48
+ org, workspace = get_org_workspace()
49
+ if metadata is None:
50
+ metadata = {}
51
+ metadata["organization"] = org or ""
52
+ metadata["workspace"] = workspace or ""
53
+ self._post_payload(
54
+ event_name=event_name,
55
+ metadata=metadata,
56
+ )
57
+
58
+ def send_error_event(
59
+ self,
60
+ event_name: Tracking.ErrorEvent,
61
+ stack_trace: str,
62
+ api: str = "",
63
+ metadata: Dict[str, Any] | None = None
64
+ ):
65
+ org, workspace = get_org_workspace()
66
+ if metadata is None:
67
+ metadata = {}
68
+ metadata["stackTrace"] = stack_trace
69
+ metadata["organization"] = org or ""
70
+ metadata["workspace"] = workspace or ""
71
+ metadata["api"] = api
72
+ self._post_payload(
73
+ event_name=event_name,
74
+ metadata=metadata,
75
+ )
76
+
77
+ def _post_payload(
78
+ self,
79
+ event_name: Union[Tracking.Event, Tracking.ErrorEvent],
80
+ metadata: Dict[str, Any]
81
+ ):
82
+ payload = {
83
+ "command": self.command.value,
84
+ "eventName": event_name.value,
85
+ "cliVersion": __version__,
86
+ "metadata": metadata,
87
+ }
88
+ path = _join_paths(
89
+ '/intake',
90
+ 'cli_tracking'
91
+ )
92
+ try:
93
+ self.http_client.request('post', payload=payload, path=path)
94
+ except Exception:
95
+ pass
@@ -0,0 +1,241 @@
1
+ import datetime
2
+ import re
3
+ import sys
4
+
5
+ import dateutil.parser
6
+ from dateutil.tz import tzlocal
7
+
8
+ from smart_tests.args4p.exceptions import BadCmdLineException
9
+
10
+
11
+ class Percentage:
12
+ def __init__(self, value: float):
13
+ self.value = value
14
+
15
+ def __str__(self):
16
+ return f"{self.value * 100}%"
17
+
18
+ def __float__(self):
19
+ return self.value
20
+
21
+
22
+ def parse_percentage(value: str) -> Percentage:
23
+ try:
24
+ missing_percent = False
25
+ if value.endswith('%'):
26
+ x = float(value[:-1]) / 100
27
+ if 0 <= x <= 1:
28
+ return Percentage(x)
29
+ else:
30
+ missing_percent = True
31
+ except ValueError:
32
+ pass
33
+
34
+ msg = "Expected percentage like 50% but got '{}'".format(value)
35
+ if missing_percent and sys.platform.startswith("win"):
36
+ msg += " ('%' is a special character in batch files, so please write '50%%' to pass in '50%')"
37
+ raise BadCmdLineException(msg)
38
+
39
+
40
+ class Duration:
41
+ def __init__(self, seconds: float):
42
+ self.seconds = seconds
43
+
44
+ def __str__(self):
45
+ return f"{self.seconds}s"
46
+
47
+ def __float__(self):
48
+ return self.seconds
49
+
50
+
51
+ def parse_duration(value: str) -> Duration:
52
+ try:
53
+ return Duration(convert_to_seconds(value))
54
+ except ValueError:
55
+ raise BadCmdLineException("Expected duration like 3600, 30m, 1h15m but got '{}'".format(value))
56
+
57
+
58
+ class KeyValue:
59
+ def __init__(self, key: str, value: str):
60
+ self.key = key
61
+ self.value = value
62
+
63
+ def __str__(self):
64
+ return f"{self.key}={self.value}"
65
+
66
+ def __iter__(self):
67
+ return iter((self.key, self.value))
68
+
69
+ def __getitem__(self, index):
70
+ return (self.key, self.value)[index]
71
+
72
+
73
+ def parse_key_value(value: str) -> KeyValue:
74
+ """
75
+ Handles options that take key/value pairs.
76
+
77
+ The preferred syntax is "--option key=value" and that's what we should be advertising in docs and help,
78
+ but for compatibility (?) we accept "--option key:value"
79
+
80
+ Typically, this is used with multiple=True to produce `Sequence[Tuple[str, str]]`.
81
+ """
82
+ error_message = "Expected a key-value pair formatted as --option key=value, but got '{}'"
83
+
84
+ for delimiter in ['=', ':']:
85
+ if delimiter in value:
86
+ kv = value.split(delimiter, 1)
87
+ if len(kv) != 2:
88
+ raise BadCmdLineException(error_message.format(value))
89
+ return KeyValue(kv[0].strip(), kv[1].strip())
90
+
91
+ raise BadCmdLineException(error_message.format(value))
92
+
93
+
94
+ class Fraction:
95
+ def __init__(self, numerator: int, denominator: int):
96
+ self.numerator = numerator
97
+ self.denominator = denominator
98
+
99
+ def __str__(self):
100
+ return f"{self.numerator}/{self.denominator}"
101
+
102
+ def __iter__(self):
103
+ return iter((self.numerator, self.denominator))
104
+
105
+ def __getitem__(self, index):
106
+ return (self.numerator, self.denominator)[index]
107
+
108
+ def __float__(self):
109
+ return self.numerator / self.denominator
110
+
111
+
112
+ def parse_fraction(value: str) -> Fraction:
113
+ try:
114
+ v = value.strip().split('/')
115
+ if len(v) == 2:
116
+ n = int(v[0])
117
+ d = int(v[1])
118
+ return Fraction(n, d)
119
+ except ValueError:
120
+ pass
121
+
122
+ raise BadCmdLineException("Expected fraction like 1/2 but got '{}'".format(value))
123
+
124
+
125
+ class DateTimeWithTimezone:
126
+ def __init__(self, dt: datetime.datetime):
127
+ self.dt = dt
128
+
129
+ def __str__(self):
130
+ return self.dt.isoformat()
131
+
132
+ def datetime(self):
133
+ return self.dt
134
+
135
+
136
+ def parse_datetime_with_timezone(value: str) -> DateTimeWithTimezone:
137
+ try:
138
+ dt = dateutil.parser.parse(value)
139
+ if dt.tzinfo is None:
140
+ dt = dt.replace(tzinfo=tzlocal())
141
+ return DateTimeWithTimezone(dt)
142
+ except ValueError:
143
+ raise BadCmdLineException("Expected datetime like 2023-10-01T12:00:00 but got '{}'".format(value))
144
+
145
+
146
+ def convert_to_seconds(s: str) -> float:
147
+ """Convert duration string to seconds"""
148
+ units = {'s': 1, 'm': 60, 'h': 60 * 60, 'd': 60 * 60 * 24, 'w': 60 * 60 * 24 * 7}
149
+
150
+ if s.isdigit():
151
+ return float(s)
152
+
153
+ duration = 0
154
+ for m in re.finditer(r'(?P<val>\d+)(?P<unit>[smhdw]?)', s, flags=re.I):
155
+ val = m.group('val')
156
+ unit = m.group('unit')
157
+
158
+ if val is None or unit is None:
159
+ raise ValueError(f"unable to parse: {s}")
160
+
161
+ u = units.get(unit)
162
+ if u is None:
163
+ raise ValueError(f"unable to parse: {s}")
164
+
165
+ duration += int(val) * u
166
+
167
+ return float(duration)
168
+
169
+
170
+ # Can the output deal with Unicode emojis?
171
+ try:
172
+ '\U0001f389'.encode(sys.stdout.encoding or "ascii")
173
+ # If stdout encoding is unavailable, such as in case of pipe, err on the safe side (EMOJI=False)
174
+ # This is a judgement call, but given that emojis do not serve functional purposes and purely decorative
175
+ # erring on the safe side seems like a reasonable call.
176
+ EMOJI = True
177
+ except UnicodeEncodeError:
178
+ EMOJI = False
179
+
180
+
181
+ def emoji(s: str, fallback: str = '') -> str:
182
+ """
183
+ Used to safely use Emoji where we can.
184
+
185
+ Returns 's' in an environment where stdout can deal with emojis, but 'fallback' otherwise.
186
+ """
187
+ return s if EMOJI else fallback
188
+
189
+
190
+ def ignorable_error(e: Exception) -> str:
191
+ return "An error occurred on Smart Tests CLI. You can ignore this message since the process will continue. " \
192
+ f"Error: {e}"
193
+
194
+
195
+ def parse_key_value_list(values: list) -> list:
196
+ """Parse a list of key-value strings into KeyValue objects"""
197
+ return [parse_key_value(v) for v in values]
198
+
199
+
200
+ # Backward compatibility functions for existing usage
201
+ def validate_key_value(value: str):
202
+ """Validate and parse a key-value string, returning a tuple for backward compatibility"""
203
+ kv = parse_key_value(value)
204
+ return (kv.key, kv.value)
205
+
206
+
207
+ def validate_datetime_with_tz(value: str):
208
+ """Validate and parse a datetime string, returning a datetime object for backward compatibility"""
209
+ dt_obj = parse_datetime_with_timezone(value)
210
+ return dt_obj.dt
211
+
212
+
213
+ def validate_past_datetime(dt_value: datetime.datetime):
214
+ """Validate that the provided datetime is in the past"""
215
+ if dt_value is None:
216
+ return dt_value
217
+
218
+ if not isinstance(dt_value, datetime.datetime):
219
+ raise BadCmdLineException("Expected a datetime object.")
220
+
221
+ now = datetime.datetime.now(tz=tzlocal())
222
+ if dt_value > now:
223
+ raise BadCmdLineException("The provided timestamp must be in the past.")
224
+
225
+ return dt_value
226
+
227
+
228
+ def _key_value_compat(value: str):
229
+ """Compatibility wrapper that returns tuple instead of KeyValue object"""
230
+ kv = parse_key_value(value)
231
+ return (kv.key, kv.value)
232
+
233
+
234
+ def _datetime_with_tz_compat(value: str):
235
+ """Compatibility wrapper that returns datetime instead of DateTimeWithTimezone object"""
236
+ dt_obj = parse_datetime_with_timezone(value)
237
+ return dt_obj.dt
238
+
239
+
240
+ KEY_VALUE = _key_value_compat
241
+ DATETIME_WITH_TZ = _datetime_with_tz_compat
smart_tests/version.py ADDED
@@ -0,0 +1,7 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ __version__ = version("smart-tests-cli")
5
+ except PackageNotFoundError:
6
+ # package is not installed
7
+ __version__ = "unknown"
@@ -0,0 +1,168 @@
1
+ Metadata-Version: 2.4
2
+ Name: smart-tests-cli
3
+ Version: 2.0.0
4
+ Summary: Smart Tests CLI
5
+ Author-email: CloudBees <support@cloudbees.com>
6
+ License: Apache Software License v2
7
+ Project-URL: Homepage, https://www.cloudbees.com/capabilities/cloudbees-smart-tests
8
+ Project-URL: Repository, https://github.com/launchableinc/cli
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.13
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE.txt
15
+ Requires-Dist: requests>=2.32.5
16
+ Requires-Dist: urllib3>=2.5
17
+ Requires-Dist: junitparser>=4.0.0
18
+ Requires-Dist: more-itertools>=7.1.0
19
+ Requires-Dist: python-dateutil>=2.9
20
+ Requires-Dist: tabulate>=0.9
21
+ Requires-Dist: click<8.2,>=8.1
22
+ Dynamic: license-file
23
+
24
+ # Usage
25
+
26
+ See https://help.launchableinc.com/resources/cli-reference/ and
27
+ https://help.launchableinc.com/sending-data-to-launchable/using-the-launchable-cli/getting-started/.
28
+
29
+ # Development
30
+
31
+ ## Preparation
32
+
33
+ We recommend uv for dependency management:
34
+
35
+ ```shell
36
+ # Install uv
37
+ curl -LsSf https://astral.sh/uv/install.sh | sh
38
+
39
+ # Install dependencies
40
+ uv sync --dev
41
+ ```
42
+
43
+ In order to automatically format files with autopep8, this repository contains a
44
+ configuration for [pre-commit](https://pre-commit.com). Install the hook with
45
+ `uv run pre-commit install`.
46
+
47
+ ## Load development environment
48
+
49
+ ```shell
50
+ # Activate virtual environment
51
+ source .venv/bin/activate
52
+ # or use uv run for individual commands
53
+ uv run <command>
54
+ ```
55
+
56
+ ## Run tests cli
57
+
58
+ ```shell
59
+ # Using poethepoet (recommended)
60
+ uv run poe test
61
+
62
+ # Direct command
63
+ uv run python -m unittest
64
+ ```
65
+
66
+ ## Run tests exe_deploy.jar
67
+
68
+ ```
69
+ bazel test ...
70
+ ```
71
+
72
+ ## Available Development Tasks
73
+
74
+ This project uses [poethepoet](https://poethepoet.natn.io/) for task management. Available tasks:
75
+
76
+ ```shell
77
+ # Show all available tasks
78
+ uv run poe --help
79
+
80
+ # Run tests
81
+ uv run poe test
82
+
83
+ # Run tests with XML output
84
+ uv run poe test-xml
85
+
86
+ # Run linting
87
+ uv run poe lint
88
+
89
+ # Run type checking
90
+ uv run poe type
91
+
92
+ # Format code
93
+ uv run poe format
94
+
95
+ # Build package
96
+ uv run poe build
97
+
98
+ # Install package locally
99
+ uv run poe install
100
+ ```
101
+
102
+ ## Add dependency
103
+
104
+ ```shell
105
+ # Add runtime dependency
106
+ uv add some-package
107
+
108
+ # Add development dependency
109
+ uv add --dev some-dev-package
110
+ ```
111
+
112
+ ## Updating Python Version
113
+
114
+ When updating the Python version requirement, update the following files:
115
+
116
+ 1. **`.python-version`** - Used by pyenv, uv, and local development
117
+ 2. **`pyproject.toml`** - Update `requires-python = ">=X.Y"`
118
+ 3. **`setup.cfg`** - Update `python_requires = >=X.Y`
119
+ 4. **`.github/workflows/python-package.yml`** - Update `python-version: ["X.Y"]`
120
+ 5. **`.github/workflows/python-publish.yml`** - Update `uv python install X.Y`
121
+ 6. **`README.md`** - Update prerequisite section
122
+ 7. **`CLAUDE.md`** - Update development notes
123
+
124
+ # How to release
125
+
126
+ Create new release on Github, then Github Actions automatically uploads the
127
+ module to PyPI.
128
+
129
+ ## How to update smart_tests/jar/exe_deploy.jar
130
+
131
+ ```
132
+ ./build-java.sh
133
+ ```
134
+
135
+ # Installing CLI
136
+
137
+ You can install the `smart-tests` command from either source or [pypi](https://pypi.org/project/smart-tests/).
138
+
139
+ ## Prerequisite
140
+
141
+ - \>= Python 3.13
142
+ - \>= Java 8
143
+
144
+ ## Install from source
145
+
146
+ ```sh
147
+ $ pwd
148
+ ~/cli
149
+
150
+ $ python setup.py install
151
+ ```
152
+
153
+ ## Install from pypi
154
+
155
+ ```sh
156
+ $ pip3 install --user --upgrade smart-tests~=1.0
157
+ ```
158
+
159
+ ## Versioning
160
+
161
+ This module follows [Semantic versioning](https://semver.org/) such as X.Y.Z.
162
+
163
+ * Major (X)
164
+ * Drastic update breaking backward compatibility
165
+ * Minor (Y)
166
+ * Add new plugins, options with backward compatibility
167
+ * Patch (Z)-
168
+ * Fix bugs or minor behaviors
@@ -0,0 +1,96 @@
1
+ smart_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ smart_tests/__main__.py,sha256=k4FIJjpCPmaJyfEqH7Q0YRXERFAPM-HpSVBaa9sbRAA,1820
3
+ smart_tests/app.py,sha256=8ydkzRvYQ4hpTMeKbaozW5m5SpLL4LhxRO1knPfkXcU,2999
4
+ smart_tests/testpath.py,sha256=aVdNC3q97m6p6p3KhmzHJmyRa_bTS1AsQKBPkfeYwbU,5289
5
+ smart_tests/version.py,sha256=5C6VKSV_QmMEFor7D6WP0Rl6joDXnrBlPPU3EoMhrW8,200
6
+ smart_tests/args4p/README.md,sha256=Q66SR7eLzWxx3Ow1JscrCipqXubQEd3aA74YqdMN5Dg,3775
7
+ smart_tests/args4p/__init__.py,sha256=RmEeQKwg35AdsXoKQy4Od-dPKRerMkwLO-XOtESdbgI,301
8
+ smart_tests/args4p/argument.py,sha256=AbvQk0tNbTmzjcGV_O2kYa6FwYqCI6Ca1e8Hg-49nwI,1662
9
+ smart_tests/args4p/command.py,sha256=RTgqKPgl0CC1xJqVfquyJWgS_hTWR6ZLajv4U7776vw,22878
10
+ smart_tests/args4p/decorators.py,sha256=tyumCTk6zacWRWaUJ4zxTp-twkYL1u09qYEkJG42pfE,2751
11
+ smart_tests/args4p/exceptions.py,sha256=NmQDYNTP4I-lABSuOU-gxQpNs_ta9ISV8mqD88LOxAA,306
12
+ smart_tests/args4p/option.py,sha256=ccS8q08-shlk5rFyMn8cS7Ipn2rJwzAVlqDvMzbzfIA,3083
13
+ smart_tests/args4p/parameter.py,sha256=N7n3hrdhQrFd-G68CkYpsMaIFNruzcNdo5nvCiu0v3k,3261
14
+ smart_tests/args4p/converters/__init__.py,sha256=vXnB161nOXNUd-_Rq3cleJaviQhZvR7lb7DGUfM_9bI,2495
15
+ smart_tests/args4p/typer/__init__.py,sha256=6AgBbi73qDXtyWZOLJ8gmgEEebw5wdsGNAC5V0cbVCE,1297
16
+ smart_tests/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ smart_tests/commands/detect_flakes.py,sha256=Qnbq0Gd6Cnzj4ZlU8hwjeA3rJIQICQtV-nNxLrfjcNE,3986
18
+ smart_tests/commands/subset.py,sha256=jPADKoxLxeM89ozdTXeiubchYRIHV84nqPgLJpPp4u8,24617
19
+ smart_tests/commands/test_path_writer.py,sha256=oaTN0ft0nyRxtw8QFHGrfRUMZtj6zntSBcBu9IDEuGM,1879
20
+ smart_tests/commands/verify.py,sha256=in3dAnCR4Sd4OyOnM1jMYWl06fSQmTpUvrEUlUwfHbo,5849
21
+ smart_tests/commands/compare/__init__.py,sha256=y1XfRibrCuktoTykHgdi1ZGIlq5YuOtswMPcDpyEyaY,178
22
+ smart_tests/commands/compare/subsets.py,sha256=0Z_4WvH7cGxwod6mDAq9D2tN5vUZJG1ETSOA6Zv6Rmk,2222
23
+ smart_tests/commands/inspect/__init__.py,sha256=dwf1yRVpH74sjSUAIH9gkiKJuUdd1k04jaGZ4Z7fV4k,262
24
+ smart_tests/commands/inspect/model.py,sha256=iqlYcuB-f44DBqVvzyrdHHzwaXoWopa63_4hH-oSc_0,1461
25
+ smart_tests/commands/inspect/subset.py,sha256=fo609fCXbZ-TZTOz-FXj93QWlLPW6ONLIQFY_EmcWaU,4325
26
+ smart_tests/commands/record/__init__.py,sha256=d3I_SpA4OoqyeS5ORTe8AdSGEfJYg4mP-6ONaEvp-PQ,455
27
+ smart_tests/commands/record/attachment.py,sha256=nA9TUOK6-VD7CMmEjR-3tjGjPTEv7dzVXnBZ112zJEk,1198
28
+ smart_tests/commands/record/build.py,sha256=yhk68195kLkvgY0SqONHfuV-ALi7QgW72Za-BIq4lMs,15625
29
+ smart_tests/commands/record/case_event.py,sha256=cl2Pu44_QD7_cRFjtJoA-dsdnGfCgiHU5Go5mcdfNQk,6403
30
+ smart_tests/commands/record/commit.py,sha256=Z33nSV3Iz5rSMEl_jKgE0V7A_Q-mdw1kmUcqChTCf6w,5329
31
+ smart_tests/commands/record/session.py,sha256=_CE79yOk9YFI2_rosP92VuxeSLFHCJ1Cb5ycmA-taFY,4391
32
+ smart_tests/commands/record/tests.py,sha256=LgOx_8VUabPB-0x1eJoe-kbSO-jcr72jGZWbY4syfEw,19903
33
+ smart_tests/commands/stats/__init__.py,sha256=dUljXynXv-43lJq93bMoJO3oVCsiozv0mZv3rHebF38,192
34
+ smart_tests/commands/stats/test_sessions.py,sha256=QbZFBNUIGsFhbsA0pWr4U1wSBpZwKUblq3MWTOEfCwE,1252
35
+ smart_tests/jar/exe_deploy.jar,sha256=1PDhaNtkHgWkEYCOtznSYKZ8W-zDsQspr2nVuLkQQrY,12594800
36
+ smart_tests/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ smart_tests/test_runners/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ smart_tests/test_runners/adb.py,sha256=YYcMOlFWBZH89TcMaFfGa6XD70tZHQ73OSxl7efrsuE,616
39
+ smart_tests/test_runners/ant.py,sha256=3IfnJYyR8pV6vHfs2kzsJbXeytSGFUl6B9JHYhwXkSE,942
40
+ smart_tests/test_runners/bazel.py,sha256=IoAvFScmPk4l6AcigqBgHb8ZG3w4MeH-HYvXe0MRBvc,3536
41
+ smart_tests/test_runners/behave.py,sha256=6NPniB7y9VA1TOUBxyXeJnDV1YiHag1LoXGO8n9A-PE,1538
42
+ smart_tests/test_runners/codeceptjs.py,sha256=2d_9gbi0KXawU1VGDQ4X8KW_q5ezj1ijNQ4FMcwYHko,1016
43
+ smart_tests/test_runners/ctest.py,sha256=lL3UkJwRts-hsijcDmUO3FrkrNXTfpwEB3mQ8TaLATw,5468
44
+ smart_tests/test_runners/cts.py,sha256=W6lJQDooWBaSg1ueEiHNCQzx3ue3irdcl6cxoEIFvuM,7076
45
+ smart_tests/test_runners/cucumber.py,sha256=Ci-5odG8N18_As6M7pEQIle7sOf8UsTJcBDJG5VeCf8,16074
46
+ smart_tests/test_runners/cypress.py,sha256=HUozYxyns5_HCtfZDQX6flxB2Ail9bjHPYgWOsmjP1Y,1276
47
+ smart_tests/test_runners/dotnet.py,sha256=d052z6NXOTpnkxX9xJCdG87nj3YOayEQyiH-9duyilA,3281
48
+ smart_tests/test_runners/file.py,sha256=pWTaEtg9PowRstp4Drf38vWb655Ce2oUYndtf6PNrVc,526
49
+ smart_tests/test_runners/flutter.py,sha256=RiG4cimK-uU3NkFRCSWoceQgTp1S0ZfqwtGA_dEZfkM,8325
50
+ smart_tests/test_runners/go_test.py,sha256=f0foXNEUPRTguKloBFgtCqc0rNqRnNqeE4fMp4ESDic,3620
51
+ smart_tests/test_runners/googletest.py,sha256=SBo-9OZAM4shL5ok5xKd21pO_jhv2K6eJCEphvZz58Q,988
52
+ smart_tests/test_runners/gradle.py,sha256=eOg9-X1u7lZGpj016bGjzi4iq-PqZ0Y2NvQmmtNqE4c,3172
53
+ smart_tests/test_runners/jest.py,sha256=4lQYBxJ24z-G2YyAW13pWld5mH6-SBTjsbumqPfe010,1334
54
+ smart_tests/test_runners/maven.py,sha256=IH_VHxMEq4EMvTrGDHqWdTMGB9y9ABF2_AmJYUVib4Y,5146
55
+ smart_tests/test_runners/minitest.py,sha256=hB8UkdgtPkJy71Wx5kflkQvgbyVp5T4ZMtlNIMagAIU,1538
56
+ smart_tests/test_runners/nunit.py,sha256=K_-uxY2QEqgvWLu5FOoZfR64AHJZsou006NlupdjxBw,7493
57
+ smart_tests/test_runners/playwright.py,sha256=rxvdUJrKoh7Hjec_RRoGrKUkWsuPBtSM8obzE354rR0,10572
58
+ smart_tests/test_runners/prove.py,sha256=OfvGIbXK3K9DkdJLlSAcLyQn2Ec12CiPRNiToktECD0,2436
59
+ smart_tests/test_runners/pytest.py,sha256=RFd3RiAp1_EwzR0XdOVpRFAu8yoDhhQPq_JN8vDSSAY,13619
60
+ smart_tests/test_runners/raw.py,sha256=nf2PnRkVCp4Qmsl0Aw3OfqreXl8GqED4SyPgo02N6vQ,7974
61
+ smart_tests/test_runners/robot.py,sha256=AHk8d--Szgbj5S4VcDlxjDEW01ifFazaUAhli5Xq7XM,3907
62
+ smart_tests/test_runners/rspec.py,sha256=t3ucgPvgepib17iNu1eu3WqMhPHgsFCCqARQthEyT7I,252
63
+ smart_tests/test_runners/smart_tests.py,sha256=yOmXsj6uNR6ZiVSrK9iOvWimab1NhiezJuDbqibHTQQ,7789
64
+ smart_tests/test_runners/vitest.py,sha256=NasFpi7je01PXXuoT_Z6WVb52cUxc3vjqALUkKW8rAk,1565
65
+ smart_tests/test_runners/xctest.py,sha256=VZ6SDYPHX3HGLIpDrwC_DRgSSTiO8bTwvfzr9-hdgnA,2578
66
+ smart_tests/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
+ smart_tests/utils/authentication.py,sha256=8PiY4zQqD0m3_8i18-c_QT0HNy_8N3er5GJ3Ak_yZv0,2895
68
+ smart_tests/utils/ci_provider.py,sha256=YiXWXFqPH7uoOORgTui4M9lFxugctUYIB40gzQwNpL8,136
69
+ smart_tests/utils/commands.py,sha256=4z7SGGutNZFc1TME5o1YgJdJB0Og7BGB8Ib__dkmMwM,332
70
+ smart_tests/utils/commit_ingester.py,sha256=Qj-n5cID1ZpHB9IsGzqIpj2hXp9rqZpwPpmOU9iA3ss,1943
71
+ smart_tests/utils/common_tz.py,sha256=cwPKKgH7XxbnQFjxNqNub7VL7_tiy2hTx4GC1bzlb4Y,472
72
+ smart_tests/utils/edit_distance.py,sha256=NxzXfWxJtnzGbEFtkPOV-X1MYJqKsrCSKEj6lU-hlIY,405
73
+ smart_tests/utils/env_keys.py,sha256=JaY_C9xN5fiAcj8B-cQ2kjCzBbtnZJEVURpLHUVwjQw,656
74
+ smart_tests/utils/exceptions.py,sha256=nAUJiFrsvgWalYpj9XmFQMMTeYo7YBzquUhJNApUJEQ,994
75
+ smart_tests/utils/fail_fast_mode.py,sha256=BtkXAj49sMNFpnoluN2kvgv3NNNhbP1u7THiQpw7mfE,3334
76
+ smart_tests/utils/file_name_pattern.py,sha256=8f0jD9P0TQ7ivuJG_vJQOymVyOfdsks-NqcBnbm2UIM,169
77
+ smart_tests/utils/git_log_parser.py,sha256=4gIyBgyoTT3gPR_nT3rsi-AI-Da6YufjQpvyhXWZxzk,1985
78
+ smart_tests/utils/glob.py,sha256=smQ6_hpAop011YM2n-1Sr517xObElYnR1-9F3SZLOJ8,1156
79
+ smart_tests/utils/gzipgen.py,sha256=hjRwb26leFgEijnOK2JySMljZTuJCN8qxFKqWGzCNaE,1339
80
+ smart_tests/utils/http_client.py,sha256=g6zWp6FYPxazrBJgc_SqUNuu3cw_AyWEeJOrE6X1T3c,5806
81
+ smart_tests/utils/java.py,sha256=E1X7aqSwp2kb_cnS67kmKlm3XRyQOkk48qfTNogajC8,2368
82
+ smart_tests/utils/link.py,sha256=lTpPBIiccyig57MnYY1tGb8fiPmEnxc9UDkDPSXJTXs,5539
83
+ smart_tests/utils/logger.py,sha256=XRcwb26_drwuFrn8IvP-m1G383gbZk7SjB_U1ONLX84,1444
84
+ smart_tests/utils/no_build.py,sha256=g54DOtRsu5vj8X43vgI8-dLJ3oMnMH_HXlirVX45yCc,62
85
+ smart_tests/utils/sax.py,sha256=9OJp1EPyiZjE_0L3uYMlPB5SoXnOjg2h_mgrghTU6Ow,3364
86
+ smart_tests/utils/session.py,sha256=DDHSAXK9cFpIqi5SA2nKg1XTIGGwdrwM95-I-TngpXg,2313
87
+ smart_tests/utils/smart_tests_client.py,sha256=qfsx8VP059YKQRCM4ehJjTp5Xzr8-O4S_dWYrXelFIM,4854
88
+ smart_tests/utils/subprocess.py,sha256=McD1_IT5uGhRyF61zfmMHwYrPCGPaMum9jMrYF2TExs,428
89
+ smart_tests/utils/tracking.py,sha256=h-EcD4fytkzpX9oGu1zago2Wg7hRxqsxU3NwsMeqQwM,2818
90
+ smart_tests/utils/typer_types.py,sha256=uNI92j8XyhDem7bxxZ1LBZ5TDwbEv_3-zEgrWUoEV08,6906
91
+ smart_tests_cli-2.0.0.dist-info/licenses/LICENSE.txt,sha256=o7VmUVwJZRYoM7X4LVmpNdnSLzUVJ58jSo6esi7DptM,11365
92
+ smart_tests_cli-2.0.0.dist-info/METADATA,sha256=C2kWjWV6EZlvoLjqezj9Ytz_HhgacqeApKUjNL3rjFc,3623
93
+ smart_tests_cli-2.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
94
+ smart_tests_cli-2.0.0.dist-info/entry_points.txt,sha256=fkU5blN61P41jH8W8mhjxvQBFq-rl7bLxIMsFrvbS8c,58
95
+ smart_tests_cli-2.0.0.dist-info/top_level.txt,sha256=NQto8RXlGDM3OzqENbAqirHoSi5O0k7dpDPV34s1Bbg,12
96
+ smart_tests_cli-2.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ smart-tests = smart_tests.__main__:main