Skip to content

Commit c0e7fbd

Browse files
committed
Preparing for first robotframework-output-stream release.
1 parent 007019c commit c0e7fbd

7 files changed

Lines changed: 337 additions & 106 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
on:
2+
push:
3+
branches:
4+
- "release-robotframework-output-stream"
5+
tags:
6+
- "robotframework-output-stream-*"
7+
name: Deploy - RobotFramework Output Stream
8+
jobs:
9+
deploy:
10+
runs-on: ubuntu-latest
11+
defaults:
12+
run:
13+
working-directory: ./robotframework-output-stream
14+
15+
strategy:
16+
fail-fast: true
17+
18+
steps:
19+
- name: Checkout repository and submodules
20+
uses: actions/checkout@v1
21+
with:
22+
submodules: recursive
23+
24+
- name: Set up Python 3.7
25+
uses: actions/setup-python@v1
26+
with:
27+
python-version: 3.7
28+
29+
# Build Python version
30+
- name: Install deps
31+
run: pip install --upgrade pip fire twine wheel setuptools
32+
33+
- name: Build wheel
34+
working-directory: ./robotframework-output-stream/src
35+
run: |
36+
cp ../README.md ./README.md
37+
python setup.py sdist bdist_wheel --universal
38+
39+
- name: Check tag version
40+
run: python -m dev check-tag-version
41+
42+
- name: Upload to PyPI
43+
working-directory: ./robotframework-output-stream/src
44+
run: twine upload dist/*
45+
env:
46+
TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
47+
TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}

robotframework-ls/dev.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def get_tag(self):
9191
import subprocess
9292

9393
# i.e.: Gets the last tagged version
94-
cmd = "git describe --tags --abbrev=0 --match robotframework*".split()
94+
cmd = "git describe --tags --abbrev=0 --match robotframework-lsp*".split()
9595
popen = subprocess.Popen(cmd, stdout=subprocess.PIPE)
9696
stdout, stderr = popen.communicate()
9797

robotframework-output-stream/README.md

Lines changed: 105 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -61,39 +61,18 @@ The requirements for the generated log files are the following:
6161

6262
## Outputs
6363

64-
Given the requisites above, the idea is generating the following files while running:
64+
The basic log can actually be splitted to multiple files.
65+
Such files are splitted in the following files (the idea
66+
is that it can be split when it becomes too big).
6567

66-
1. `Basic log`
67-
68-
The basic log can actually be splitted to multiple files.
69-
Such files are splitted in the following files (the idea
70-
is that it can be split when it becomes too big).
71-
72-
- `output.0.rfstream`
73-
- `output.1.rfstream`
74-
- `output.2.rfstream`
75-
- ...
76-
77-
The file should be always written and flushed at each log entry and
78-
it should be consistent even if the process crashes in the meanwhile
79-
(meaning that all entries written are valid up to the point of the crash).
80-
81-
2. `Errors log`
82-
83-
Files in the same format pointing to where an error happened (it should
84-
be possible to derive a traceback from that information).
85-
86-
- `robot_out_stream.error.0.rfstream`
87-
- `robot_out_stream.error.1.rfstream`
88-
89-
After the processing finished a file is written with all the errors.
90-
91-
- `robot_out_stream.errors.summary.rfstream`
92-
93-
Note: for most users just the errors log should be enough, but if something
94-
isn't identified as an error, the "Basic log" should provide insight on
95-
what actually happened during the full run.
68+
- `output_0.rfstream`
69+
- `output_1.rfstream`
70+
- `output_2.rfstream`
71+
- ...
9672

73+
The file should be always written and flushed at each log entry and
74+
it should be consistent even if the process crashes in the meanwhile
75+
(meaning that all entries written are valid up to the point of the crash).
9776

9877
## "Basic log" spec
9978

@@ -126,34 +105,121 @@ Basic message types are:
126105
I "python=3.7"
127106
I "RF=5.7.0"
128107

129-
### M: Memorize name(id, json_string)
108+
### M: Memorize name(id ':' json_string)
130109

131110
Example:
132111

133112
M SS:"Start Suite" - Identifies the String 'Start Suite' as 'SS' in the logs
134113
M ES:"End Suite" - Identifies the String 'End Suite' as 'ES' in the logs
135-
114+
136115
### T: Initial time(isoformat)
137116

138117
Example:
139118

140119
T 2022-10-03T11:30:54.927
141120

142-
### SS: Start Suite(name_id, suite_id_id, suite_source_id, time_delta_in_seconds)
121+
### SS: Start Suite
143122

144-
Example:
123+
Spec: `name:oid, suite_id:oid, suite_source:oid, time_delta_in_seconds:float`
145124

146-
M 1:"My Suite"
147-
M 2:"my_suite"
148-
M 3:"c:/temp/foo/bar/my_suite.robot"
149-
SS 1|2|3|0.553
125+
Note: references to oid mean a reference to a previously memorized name.
126+
127+
Note: the time may be given as -1 (if unknown -- later it may be provided
128+
through an "S" message to specify the start time which may be useful
129+
when converting to xml where the status only appears later on in the file
130+
along with the status and not at the suite definition).
131+
132+
Example (were a, b and c are references to previously memorized names):
133+
134+
SS a|b|c|0.333
150135

151136
### ES: End Suite
152137

138+
Spec: `status:oid, time_delta_in_seconds:float`
139+
140+
Note: the status (PASS, FAIL, SKIP) is a previously memorized name.
141+
142+
Example:
143+
144+
ES a|0.222
145+
153146
### ST: Start Task/test
154147

148+
Spec: `name:oid, suite_id:oid, lineno:int, time_delta_in_seconds:float`
149+
150+
Note: the source (filename) is available through the parent suite_source.
151+
152+
Example:
153+
154+
ST a|b|22|0.332
155+
155156
### ET: End Task/Test
156157

158+
Spec: `status:oid, message:oid, time_delta_in_seconds:float`
159+
160+
Example:
161+
162+
ET a|b|0.332
163+
157164
### SK: Start Keyword
158165

166+
Spec: `name:oid, libname:oid, keyword_type:oid, doc:oid, source:oid, lineno:int, time_delta_in_seconds:float`
167+
168+
Example:
169+
170+
SK a|b|c|d|e|22|0.444
171+
172+
### KA: Keyword argument
173+
174+
Spec: `argument:oid`
175+
176+
Example:
177+
178+
KA f
179+
180+
### AS: Assign keyword call result to a variable
181+
182+
Spec: `assign:oid`
183+
184+
Example:
185+
186+
AS f
187+
159188
### EK: End Keyword
189+
190+
Spec: `status:oid, time_delta_in_seconds:float`
191+
192+
Example:
193+
194+
EK a|0.333
195+
196+
### L: Provide a log message
197+
198+
Spec: `level:level_enum, message:oid, time_delta_in_seconds:float`
199+
200+
level_enum is:
201+
# ERROR = E
202+
# FAIL = F
203+
# INFO = I
204+
# WARN = W
205+
206+
Example:
207+
208+
L E|a|0.123
209+
210+
### S: Specify the start time (of the containing suite/test/task/keyword)
211+
212+
Spec: `start_time_delta:float`
213+
214+
Example:
215+
216+
S 2.456
217+
218+
### TG: Apply tag
219+
220+
Spec: `tag:oid`
221+
222+
Example:
223+
224+
TG a
225+
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
"""
2+
This is a script to help with the automation of common development tasks.
3+
4+
It requires 'fire' to be installed for the command line automation (i.e.: pip install fire).
5+
6+
Some example commands:
7+
8+
python -m dev set-version 0.0.2
9+
python -m dev check-tag-version
10+
"""
11+
import sys
12+
import os
13+
import traceback
14+
15+
__file__ = os.path.abspath(__file__)
16+
17+
if not os.path.exists(os.path.join(os.path.abspath("."), "dev.py")):
18+
raise RuntimeError('Please execute commands from the directory containing "dev.py"')
19+
20+
import fire
21+
22+
23+
def _fix_contents_version(contents, version):
24+
import re
25+
26+
contents = re.sub(
27+
r"(version\s*=\s*)\"\d+\.\d+\.\d+", r'\1"%s' % (version,), contents
28+
)
29+
contents = re.sub(
30+
r"(__version__\s*=\s*)\"\d+\.\d+\.\d+", r'\1"%s' % (version,), contents
31+
)
32+
contents = re.sub(
33+
r"(\"version\"\s*:\s*)\"\d+\.\d+\.\d+", r'\1"%s' % (version,), contents
34+
)
35+
contents = re.sub(
36+
r"(blob/robotframework-lsp)-\d+\.\d+\.\d+", r"\1-%s" % (version,), contents
37+
)
38+
39+
return contents
40+
41+
42+
class Dev(object):
43+
def set_version(self, version):
44+
"""
45+
Sets a new version for robotframework-output-stream in all the needed files.
46+
"""
47+
48+
def update_version(version, filepath, fix_func=_fix_contents_version):
49+
with open(filepath, "r") as stream:
50+
contents = stream.read()
51+
52+
new_contents = fix_func(contents, version)
53+
if contents != new_contents:
54+
print("Changed: ", filepath)
55+
with open(filepath, "w") as stream:
56+
stream.write(new_contents)
57+
58+
update_version(version, os.path.join(".", "src", "setup.py"))
59+
update_version(
60+
version, os.path.join(".", "src", "robot_out_stream", "__init__.py")
61+
)
62+
63+
def get_tag(self):
64+
import subprocess
65+
66+
# i.e.: Gets the last tagged version
67+
cmd = "git describe --tags --abbrev=0 --match robotframework-output-stream*".split()
68+
popen = subprocess.Popen(cmd, stdout=subprocess.PIPE)
69+
stdout, stderr = popen.communicate()
70+
71+
# Something as: b'robotframework-output-stream-0.0.1'
72+
if sys.version_info[0] >= 3:
73+
stdout = stdout.decode("utf-8")
74+
stdout = stdout.strip()
75+
return stdout
76+
77+
def check_tag_version(self):
78+
"""
79+
Checks if the current tag matches the latest version (exits with 1 if it
80+
does not match and with 0 if it does match).
81+
"""
82+
tag = self.get_tag()
83+
version = tag[tag.rfind("-") + 1 :]
84+
85+
if robotframework_ls.__version__ == version:
86+
sys.stderr.write("Version matches (%s) (exit(0))\n" % (version,))
87+
sys.exit(0)
88+
else:
89+
sys.stderr.write(
90+
"Version does not match (lsp: %s != tag: %s) (exit(1))\n"
91+
% (robotframework_ls.__version__, version)
92+
)
93+
sys.exit(1)
94+
95+
96+
def test_lines():
97+
"""
98+
Check that the replace matches what we expect.
99+
100+
Things we must match:
101+
102+
version="0.0.1"
103+
"version": "0.0.1",
104+
__version__ = "0.0.1"
105+
https://github.com/robocorp/robotframework-lsp/blob/robotframework-lsp-0.1.1/robotframework-ls/README.md
106+
"""
107+
from robocorp_ls_core.unittest_tools.compare import compare_lines
108+
109+
contents = _fix_contents_version(
110+
"""
111+
version="0.0.198"
112+
version = "0.0.1"
113+
"version": "0.0.1",
114+
"version":"0.0.1",
115+
"version" :"0.0.1",
116+
__version__ = "0.0.1"
117+
https://github.com/robocorp/robotframework-lsp/blob/robotframework-lsp-0.1.1/robotframework-ls/README.md
118+
""",
119+
"3.7.1",
120+
)
121+
122+
expected = """
123+
version="3.7.1"
124+
version = "3.7.1"
125+
"version": "3.7.1",
126+
"version":"3.7.1",
127+
"version" :"3.7.1",
128+
__version__ = "3.7.1"
129+
https://github.com/robocorp/robotframework-lsp/blob/robotframework-lsp-3.7.1/robotframework-ls/README.md
130+
"""
131+
132+
compare_lines(contents.splitlines(), expected.splitlines())
133+
134+
135+
if __name__ == "__main__":
136+
TEST = False
137+
if TEST:
138+
test_lines()
139+
else:
140+
# Workaround so that fire always prints the output.
141+
# See: https://github.com/google/python-fire/issues/188
142+
def Display(lines, out):
143+
text = "\n".join(lines) + "\n"
144+
out.write(text)
145+
146+
from fire import core
147+
148+
core.Display = Display
149+
150+
fire.Fire(Dev())

robotframework-output-stream/src/robot_out_stream/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
from typing import Optional, Any
44
import sys
55

6+
__version__ = "0.0.1"
7+
version_info = [int(x) for x in __version__.split(".")]
8+
69

710
_convert = {
811
"gb": lambda s: s * 1e9,

0 commit comments

Comments
 (0)