synapse 2.224.0__py311-none-any.whl → 2.225.0__py311-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.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/axon.py +10 -5
- synapse/lib/cell.py +1 -1
- synapse/lib/const.py +4 -0
- synapse/lib/multislabseqn.py +36 -1
- synapse/lib/nexus.py +67 -8
- synapse/lib/queue.py +4 -1
- synapse/lib/rstorm.py +2 -2
- synapse/lib/schemas.py +11 -1
- synapse/lib/slabseqn.py +28 -0
- synapse/lib/storm.py +5 -1
- synapse/lib/stormhttp.py +7 -1
- synapse/lib/version.py +2 -2
- synapse/models/inet.py +4 -0
- synapse/models/media.py +4 -0
- synapse/models/risk.py +3 -0
- synapse/tests/test_cortex.py +2 -2
- synapse/tests/test_lib_agenda.py +1 -1
- synapse/tests/test_lib_cell.py +1 -1
- synapse/tests/test_lib_certdir.py +1 -1
- synapse/tests/test_lib_httpapi.py +1 -1
- synapse/tests/test_lib_layer.py +1 -1
- synapse/tests/test_lib_multislabseqn.py +22 -0
- synapse/tests/test_lib_nexus.py +42 -1
- synapse/tests/test_lib_slabseqn.py +30 -1
- synapse/tests/test_lib_storm.py +59 -1
- synapse/tests/test_lib_stormhttp.py +16 -0
- synapse/tests/test_lib_stormlib_oauth.py +1 -1
- synapse/tests/test_lib_stormsvc.py +1 -1
- synapse/tests/test_lib_trigger.py +1 -1
- synapse/tests/test_model_inet.py +6 -0
- synapse/tests/test_model_media.py +4 -1
- synapse/tests/test_model_risk.py +2 -0
- synapse/tests/{test_tools_axon2axon.py → test_tools_axon_copy.py} +4 -4
- synapse/tests/{test_tools_pullfile.py → test_tools_axon_get.py} +4 -4
- synapse/tests/{test_tools_pushfile.py → test_tools_axon_put.py} +7 -7
- synapse/tests/{test_tools_csvtool.py → test_tools_cortex_csv.py} +12 -3
- synapse/tests/{test_tools_feed.py → test_tools_cortex_feed.py} +2 -2
- synapse/tests/{test_tools_apikey.py → test_tools_service_apikey.py} +1 -4
- synapse/tests/{test_tools_backup.py → test_tools_service_backup.py} +5 -5
- synapse/tests/{test_tools_demote.py → test_tools_service_demote.py} +1 -1
- synapse/tests/{test_tools_healthcheck.py → test_tools_service_healthcheck.py} +1 -1
- synapse/tests/{test_tools_livebackup.py → test_tools_service_livebackup.py} +1 -1
- synapse/tests/{test_tools_modrole.py → test_tools_service_modrole.py} +1 -1
- synapse/tests/{test_tools_moduser.py → test_tools_service_moduser.py} +1 -1
- synapse/tests/{test_tools_promote.py → test_tools_service_promote.py} +1 -1
- synapse/tests/{test_tools_reload.py → test_tools_service_reload.py} +1 -1
- synapse/tests/{test_tools_shutdown.py → test_tools_service_shutdown.py} +1 -1
- synapse/tests/{test_tools_snapshot.py → test_tools_service_snapshot.py} +1 -1
- synapse/tests/{test_tools_storm.py → test_tools_storm_cli.py} +1 -1
- synapse/tests/{test_tools_pkgs_gendocs.py → test_tools_storm_pkg_doc.py} +12 -3
- synapse/tests/{test_tools_genpkg.py → test_tools_storm_pkg_gen.py} +1 -1
- synapse/tests/{test_tools_autodoc.py → test_tools_utils_autodoc.py} +1 -1
- synapse/tests/test_tools_utils_changelog.py +454 -0
- synapse/tests/{test_tools_easycert.py → test_tools_utils_easycert.py} +48 -46
- synapse/tests/{test_tools_guid.py → test_tools_utils_guid.py} +3 -3
- synapse/tests/{test_tools_json2mpk.py → test_tools_utils_json2mpk.py} +3 -3
- synapse/tests/{test_tools_rstorm.py → test_tools_utils_rstorm.py} +6 -1
- synapse/tests/utils.py +3 -1
- synapse/tools/apikey.py +4 -83
- synapse/tools/autodoc.py +3 -1031
- synapse/tools/axon/copy.py +44 -0
- synapse/tools/axon/get.py +64 -0
- synapse/tools/axon/put.py +122 -0
- synapse/tools/axon2axon.py +3 -36
- synapse/tools/backup.py +6 -176
- synapse/tools/changelog.py +3 -1098
- synapse/tools/cortex/csv.py +236 -0
- synapse/tools/cortex/feed.py +151 -0
- synapse/tools/csvtool.py +3 -227
- synapse/tools/demote.py +4 -40
- synapse/tools/docker/validate.py +3 -3
- synapse/tools/easycert.py +4 -129
- synapse/tools/feed.py +3 -140
- synapse/tools/genpkg.py +3 -307
- synapse/tools/guid.py +7 -6
- synapse/tools/healthcheck.py +3 -101
- synapse/tools/json2mpk.py +6 -38
- synapse/tools/livebackup.py +4 -27
- synapse/tools/modrole.py +3 -108
- synapse/tools/moduser.py +3 -179
- synapse/tools/pkgs/gendocs.py +3 -164
- synapse/tools/promote.py +4 -41
- synapse/tools/pullfile.py +3 -56
- synapse/tools/pushfile.py +3 -114
- synapse/tools/reload.py +4 -61
- synapse/tools/rstorm.py +3 -26
- synapse/tools/service/__init__.py +0 -0
- synapse/tools/service/apikey.py +90 -0
- synapse/tools/service/backup.py +181 -0
- synapse/tools/service/demote.py +47 -0
- synapse/tools/service/healthcheck.py +109 -0
- synapse/tools/service/livebackup.py +34 -0
- synapse/tools/service/modrole.py +116 -0
- synapse/tools/service/moduser.py +184 -0
- synapse/tools/service/promote.py +48 -0
- synapse/tools/service/reload.py +68 -0
- synapse/tools/service/shutdown.py +51 -0
- synapse/tools/service/snapshot.py +64 -0
- synapse/tools/shutdown.py +5 -45
- synapse/tools/snapshot.py +4 -57
- synapse/tools/storm/__init__.py +0 -0
- synapse/tools/storm/__main__.py +5 -0
- synapse/tools/{storm.py → storm/_cli.py} +0 -3
- synapse/tools/storm/pkg/__init__.py +0 -0
- synapse/tools/{pkgs/pandoc_filter.py → storm/pkg/_pandoc_filter.py} +1 -1
- synapse/tools/storm/pkg/doc.py +176 -0
- synapse/tools/storm/pkg/gen.py +315 -0
- synapse/tools/utils/__init__.py +0 -0
- synapse/tools/utils/autodoc.py +1040 -0
- synapse/tools/utils/changelog.py +1124 -0
- synapse/tools/utils/easycert.py +136 -0
- synapse/tools/utils/guid.py +11 -0
- synapse/tools/utils/json2mpk.py +46 -0
- synapse/tools/utils/rstorm.py +35 -0
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/METADATA +1 -1
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/RECORD +120 -91
- synapse/tests/test_tools_changelog.py +0 -196
- /synapse/tests/{test_tools_axon.py → test_tools_axon_dump_load.py} +0 -0
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/WHEEL +0 -0
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import gzip
|
|
3
|
+
|
|
4
|
+
import synapse.common as s_common
|
|
5
|
+
|
|
6
|
+
import synapse.tests.utils as s_test_utils
|
|
7
|
+
|
|
8
|
+
import synapse.tools.utils.changelog as s_t_changelog
|
|
9
|
+
|
|
10
|
+
multiline_feature = '''---
|
|
11
|
+
desc: |
|
|
12
|
+
- This is a pre-formatted RST block as YAML literal scalar.
|
|
13
|
+
|
|
14
|
+
It has stuff in it already formatted all nice like.
|
|
15
|
+
|
|
16
|
+
+-------------------+---------------------------+
|
|
17
|
+
| Beep | Boop |
|
|
18
|
+
+===================+===========================+
|
|
19
|
+
| hahaha | lasers |
|
|
20
|
+
+-------------------+---------------------------+
|
|
21
|
+
| wowow | stufff |
|
|
22
|
+
+-------------------+---------------------------+
|
|
23
|
+
|
|
24
|
+
These are more lines. They can have things like RST string literals in
|
|
25
|
+
them ``like this``. You can even do a literal block!
|
|
26
|
+
|
|
27
|
+
::
|
|
28
|
+
|
|
29
|
+
wow
|
|
30
|
+
|
|
31
|
+
So this is a example.
|
|
32
|
+
desc:literal: true
|
|
33
|
+
prs: []
|
|
34
|
+
type: feat
|
|
35
|
+
...
|
|
36
|
+
'''
|
|
37
|
+
|
|
38
|
+
changelog_format_output = '''CHANGELOG ENTRY:
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
v0.1.22 - 2025-10-03
|
|
42
|
+
====================
|
|
43
|
+
|
|
44
|
+
Automatic Migrations
|
|
45
|
+
--------------------
|
|
46
|
+
- Migrated the widget storage to use acme lasers.
|
|
47
|
+
- See :ref:`datamigration` for more information about automatic migrations.
|
|
48
|
+
|
|
49
|
+
Model Changes
|
|
50
|
+
-------------
|
|
51
|
+
- Added lasers to the sci model.
|
|
52
|
+
|
|
53
|
+
Features and Enhancements
|
|
54
|
+
-------------------------
|
|
55
|
+
- This is a pre-formatted RST block as YAML literal scalar.
|
|
56
|
+
|
|
57
|
+
It has stuff in it already formatted all nice like.
|
|
58
|
+
|
|
59
|
+
+-------------------+---------------------------+
|
|
60
|
+
| Beep | Boop |
|
|
61
|
+
+===================+===========================+
|
|
62
|
+
| hahaha | lasers |
|
|
63
|
+
+-------------------+---------------------------+
|
|
64
|
+
| wowow | stufff |
|
|
65
|
+
+-------------------+---------------------------+
|
|
66
|
+
|
|
67
|
+
These are more lines. They can have things like RST string literals in
|
|
68
|
+
them ``like this``. You can even do a literal block!
|
|
69
|
+
|
|
70
|
+
::
|
|
71
|
+
|
|
72
|
+
wow
|
|
73
|
+
|
|
74
|
+
So this is a example.
|
|
75
|
+
- I am a earlier feature.
|
|
76
|
+
(`#1230 <https://github.com/vertexproject/synapse/pull/1230>`_)
|
|
77
|
+
- I am a feature.
|
|
78
|
+
(`#1234 <https://github.com/vertexproject/synapse/pull/1234>`_)
|
|
79
|
+
|
|
80
|
+
Bugfixes
|
|
81
|
+
--------
|
|
82
|
+
- I am a bug which has quite a large amount of text in it. The amount of text
|
|
83
|
+
will span across multiple lines after being formatted by the changelog tool.
|
|
84
|
+
|
|
85
|
+
Notes
|
|
86
|
+
-----
|
|
87
|
+
- I am a fancy note.
|
|
88
|
+
|
|
89
|
+
Improved documentation
|
|
90
|
+
----------------------
|
|
91
|
+
- Documented the lasers.
|
|
92
|
+
|
|
93
|
+
Deprecations
|
|
94
|
+
------------
|
|
95
|
+
- For widget maker has been deprecated in favor of the new acme corp laser
|
|
96
|
+
cannons.
|
|
97
|
+
'''
|
|
98
|
+
|
|
99
|
+
class ChangelogToolTest(s_test_utils.SynTest):
|
|
100
|
+
|
|
101
|
+
async def test_changelog_model_diff_class(self):
|
|
102
|
+
outp = self.getTestOutp()
|
|
103
|
+
old_fp = self.getTestFilePath('changelog', 'model_2.176.0_16ee721a6b7221344eaf946c3ab4602dda546b1a.yaml.gz')
|
|
104
|
+
new_fp = self.getTestFilePath('changelog', 'model_2.176.0_2a25c58bbd344716cd7cbc3f4304d8925b0f4ef2.yaml.gz')
|
|
105
|
+
oldmodel = s_t_changelog._getModelFile(old_fp)
|
|
106
|
+
newmodel = s_t_changelog._getModelFile(new_fp)
|
|
107
|
+
|
|
108
|
+
differ = s_t_changelog.ModelDiffer(newmodel.get('model'), oldmodel.get('model'))
|
|
109
|
+
|
|
110
|
+
self.eq(differ.cur_type2iface['it:host'], ['inet:service:object', 'inet:service:base'])
|
|
111
|
+
self.eq(differ.cur_type2iface['mat:type'], ['meta:taxonomy'])
|
|
112
|
+
self.eq(differ.cur_iface_to_allifaces['it:host:activity'], ['it:host:activity'])
|
|
113
|
+
self.eq(differ.cur_iface_to_allifaces['file:mime:msoffice'], ['file:mime:msoffice', 'file:mime:meta'])
|
|
114
|
+
changes = differ.diffModl(outp)
|
|
115
|
+
|
|
116
|
+
self.len(4, changes.get('edges').get('new_edges'))
|
|
117
|
+
|
|
118
|
+
form_chng = changes.get('forms')
|
|
119
|
+
self.isin('it:beeper:thingy', form_chng.get('new_forms'))
|
|
120
|
+
self.notin('it:beeper:name', form_chng.get('new_forms'))
|
|
121
|
+
updt_frms = form_chng.get('updated_forms')
|
|
122
|
+
self.isin('new_properties', updt_frms.get('file:mime:pe:resource'))
|
|
123
|
+
self.isin('new_properties_no_interfaces', updt_frms.get('file:mime:pe:resource'))
|
|
124
|
+
self.isin('new_properties', updt_frms.get('inet:http:request'))
|
|
125
|
+
self.notin('new_properties_no_interfaces', updt_frms.get('inet:http:request'))
|
|
126
|
+
self.isin('updated_properties', updt_frms.get('file:mime:macho:section'))
|
|
127
|
+
self.isin('deprecated_properties', updt_frms.get('file:mime:lnk'))
|
|
128
|
+
self.isin('deprecated_properties_no_interfaces', updt_frms.get('file:mime:lnk'))
|
|
129
|
+
self.isin('deprecated_properties', updt_frms.get('inet:http:request'))
|
|
130
|
+
self.notin('deprecated_properties_no_interfaces', updt_frms.get('inet:http:request'))
|
|
131
|
+
self.isin('new_properties', updt_frms.get('file:mime:lnk'))
|
|
132
|
+
self.isin('new_properties_no_interfaces', updt_frms.get('file:mime:lnk'))
|
|
133
|
+
self.isin('updated_properties', updt_frms.get('file:mime:lnk'))
|
|
134
|
+
self.isin('updated_properties_no_interfaces', updt_frms.get('file:mime:lnk'))
|
|
135
|
+
self.isin('updated_properties', updt_frms.get('inet:service:access'))
|
|
136
|
+
self.notin('updated_properties_no_interfaces', updt_frms.get('inet:service:access'))
|
|
137
|
+
|
|
138
|
+
self.isin('it:host:beeper', changes.get('interfaces').get('new_interfaces'))
|
|
139
|
+
updt_iface = changes.get('interfaces').get('updated_interfaces')
|
|
140
|
+
self.isin('deprecated_properties', updt_iface.get('it:host:activity'))
|
|
141
|
+
self.isin('new_properties', updt_iface.get('it:host:activity'))
|
|
142
|
+
self.isin('updated_properties', updt_iface.get('inet:service:base'))
|
|
143
|
+
|
|
144
|
+
self.eq(changes.get('tagprops'), {})
|
|
145
|
+
|
|
146
|
+
self.isin('it:reveng:function', changes.get('types').get('deprecated_types'))
|
|
147
|
+
self.isin('inet:port', changes.get('types').get('deprecated_types'))
|
|
148
|
+
self.isin('it:beeper:thingy', changes.get('types').get('new_types'))
|
|
149
|
+
self.isin('it:beeper:name', changes.get('types').get('new_types'))
|
|
150
|
+
uptd_types = changes.get('types').get('updated_types')
|
|
151
|
+
self.isin('updated_opts', uptd_types.get('it:query'))
|
|
152
|
+
self.isin('updated_interfaces', uptd_types.get('it:reveng:impfunc'))
|
|
153
|
+
|
|
154
|
+
rst = s_t_changelog._gen_model_rst('v2.177.0', 'userguide_model_v2_177_0',
|
|
155
|
+
changes, newmodel.get('model'), outp)
|
|
156
|
+
text = rst.getRstText()
|
|
157
|
+
self.isin('v2.177.0 Model Updates', text)
|
|
158
|
+
self.isin('''**************
|
|
159
|
+
New Interfaces
|
|
160
|
+
**************
|
|
161
|
+
|
|
162
|
+
``it:host:beeper``
|
|
163
|
+
Properties common to instances of beepers.''', text)
|
|
164
|
+
self.isin('''*********
|
|
165
|
+
New Types
|
|
166
|
+
*********
|
|
167
|
+
|
|
168
|
+
``it:beeper:name``
|
|
169
|
+
The friendly name of a beeper.
|
|
170
|
+
''', text)
|
|
171
|
+
self.isin('''*********
|
|
172
|
+
New Forms
|
|
173
|
+
*********
|
|
174
|
+
|
|
175
|
+
``it:beeper:thingy``
|
|
176
|
+
A beeper thingy.
|
|
177
|
+
''', text)
|
|
178
|
+
self.isin('''**************
|
|
179
|
+
New Properties
|
|
180
|
+
**************
|
|
181
|
+
|
|
182
|
+
``file:mime:lnk``
|
|
183
|
+
The form had the following properties added to it:
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
``driveserial``
|
|
187
|
+
The drive serial number of the volume the link target is stored on.
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
``iconindex``
|
|
191
|
+
A resource index for an icon within an icon location.
|
|
192
|
+
''', text)
|
|
193
|
+
self.isin('''``inet:http:request``
|
|
194
|
+
The form had the following property added to it:
|
|
195
|
+
|
|
196
|
+
``beep``
|
|
197
|
+
The time that the host went beep.
|
|
198
|
+
''', text)
|
|
199
|
+
# Some updates will require manual intervention to rewrite.
|
|
200
|
+
self.isin('''******************
|
|
201
|
+
Updated Interfaces
|
|
202
|
+
******************
|
|
203
|
+
|
|
204
|
+
``inet:service:base``
|
|
205
|
+
The property ``id`` has been modified from ['str', {'strip': True}] to ['str',
|
|
206
|
+
{'lower': True, 'strip': True}].
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
``it:host:activity``
|
|
210
|
+
The interface property ``time`` has been deprecated.
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
The property ``beep`` has been added to the interface.
|
|
214
|
+
''', text)
|
|
215
|
+
self.isin('''*************
|
|
216
|
+
Updated Types
|
|
217
|
+
*************
|
|
218
|
+
|
|
219
|
+
``it:query``
|
|
220
|
+
The type has been modified from {'enums': None, 'globsuffix': False, 'lower':
|
|
221
|
+
False, 'onespace': False, 'regex': None, 'replace': [], 'strip': True} to
|
|
222
|
+
{'enums': None, 'globsuffix': False, 'lower': True, 'onespace': False,
|
|
223
|
+
'regex': None, 'replace': [], 'strip': True}.
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
``it:reveng:impfunc``
|
|
227
|
+
The type interface has been modified from None to ['it:host:beeper'].
|
|
228
|
+
''', text)
|
|
229
|
+
self.isin('''******************
|
|
230
|
+
Updated Properties
|
|
231
|
+
******************
|
|
232
|
+
|
|
233
|
+
``file:mime:lnk``
|
|
234
|
+
The form had the following property updated:
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
The property ``entry:icon`` has been modified from ['file:path', {}] to
|
|
238
|
+
['time', {}].
|
|
239
|
+
''', text)
|
|
240
|
+
self.isin('''***********
|
|
241
|
+
Light Edges
|
|
242
|
+
***********
|
|
243
|
+
|
|
244
|
+
``jenkies``
|
|
245
|
+
When used with a ``it:prod:soft`` node, the edge indicates The software uses
|
|
246
|
+
the jenkies technique.
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
``loves``
|
|
250
|
+
The source node loves the target node.
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
``sneaky``
|
|
254
|
+
When used with a ``ou:technique`` target node, the edge indicates The
|
|
255
|
+
technique referred to is sneakily used.
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
``zoinks``
|
|
259
|
+
When used with a ``it:prod:soft`` and an ``ou:technique`` node, the edge
|
|
260
|
+
indicates The software uses the zoinks technique.
|
|
261
|
+
''', text)
|
|
262
|
+
self.isin('''****************
|
|
263
|
+
Deprecated Types
|
|
264
|
+
****************
|
|
265
|
+
|
|
266
|
+
The following types have been marked as deprecated:
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
* ``inet:port``
|
|
270
|
+
|
|
271
|
+
''', text)
|
|
272
|
+
self.isin('''****************
|
|
273
|
+
Deprecated Types
|
|
274
|
+
****************
|
|
275
|
+
|
|
276
|
+
The following forms have been marked as deprecated:
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
* ``it:reveng:function``
|
|
280
|
+
''', text)
|
|
281
|
+
self.isin('''*********************
|
|
282
|
+
Deprecated Properties
|
|
283
|
+
*********************
|
|
284
|
+
|
|
285
|
+
``file:mime:lnk``
|
|
286
|
+
The form had the following property deprecated:
|
|
287
|
+
|
|
288
|
+
``target:attrs``
|
|
289
|
+
The attributes of the target file according to the LNK header.
|
|
290
|
+
''', text)
|
|
291
|
+
|
|
292
|
+
async def test_changelog_model_diff_tool(self):
|
|
293
|
+
# diff the stored test asset model vs the current runtime model :fingers_crossed:
|
|
294
|
+
with self.getTestDir() as dirn:
|
|
295
|
+
cdir = s_common.gendir(s_common.genpath(dirn, 'changes'))
|
|
296
|
+
outp = self.getTestOutp()
|
|
297
|
+
argv = ['gen', '--cdir', cdir, '--verbose', '--type', 'feat', 'I am a mighty feature!']
|
|
298
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
299
|
+
|
|
300
|
+
modl_dirn = s_common.gendir(s_common.genpath(dirn, 'model'))
|
|
301
|
+
old_fp = self.getTestFilePath('changelog', 'model_2.176.0_16ee721a6b7221344eaf946c3ab4602dda546b1a.yaml.gz')
|
|
302
|
+
|
|
303
|
+
argv = ['format', '--cdir', cdir, '--version', 'v0.1.2', '--date', '2025-10-03',
|
|
304
|
+
'--model-doc-dir', modl_dirn, '--model-ref', old_fp,
|
|
305
|
+
'--model-doc-no-git', '--verbose',
|
|
306
|
+
]
|
|
307
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
308
|
+
# We have many assertions we may run over outp where using outp.expect()
|
|
309
|
+
# not not be the most efficient
|
|
310
|
+
outp_str = str(outp)
|
|
311
|
+
# model diff data
|
|
312
|
+
self.isin('Not adding model changes to git.', outp_str)
|
|
313
|
+
# Changelog data
|
|
314
|
+
self.isin('v0.1.2 - 2025-10-03', outp_str)
|
|
315
|
+
self.isin('- See :ref:`userguide_model_v0_1_2` for more detailed model changes.', outp_str)
|
|
316
|
+
self.isin('- I am a mighty feature!', outp_str)
|
|
317
|
+
|
|
318
|
+
async def test_changelog_model_save_compare(self):
|
|
319
|
+
with self.getTestDir() as dirn:
|
|
320
|
+
outp = self.getTestOutp()
|
|
321
|
+
argv = ['model', '--cdir', dirn, '--save',]
|
|
322
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
323
|
+
modelrefs_dirn = s_common.genpath(dirn, 'modelrefs')
|
|
324
|
+
|
|
325
|
+
files = os.listdir(modelrefs_dirn)
|
|
326
|
+
self.len(1, files)
|
|
327
|
+
|
|
328
|
+
model_fp = s_common.genpath(modelrefs_dirn, files[0])
|
|
329
|
+
|
|
330
|
+
with s_common.genfile(model_fp) as fd:
|
|
331
|
+
buf = fd.read()
|
|
332
|
+
buf = gzip.decompress(buf)
|
|
333
|
+
data = s_common.yamlloads(buf)
|
|
334
|
+
self.isin('commit', data)
|
|
335
|
+
self.isin('model', data)
|
|
336
|
+
self.isin('version', data)
|
|
337
|
+
|
|
338
|
+
# Test compare vs self - no changes
|
|
339
|
+
outp.clear()
|
|
340
|
+
argv = ['model', '-c', model_fp, '--verbose']
|
|
341
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
342
|
+
outp.expect("'edges': {}")
|
|
343
|
+
outp.expect("'forms': {}")
|
|
344
|
+
outp.expect("'interfaces': {}")
|
|
345
|
+
outp.expect("'tagprops': {}")
|
|
346
|
+
outp.expect("'types': {}")
|
|
347
|
+
outp.expect("'univs': {}")
|
|
348
|
+
|
|
349
|
+
async def test_changelog_gen_format(self):
|
|
350
|
+
with self.getTestDir() as dirn:
|
|
351
|
+
outp = self.getTestOutp()
|
|
352
|
+
argv = ['gen', '--cdir', dirn, '--type', 'feat', '--pr', '1234', 'I am a feature.']
|
|
353
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
354
|
+
|
|
355
|
+
outp = self.getTestOutp()
|
|
356
|
+
argv = ['gen', '--cdir', dirn, '--type', 'feat', '--pr', '1230', 'I am a earlier feature.']
|
|
357
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
358
|
+
|
|
359
|
+
outp.clear()
|
|
360
|
+
desc = '''I am a bug which has quite a large amount of text in it. The amount of text will span across'''\
|
|
361
|
+
''' multiple lines after being formatted by the changelog tool.'''
|
|
362
|
+
argv = ['gen', '--cdir', dirn, '--type', 'bug', desc]
|
|
363
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
364
|
+
|
|
365
|
+
outp.clear()
|
|
366
|
+
desc = 'I am a fancy note.'
|
|
367
|
+
argv = ['gen', '--cdir', dirn, '--type', 'note', desc]
|
|
368
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
369
|
+
|
|
370
|
+
outp.clear()
|
|
371
|
+
desc = 'For widget maker has been deprecated in favor of the new acme corp laser cannons.'
|
|
372
|
+
argv = ['gen', '--cdir', dirn, '--type', 'deprecation', desc,]
|
|
373
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
374
|
+
|
|
375
|
+
outp.clear()
|
|
376
|
+
desc = 'Documented the lasers.'
|
|
377
|
+
argv = ['gen', '--cdir', dirn, '--type', 'doc', desc]
|
|
378
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
379
|
+
|
|
380
|
+
outp.clear()
|
|
381
|
+
desc = 'Migrated the widget storage to use acme lasers.'
|
|
382
|
+
argv = ['gen', '--cdir', dirn, '--type', 'migration', desc]
|
|
383
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
384
|
+
|
|
385
|
+
outp.clear()
|
|
386
|
+
desc = 'Added lasers to the sci model.'
|
|
387
|
+
argv = ['gen', '--cdir', dirn, '--type', 'model', desc]
|
|
388
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
389
|
+
|
|
390
|
+
with s_common.genfile(dirn, f'{s_common.guid()}.yaml') as fd:
|
|
391
|
+
fd.write(multiline_feature.encode())
|
|
392
|
+
|
|
393
|
+
outp.clear()
|
|
394
|
+
argv = ['format', '--cdir', dirn, '--version', 'v0.1.22', '--date', '2025-10-03']
|
|
395
|
+
self.eq(0, await s_t_changelog.main(argv, outp))
|
|
396
|
+
|
|
397
|
+
self.eq(str(outp).strip(), changelog_format_output.strip())
|
|
398
|
+
|
|
399
|
+
# Sad path tests
|
|
400
|
+
with self.getTestDir() as dirn:
|
|
401
|
+
outp = self.getTestOutp()
|
|
402
|
+
|
|
403
|
+
fp = s_common.genpath(dirn, s_common.guid())
|
|
404
|
+
with s_common.genfile(fp) as fd:
|
|
405
|
+
fd.write('hello world'.encode())
|
|
406
|
+
|
|
407
|
+
argv = ['format', '--cdir', dirn, '--version', 'v0.1.22', '--date', '2025-10-03']
|
|
408
|
+
self.eq(1, await s_t_changelog.main(argv, outp))
|
|
409
|
+
outp.expect('Error running')
|
|
410
|
+
|
|
411
|
+
with s_common.genfile(fp) as fd:
|
|
412
|
+
fd.truncate(0)
|
|
413
|
+
fd.write(s_common.buid())
|
|
414
|
+
outp.clear()
|
|
415
|
+
argv = ['format', '--cdir', dirn, '--version', 'v0.1.22', '--date', '2025-10-03']
|
|
416
|
+
self.eq(1, await s_t_changelog.main(argv, outp))
|
|
417
|
+
outp.expect('No files passed validation')
|
|
418
|
+
|
|
419
|
+
with s_common.genfile(fp) as fd:
|
|
420
|
+
fd.truncate(0)
|
|
421
|
+
fd.write('''desc:literal: true
|
|
422
|
+
desc: |
|
|
423
|
+
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
424
|
+
type: feat
|
|
425
|
+
'''.encode())
|
|
426
|
+
outp.clear()
|
|
427
|
+
argv = ['format', '--cdir', dirn, '--version', 'v0.1.22', '--date', '2025-10-03']
|
|
428
|
+
self.eq(1, await s_t_changelog.main(argv, outp))
|
|
429
|
+
outp.expect('desc line 0 must start with "- "')
|
|
430
|
+
|
|
431
|
+
with s_common.genfile(fp) as fd:
|
|
432
|
+
fd.truncate(0)
|
|
433
|
+
fd.write('''desc:literal: true
|
|
434
|
+
desc: |
|
|
435
|
+
- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
436
|
+
xxxxxx
|
|
437
|
+
type: feat
|
|
438
|
+
'''.encode())
|
|
439
|
+
outp.clear()
|
|
440
|
+
argv = ['format', '--cdir', dirn, '--version', 'v0.1.22', '--date', '2025-10-03']
|
|
441
|
+
self.eq(1, await s_t_changelog.main(argv, outp))
|
|
442
|
+
outp.expect('desc line 1 must start with " "')
|
|
443
|
+
|
|
444
|
+
with s_common.genfile(fp) as fd:
|
|
445
|
+
fd.truncate(0)
|
|
446
|
+
fd.write('''desc:literal: true
|
|
447
|
+
desc: |
|
|
448
|
+
- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
449
|
+
type: feat
|
|
450
|
+
'''.encode())
|
|
451
|
+
outp.clear()
|
|
452
|
+
argv = ['format', '--cdir', dirn, '--version', 'v0.1.22', '--date', '2025-10-03']
|
|
453
|
+
self.eq(1, await s_t_changelog.main(argv, outp))
|
|
454
|
+
outp.expect('desc line 0 is too long, 79 > 79')
|