ovoscope 0.0.1__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.
- ovoscope-0.0.1/PKG-INFO +92 -0
- ovoscope-0.0.1/README.md +76 -0
- ovoscope-0.0.1/ovoscope/__init__.py +171 -0
- ovoscope-0.0.1/ovoscope/version.py +6 -0
- ovoscope-0.0.1/ovoscope.egg-info/PKG-INFO +92 -0
- ovoscope-0.0.1/ovoscope.egg-info/SOURCES.txt +10 -0
- ovoscope-0.0.1/ovoscope.egg-info/dependency_links.txt +1 -0
- ovoscope-0.0.1/ovoscope.egg-info/not-zip-safe +1 -0
- ovoscope-0.0.1/ovoscope.egg-info/requires.txt +1 -0
- ovoscope-0.0.1/ovoscope.egg-info/top_level.txt +1 -0
- ovoscope-0.0.1/setup.cfg +4 -0
- ovoscope-0.0.1/setup.py +53 -0
ovoscope-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: ovoscope
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: End-to-end test framework for OpenVoiceOS skills
|
|
5
|
+
Home-page: https://github.com/TigreGotico/ovoscope
|
|
6
|
+
Author: JarbasAI
|
|
7
|
+
Author-email: jarbasai@mailfence.com
|
|
8
|
+
License: Apache-2.0
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Topic :: Software Development :: Testing
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# OvoScope
|
|
18
|
+
|
|
19
|
+
**OvoScope** is an end-to-end testing framework for [OVOS](https://openvoiceos.org) skills.
|
|
20
|
+
|
|
21
|
+
It contains the full core runtime environment using a lightweight in-process `ovos-core`, allowing skill developers to test the full skill message flow, from utterance to intent handling to final bus responses — without launching a full assistant stack.
|
|
22
|
+
|
|
23
|
+
> Like a microscope for your OVOS skills.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- Simulates OVOS Core messagebus interactions
|
|
30
|
+
- Sends test `Message` objects and captures responses
|
|
31
|
+
- Verifies message types, data, routing, session handling, and language
|
|
32
|
+
- Automatically flips message direction when configured
|
|
33
|
+
- Designed to integrate cleanly into `unittest` or `pytest` workflows
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install ovoscope
|
|
41
|
+
````
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Usage Example
|
|
46
|
+
|
|
47
|
+
Testing scenario of complete intent failure (no skills installed)
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from ovoscope import End2EndTest
|
|
51
|
+
from ovos_bus_client.message import Message
|
|
52
|
+
from ovos_bus_client.session import Session
|
|
53
|
+
|
|
54
|
+
session = Session("test123")
|
|
55
|
+
message = Message("recognizer_loop:utterance",
|
|
56
|
+
{"utterances": ["hello world"]},
|
|
57
|
+
{"session": session.serialize(), "source": "A", "destination": "B"})
|
|
58
|
+
|
|
59
|
+
test = End2EndTest(
|
|
60
|
+
skill_ids=[],
|
|
61
|
+
source_message=message,
|
|
62
|
+
expected_messages=[
|
|
63
|
+
Message("recognizer_loop:utterance", {"utterances": ["hello world"]}, {"session": session.serialize()}),
|
|
64
|
+
Message("complete_intent_failure", {}, {"session": session.serialize()}),
|
|
65
|
+
Message("ovos.utterance.handled", {}, {"session": session.serialize()}),
|
|
66
|
+
]
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
test.execute()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Why OvoScope?
|
|
75
|
+
|
|
76
|
+
* Lightweight: No need to launch a full messagebus or audio stack
|
|
77
|
+
* Isolated: Use `FakeBus` and `MiniCroft` for fast, reliable test environments
|
|
78
|
+
* Flexible: Works with any skill that conforms to OVOS skill loading
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
[Apache 2.0](LICENSE)
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Contributing
|
|
89
|
+
|
|
90
|
+
PRs are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
91
|
+
|
|
92
|
+
|
ovoscope-0.0.1/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# OvoScope
|
|
2
|
+
|
|
3
|
+
**OvoScope** is an end-to-end testing framework for [OVOS](https://openvoiceos.org) skills.
|
|
4
|
+
|
|
5
|
+
It contains the full core runtime environment using a lightweight in-process `ovos-core`, allowing skill developers to test the full skill message flow, from utterance to intent handling to final bus responses — without launching a full assistant stack.
|
|
6
|
+
|
|
7
|
+
> Like a microscope for your OVOS skills.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Simulates OVOS Core messagebus interactions
|
|
14
|
+
- Sends test `Message` objects and captures responses
|
|
15
|
+
- Verifies message types, data, routing, session handling, and language
|
|
16
|
+
- Automatically flips message direction when configured
|
|
17
|
+
- Designed to integrate cleanly into `unittest` or `pytest` workflows
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install ovoscope
|
|
25
|
+
````
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Usage Example
|
|
30
|
+
|
|
31
|
+
Testing scenario of complete intent failure (no skills installed)
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from ovoscope import End2EndTest
|
|
35
|
+
from ovos_bus_client.message import Message
|
|
36
|
+
from ovos_bus_client.session import Session
|
|
37
|
+
|
|
38
|
+
session = Session("test123")
|
|
39
|
+
message = Message("recognizer_loop:utterance",
|
|
40
|
+
{"utterances": ["hello world"]},
|
|
41
|
+
{"session": session.serialize(), "source": "A", "destination": "B"})
|
|
42
|
+
|
|
43
|
+
test = End2EndTest(
|
|
44
|
+
skill_ids=[],
|
|
45
|
+
source_message=message,
|
|
46
|
+
expected_messages=[
|
|
47
|
+
Message("recognizer_loop:utterance", {"utterances": ["hello world"]}, {"session": session.serialize()}),
|
|
48
|
+
Message("complete_intent_failure", {}, {"session": session.serialize()}),
|
|
49
|
+
Message("ovos.utterance.handled", {}, {"session": session.serialize()}),
|
|
50
|
+
]
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
test.execute()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Why OvoScope?
|
|
59
|
+
|
|
60
|
+
* Lightweight: No need to launch a full messagebus or audio stack
|
|
61
|
+
* Isolated: Use `FakeBus` and `MiniCroft` for fast, reliable test environments
|
|
62
|
+
* Flexible: Works with any skill that conforms to OVOS skill loading
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
[Apache 2.0](LICENSE)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Contributing
|
|
73
|
+
|
|
74
|
+
PRs are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
75
|
+
|
|
76
|
+
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import threading
|
|
3
|
+
from time import sleep
|
|
4
|
+
from typing import Union, List
|
|
5
|
+
|
|
6
|
+
from ovos_bus_client.message import Message
|
|
7
|
+
from ovos_bus_client.session import SessionManager, Session
|
|
8
|
+
from ovos_bus_client.util.scheduler import EventScheduler
|
|
9
|
+
from ovos_core.intent_services import IntentService
|
|
10
|
+
from ovos_core.skill_manager import SkillManager
|
|
11
|
+
from ovos_plugin_manager.skills import find_skill_plugins
|
|
12
|
+
from ovos_utils.fakebus import FakeBus
|
|
13
|
+
from ovos_utils.log import LOG
|
|
14
|
+
from ovos_utils.process_utils import ProcessState
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class MiniCroft(SkillManager):
|
|
19
|
+
def __init__(self, skill_ids, *args, **kwargs):
|
|
20
|
+
bus = FakeBus()
|
|
21
|
+
super().__init__(bus, *args, **kwargs)
|
|
22
|
+
self.skill_ids = skill_ids
|
|
23
|
+
self.intent_service = IntentService(self.bus)
|
|
24
|
+
self.scheduler = EventScheduler(bus, schedule_file="/tmp/schetest.json")
|
|
25
|
+
|
|
26
|
+
def load_metadata_transformers(self, cfg):
|
|
27
|
+
self.intent_service.metadata_plugins.config = cfg
|
|
28
|
+
self.intent_service.metadata_plugins.load_plugins()
|
|
29
|
+
|
|
30
|
+
def load_plugin_skills(self):
|
|
31
|
+
LOG.info("loading skill plugins")
|
|
32
|
+
plugins = find_skill_plugins()
|
|
33
|
+
for skill_id, plug in plugins.items():
|
|
34
|
+
if skill_id not in self.skill_ids:
|
|
35
|
+
continue
|
|
36
|
+
if skill_id not in self.plugin_skills:
|
|
37
|
+
self._load_plugin_skill(skill_id, plug)
|
|
38
|
+
|
|
39
|
+
def run(self):
|
|
40
|
+
"""Load skills and mark core as ready to start tests"""
|
|
41
|
+
self.status.set_alive()
|
|
42
|
+
self.load_plugin_skills()
|
|
43
|
+
self.status.set_ready()
|
|
44
|
+
LOG.info("Skills all loaded!")
|
|
45
|
+
|
|
46
|
+
def stop(self):
|
|
47
|
+
super().stop()
|
|
48
|
+
self.scheduler.shutdown()
|
|
49
|
+
SessionManager.bus = None
|
|
50
|
+
SessionManager.sessions = {}
|
|
51
|
+
SessionManager.default_session = SessionManager.sessions["default"] = Session("default")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_minicroft(skill_ids: Union[List[str], str]):
|
|
55
|
+
if isinstance(skill_ids, str):
|
|
56
|
+
skill_ids = [skill_ids]
|
|
57
|
+
assert isinstance(skill_ids, list)
|
|
58
|
+
croft1 = MiniCroft(skill_ids)
|
|
59
|
+
croft1.start()
|
|
60
|
+
while croft1.status.state != ProcessState.READY:
|
|
61
|
+
sleep(0.2)
|
|
62
|
+
return croft1
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclasses.dataclass()
|
|
66
|
+
class End2EndTest:
|
|
67
|
+
skill_ids: List[str] # skill_ids to load during the test
|
|
68
|
+
source_message: Message # starts the test
|
|
69
|
+
expected_messages: List[Message] # tests are performed against message list
|
|
70
|
+
|
|
71
|
+
# if received, end message capture
|
|
72
|
+
eof_msgs: List[str] = dataclasses.field(default_factory=lambda: ["ovos.utterance.handled"])
|
|
73
|
+
|
|
74
|
+
# messages after which source and destination flip in the message.context
|
|
75
|
+
flip_points: List[str] = dataclasses.field(default_factory=lambda: ["recognizer_loop:utterance"])
|
|
76
|
+
|
|
77
|
+
# test assertions to run
|
|
78
|
+
test_session_lang: bool = True
|
|
79
|
+
test_session_pipeline: bool = True
|
|
80
|
+
test_msg_type: bool = True
|
|
81
|
+
test_msg_data: bool = True
|
|
82
|
+
test_msg_context: bool = True
|
|
83
|
+
test_routing: bool = True
|
|
84
|
+
|
|
85
|
+
def capture_messages(self, timeout=20) -> List[Message]:
|
|
86
|
+
|
|
87
|
+
test_message = self.source_message
|
|
88
|
+
|
|
89
|
+
responses = []
|
|
90
|
+
done = threading.Event()
|
|
91
|
+
|
|
92
|
+
def handle_message(msg: str):
|
|
93
|
+
nonlocal responses
|
|
94
|
+
if done.is_set():
|
|
95
|
+
return
|
|
96
|
+
msg = Message.deserialize(msg)
|
|
97
|
+
responses.append(msg)
|
|
98
|
+
|
|
99
|
+
def handle_end_of_test(msg: Message):
|
|
100
|
+
done.set()
|
|
101
|
+
|
|
102
|
+
minicroft = get_minicroft(self.skill_ids)
|
|
103
|
+
|
|
104
|
+
minicroft.bus.on("message", handle_message)
|
|
105
|
+
for m in self.eof_msgs:
|
|
106
|
+
minicroft.bus.on(m, handle_end_of_test)
|
|
107
|
+
|
|
108
|
+
minicroft.bus.emit(test_message)
|
|
109
|
+
done.wait(timeout)
|
|
110
|
+
|
|
111
|
+
minicroft.stop()
|
|
112
|
+
|
|
113
|
+
return responses
|
|
114
|
+
|
|
115
|
+
def execute(self, timeout=30):
|
|
116
|
+
e_src = self.source_message.context.get("source")
|
|
117
|
+
e_dst = self.source_message.context.get("destination")
|
|
118
|
+
messages = self.capture_messages(timeout)
|
|
119
|
+
for expected, received in zip(self.expected_messages, messages):
|
|
120
|
+
sess_e = SessionManager.get(expected)
|
|
121
|
+
sess_r = SessionManager.get(received)
|
|
122
|
+
if self.test_msg_type:
|
|
123
|
+
assert expected.msg_type == received.msg_type
|
|
124
|
+
if self.test_msg_data:
|
|
125
|
+
for k, v in expected.data.items():
|
|
126
|
+
assert received.data[k] == v
|
|
127
|
+
if self.test_msg_context:
|
|
128
|
+
for k, v in expected.context.items():
|
|
129
|
+
assert received.context[k] == v
|
|
130
|
+
if self.test_routing:
|
|
131
|
+
r_src = received.context.get("source")
|
|
132
|
+
r_dst = received.context.get("destination")
|
|
133
|
+
assert e_src == r_src
|
|
134
|
+
assert e_dst == r_dst
|
|
135
|
+
if expected.msg_type in self.flip_points:
|
|
136
|
+
e_src, e_dst = e_dst, e_src
|
|
137
|
+
|
|
138
|
+
if self.test_session_lang:
|
|
139
|
+
assert sess_e.lang == sess_r.lang
|
|
140
|
+
if self.test_session_pipeline:
|
|
141
|
+
assert sess_e.pipeline == sess_e.pipeline
|
|
142
|
+
|
|
143
|
+
if __name__ == "__main__":
|
|
144
|
+
LOG.set_level("CRITICAL")
|
|
145
|
+
|
|
146
|
+
session = Session("123") # change lang, pipeline, whatever as needed
|
|
147
|
+
message = Message("recognizer_loop:utterance",
|
|
148
|
+
{"utterances": ["hello world"]},
|
|
149
|
+
{"session": session.serialize(),
|
|
150
|
+
"source": "A", "destination": "B"})
|
|
151
|
+
|
|
152
|
+
test = End2EndTest(
|
|
153
|
+
skill_ids=["skill-ovos-hello-world.openvoiceos"],
|
|
154
|
+
source_message=message,
|
|
155
|
+
expected_messages=[
|
|
156
|
+
Message("recognizer_loop:utterance",
|
|
157
|
+
{"utterances": ["hello world"]},
|
|
158
|
+
{"session": session.serialize()}),
|
|
159
|
+
Message("mycroft.audio.play_sound",
|
|
160
|
+
{"uri":"snd/error.mp3"},
|
|
161
|
+
{"session": session.serialize()}),
|
|
162
|
+
Message("complete_intent_failure",
|
|
163
|
+
{},
|
|
164
|
+
{"session": session.serialize()}),
|
|
165
|
+
Message("ovos.utterance.handled",
|
|
166
|
+
{},
|
|
167
|
+
{"session": session.serialize()}),
|
|
168
|
+
]
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
test.execute()
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: ovoscope
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: End-to-end test framework for OpenVoiceOS skills
|
|
5
|
+
Home-page: https://github.com/TigreGotico/ovoscope
|
|
6
|
+
Author: JarbasAI
|
|
7
|
+
Author-email: jarbasai@mailfence.com
|
|
8
|
+
License: Apache-2.0
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Topic :: Software Development :: Testing
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# OvoScope
|
|
18
|
+
|
|
19
|
+
**OvoScope** is an end-to-end testing framework for [OVOS](https://openvoiceos.org) skills.
|
|
20
|
+
|
|
21
|
+
It contains the full core runtime environment using a lightweight in-process `ovos-core`, allowing skill developers to test the full skill message flow, from utterance to intent handling to final bus responses — without launching a full assistant stack.
|
|
22
|
+
|
|
23
|
+
> Like a microscope for your OVOS skills.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- Simulates OVOS Core messagebus interactions
|
|
30
|
+
- Sends test `Message` objects and captures responses
|
|
31
|
+
- Verifies message types, data, routing, session handling, and language
|
|
32
|
+
- Automatically flips message direction when configured
|
|
33
|
+
- Designed to integrate cleanly into `unittest` or `pytest` workflows
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install ovoscope
|
|
41
|
+
````
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Usage Example
|
|
46
|
+
|
|
47
|
+
Testing scenario of complete intent failure (no skills installed)
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from ovoscope import End2EndTest
|
|
51
|
+
from ovos_bus_client.message import Message
|
|
52
|
+
from ovos_bus_client.session import Session
|
|
53
|
+
|
|
54
|
+
session = Session("test123")
|
|
55
|
+
message = Message("recognizer_loop:utterance",
|
|
56
|
+
{"utterances": ["hello world"]},
|
|
57
|
+
{"session": session.serialize(), "source": "A", "destination": "B"})
|
|
58
|
+
|
|
59
|
+
test = End2EndTest(
|
|
60
|
+
skill_ids=[],
|
|
61
|
+
source_message=message,
|
|
62
|
+
expected_messages=[
|
|
63
|
+
Message("recognizer_loop:utterance", {"utterances": ["hello world"]}, {"session": session.serialize()}),
|
|
64
|
+
Message("complete_intent_failure", {}, {"session": session.serialize()}),
|
|
65
|
+
Message("ovos.utterance.handled", {}, {"session": session.serialize()}),
|
|
66
|
+
]
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
test.execute()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Why OvoScope?
|
|
75
|
+
|
|
76
|
+
* Lightweight: No need to launch a full messagebus or audio stack
|
|
77
|
+
* Isolated: Use `FakeBus` and `MiniCroft` for fast, reliable test environments
|
|
78
|
+
* Flexible: Works with any skill that conforms to OVOS skill loading
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
[Apache 2.0](LICENSE)
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Contributing
|
|
89
|
+
|
|
90
|
+
PRs are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
91
|
+
|
|
92
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
ovoscope/__init__.py
|
|
4
|
+
ovoscope/version.py
|
|
5
|
+
ovoscope.egg-info/PKG-INFO
|
|
6
|
+
ovoscope.egg-info/SOURCES.txt
|
|
7
|
+
ovoscope.egg-info/dependency_links.txt
|
|
8
|
+
ovoscope.egg-info/not-zip-safe
|
|
9
|
+
ovoscope.egg-info/requires.txt
|
|
10
|
+
ovoscope.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ovos-core>=1.1.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ovoscope
|
ovoscope-0.0.1/setup.cfg
ADDED
ovoscope-0.0.1/setup.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
BASEDIR = os.path.abspath(os.path.dirname(__file__))
|
|
5
|
+
|
|
6
|
+
def get_version():
|
|
7
|
+
""" Find the version of the package"""
|
|
8
|
+
version_file = os.path.join(BASEDIR, 'ovoscope', 'version.py')
|
|
9
|
+
major, minor, build, alpha = (None, None, None, None)
|
|
10
|
+
with open(version_file) as f:
|
|
11
|
+
for line in f:
|
|
12
|
+
if 'VERSION_MAJOR' in line:
|
|
13
|
+
major = line.split('=')[1].strip()
|
|
14
|
+
elif 'VERSION_MINOR' in line:
|
|
15
|
+
minor = line.split('=')[1].strip()
|
|
16
|
+
elif 'VERSION_BUILD' in line:
|
|
17
|
+
build = line.split('=')[1].strip()
|
|
18
|
+
elif 'VERSION_ALPHA' in line:
|
|
19
|
+
alpha = line.split('=')[1].strip()
|
|
20
|
+
|
|
21
|
+
if ((major and minor and build and alpha) or
|
|
22
|
+
'# END_VERSION_BLOCK' in line):
|
|
23
|
+
break
|
|
24
|
+
version = f"{major}.{minor}.{build}"
|
|
25
|
+
if alpha and int(alpha) > 0:
|
|
26
|
+
version += f"a{alpha}"
|
|
27
|
+
return version
|
|
28
|
+
|
|
29
|
+
setup(
|
|
30
|
+
name="ovoscope",
|
|
31
|
+
version=get_version(),
|
|
32
|
+
description="End-to-end test framework for OpenVoiceOS skills",
|
|
33
|
+
long_description=open(f"{BASEDIR}/README.md").read(),
|
|
34
|
+
long_description_content_type="text/markdown",
|
|
35
|
+
author="JarbasAI",
|
|
36
|
+
author_email="jarbasai@mailfence.com",
|
|
37
|
+
url="https://github.com/TigreGotico/ovoscope",
|
|
38
|
+
license="Apache-2.0",
|
|
39
|
+
packages=find_packages(),
|
|
40
|
+
install_requires=[
|
|
41
|
+
"ovos-core>=1.1.0"
|
|
42
|
+
],
|
|
43
|
+
python_requires='>=3.10',
|
|
44
|
+
classifiers=[
|
|
45
|
+
"Programming Language :: Python :: 3",
|
|
46
|
+
"License :: OSI Approved :: Apache Software License",
|
|
47
|
+
"Operating System :: OS Independent",
|
|
48
|
+
"Intended Audience :: Developers",
|
|
49
|
+
"Topic :: Software Development :: Testing",
|
|
50
|
+
],
|
|
51
|
+
include_package_data=True,
|
|
52
|
+
zip_safe=False,
|
|
53
|
+
)
|