python-kacl 0.6.4__py3-none-any.whl → 0.6.5__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.
kacl/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  # Version of the python-kacl package
2
- __version__ = "0.6.4"
2
+ __version__ = "0.6.5"
3
3
 
4
4
  from kacl.document import KACLDocument
5
5
  from kacl.serializer import KACLMarkdownSerializer
kacl/serializer.py CHANGED
@@ -19,7 +19,11 @@ class KACLMarkdownSerializer:
19
19
  data.extend(serialized_metadata)
20
20
 
21
21
  data.append(self.__serialize_header(document.header()))
22
- data.append(document.header().body())
22
+ # check if the body starts with a newline. if not add one
23
+ if document.header().body().startswith("\n"):
24
+ data.append(document.header().body())
25
+ else:
26
+ data.append("\n" + document.header().body())
23
27
 
24
28
  for version in document.versions():
25
29
  data.extend([self.__serialize_version(version), ""])
@@ -67,11 +71,12 @@ class KACLMarkdownSerializer:
67
71
  return f"# {obj.title()}"
68
72
 
69
73
  def __serialize_version(self, obj):
70
- lines = [self.__serialize_header(obj)]
74
+ lines = [self.__serialize_header(obj), ""]
71
75
  for title, changes in obj.sections().items():
72
76
  lines.extend(
73
77
  [
74
78
  self.__serialize_header(changes),
79
+ "",
75
80
  self.__serialize_list(changes.items()),
76
81
  "",
77
82
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-kacl
3
- Version: 0.6.4
3
+ Version: 0.6.5
4
4
  Summary: Python module and CLI tool for validating and modifying Changelogs in "keep-a-changelog" format"
5
5
  Home-page: https://gitlab.com/schmieder.matthias/python-kacl.git
6
6
  Author: Matthias Schmieder
@@ -1,4 +1,4 @@
1
- kacl/__init__.py,sha256=q8SmFU-sgBzWA5PVrCnpP_Bb1gmCSKi3grD6o4TcEmw,644
1
+ kacl/__init__.py,sha256=WUM42QzTkxNY6Yd-x-FEqcO2NFfzXkqDhRoAyqME1EE,644
2
2
  kacl/__main__.py,sha256=cpulIGoFUJNN5ZW9oUoNN1PnBvrOyJ24xwtpf_yRwgQ,91
3
3
  kacl/changes.py,sha256=A0POz-xFMpFuq7nISnx_K75xOZOMmBuHq6EZ8NOQDsU,661
4
4
  kacl/config.py,sha256=Glw-1hRqS3AHpZ-2QRGzHRQ-TSLc1xtneb2MEATWFEQ,3966
@@ -9,18 +9,14 @@ kacl/jira_client.py,sha256=KPE94bZDkJFKw3okFsCgf2DjoyMlUUTMZKtQGKreVQY,989
9
9
  kacl/kacl_cli.py,sha256=KeCT4DydkHjckt5sbTtTwp2BQf0RllXpBUwLj-G5-U0,19987
10
10
  kacl/link_provider.py,sha256=tgvMYhJe2ErH1m_qXMlQEacq9Cg_KGp_-sF03sVFP6E,1866
11
11
  kacl/parser.py,sha256=EUtRjgaW0beWVqiYaRJ9Rcf6jbuGoTgWzVBdOdUHnv8,2587
12
- kacl/serializer.py,sha256=VkPuW06-ehaHsNRtskLJ7o-l3Ckgs8oONkgxceewrms,2851
12
+ kacl/serializer.py,sha256=PdR2FFCh9rbBhkxXwUYD0fSjQqTG_Mb6mYws3lNAWQ8,3090
13
13
  kacl/utils.py,sha256=bHiDDmjoYB868Bm732vNjpfML-6xcNQQqS7NQn_Sfm0,2824
14
14
  kacl/validation.py,sha256=b9r_5CyY6Cmi9BePh47IgZ3j64zdVsoB_fFvucieNbw,2125
15
15
  kacl/version.py,sha256=IDYCWIIXzxdYyMptUAidMgf0SXJqoETFVJ8NVyKgA9A,9526
16
16
  kacl/config/kacl-default.yml,sha256=BdrQytOsx32_vXXBtR3VRp1-nzWrczNVc-gHuCGYuIA,1424
17
- python_kacl-0.6.4.dist-info/licenses/LICENSE,sha256=TRSJOIt7LZuMeZXFleJVL_LHczSxqi70HEiTLT-kI8Q,1075
18
- tests/__init__.py,sha256=dwb12vsojIwrtIgqwjc2fWhEVgVoiedUaVpZ7kusfY0,23
19
- tests/snapshot_directory.py,sha256=yH_ZpzJG5nA6F1ZxCrFPpbxBBON6bxSYO5OYZqKuzZA,1264
20
- tests/test_cli.py,sha256=C4dMCJo-lq6rs5euIJdM55Bvm9YGKot_a36FO8YCtWU,17006
21
- tests/test_kacl.py,sha256=7hxrBVnj2srkhJGVrfpt651QEItthq-iDntxGnEbt_g,15919
22
- python_kacl-0.6.4.dist-info/METADATA,sha256=hC3mJKWO71afeUGCM_hlHL7cRL1AVAGO7WZQ-c8_JGs,24325
23
- python_kacl-0.6.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
- python_kacl-0.6.4.dist-info/entry_points.txt,sha256=8oCwuEyBEH-Z1M_xZIUePgfM7HfkYUAwcXdTPdrnwt4,49
25
- python_kacl-0.6.4.dist-info/top_level.txt,sha256=25gO0j-S3j_-DCptjHqVBlJi3tH_tiN8qyympi1E_Ys,11
26
- python_kacl-0.6.4.dist-info/RECORD,,
17
+ python_kacl-0.6.5.dist-info/licenses/LICENSE,sha256=TRSJOIt7LZuMeZXFleJVL_LHczSxqi70HEiTLT-kI8Q,1075
18
+ python_kacl-0.6.5.dist-info/METADATA,sha256=kVBx144zCKsmVBAnZS-RQ1omJ2QiPfIME6DtJRz8loE,24325
19
+ python_kacl-0.6.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
+ python_kacl-0.6.5.dist-info/entry_points.txt,sha256=rXqqJKfm6Y7fYfioq_7ay2VWOOM9C-hts1IsoGTtojM,76
21
+ python_kacl-0.6.5.dist-info/top_level.txt,sha256=BcmQgo67JyGnVZ3Jc0Ag8hKMGVOqXc8ex01zW4Njw5M,5
22
+ python_kacl-0.6.5.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ kacl = kacl.kacl_cli:start
2
3
  kacl-cli = kacl.kacl_cli:start
@@ -0,0 +1 @@
1
+ kacl
@@ -1,2 +0,0 @@
1
- kacl
2
- tests
tests/__init__.py DELETED
@@ -1 +0,0 @@
1
- __version__ = "0.4.51"
@@ -1,42 +0,0 @@
1
- import os
2
- from pathlib import Path
3
-
4
-
5
- def snapshot_directory(
6
- snapshot,
7
- directory_path,
8
- dir_excludes=[".git"],
9
- file_excludes=[],
10
- sanitize_callbacks={},
11
- ):
12
- snapshot_dir = {}
13
-
14
- for root, dirs, files in os.walk(directory_path, topdown=True):
15
- dirs[:] = [d for d in dirs if d not in dir_excludes]
16
-
17
- for file in files:
18
- if file in file_excludes:
19
- continue
20
- current = snapshot_dir
21
- parts = Path(root).relative_to(directory_path).parts
22
- for part in parts:
23
- current = current.setdefault(part, {})
24
-
25
- file_path = os.path.join(root, f"{file}")
26
- if __is_binary(file_path):
27
- content = open(file_path, "rb").read()
28
- else:
29
- content = open(file_path, "r").read()
30
-
31
- if file in sanitize_callbacks:
32
- callback = sanitize_callbacks[file]
33
- content = callback(content)
34
-
35
- current[f"{file}.snap"] = content
36
-
37
- snapshot.assert_match_dir(snapshot_dir, "snapshots")
38
-
39
-
40
- def __is_binary(file_path):
41
- textchars = bytearray({7, 8, 9, 10, 12, 13, 27} | set(range(0x20, 0x100)) - {0x7F})
42
- return bool(open(file_path, "rb").read(1024).translate(None, textchars))
tests/test_cli.py DELETED
@@ -1,492 +0,0 @@
1
- import json
2
- import os
3
- import shutil
4
-
5
- import pytest
6
- from click.testing import CliRunner
7
- from freezegun import freeze_time
8
-
9
- from kacl.kacl_cli import cli
10
- from tests.snapshot_directory import snapshot_directory
11
-
12
-
13
- def test_verify():
14
- runner = CliRunner()
15
- result = runner.invoke(cli, ["-f", "tests/data/CHANGELOG.md", "verify"])
16
- assert result.exit_code == 0
17
- assert result.output == "Success\n"
18
-
19
- result = runner.invoke(cli, ["-f", "tests/data/CHANGELOG_invalid.md", "verify"])
20
- assert result.exit_code == 10 # spawns 8 errors
21
-
22
-
23
- def test_verify_invalid_duplicates():
24
- runner = CliRunner()
25
- result = runner.invoke(
26
- cli, ["-f", "tests/data/CHANGELOG_invalid_duplicates.md", "verify"]
27
- )
28
- assert result.exit_code == 2
29
-
30
-
31
- def test_verify_with_json_output():
32
- runner = CliRunner()
33
- result = runner.invoke(
34
- cli, ["-f", "tests/data/CHANGELOG_invalid.md", "verify", "--json"]
35
- )
36
- validation_result = json.loads(result.output)
37
-
38
- assert len(validation_result["errors"]) == 10
39
- assert validation_result["valid"] is False
40
-
41
-
42
- def test_current(tmp_path, snapshot):
43
- runner = CliRunner()
44
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
45
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
46
-
47
- with runner.isolated_filesystem(temp_dir=tmp_path):
48
- result = runner.invoke(
49
- cli,
50
- [
51
- "-f",
52
- changelog_file,
53
- "current",
54
- ],
55
- catch_exceptions=False,
56
- )
57
- assert result.exit_code == 0, result.output
58
- assert result.output == "1.0.0\n"
59
-
60
-
61
- def test_next(tmp_path, snapshot):
62
- runner = CliRunner()
63
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
64
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
65
-
66
- with runner.isolated_filesystem(temp_dir=tmp_path):
67
- result = runner.invoke(
68
- cli,
69
- ["-f", changelog_file, "next", "patch"],
70
- catch_exceptions=False,
71
- )
72
- assert result.exit_code == 0, result.output
73
- assert result.output == "1.0.1\n"
74
-
75
-
76
- @freeze_time("2023-01-01")
77
- def test_release_patch(tmp_path, snapshot):
78
- runner = CliRunner()
79
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
80
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
81
-
82
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
83
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
84
- result = runner.invoke(
85
- cli,
86
- [
87
- "-f",
88
- "CHANGELOG.md",
89
- "release",
90
- "patch",
91
- "-m",
92
- ],
93
- catch_exceptions=False,
94
- )
95
- assert result.exit_code == 0, result.output
96
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
97
-
98
-
99
- @freeze_time("2023-01-01")
100
- def test_release_post_bump(tmp_path, snapshot):
101
- runner = CliRunner()
102
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
103
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
104
-
105
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
106
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
107
- result = runner.invoke(
108
- cli,
109
- [
110
- "-c",
111
- os.path.join(resources_dir, "extension-config.yml"),
112
- "-f",
113
- "CHANGELOG.md",
114
- "release",
115
- "post",
116
- "-m",
117
- ],
118
- catch_exceptions=False,
119
- )
120
- assert result.exit_code == 0, result.output
121
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
122
-
123
-
124
- @freeze_time("2023-01-01")
125
- def test_release_post_manual(tmp_path, snapshot):
126
- runner = CliRunner()
127
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
128
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
129
-
130
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
131
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
132
- result = runner.invoke(
133
- cli,
134
- [
135
- "-c",
136
- os.path.join(resources_dir, "extension-config.yml"),
137
- "-f",
138
- "CHANGELOG.md",
139
- "release",
140
- "2.0.0-hotfix.0",
141
- "-m",
142
- ],
143
- catch_exceptions=False,
144
- )
145
- assert result.exit_code == 0, result.output
146
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
147
-
148
-
149
- @freeze_time("2023-01-01")
150
- def test_release_post_manual_fail(tmp_path, snapshot):
151
- runner = CliRunner()
152
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
153
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
154
-
155
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
156
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
157
- result = runner.invoke(
158
- cli,
159
- [
160
- "-c",
161
- os.path.join(resources_dir, "extension-config.yml"),
162
- "-f",
163
- "CHANGELOG.md",
164
- "release",
165
- "0.5.0-hotfix.0",
166
- "-m",
167
- ],
168
- catch_exceptions=True,
169
- )
170
- assert result.exit_code == 1, result.output
171
-
172
-
173
- @freeze_time("2023-01-01")
174
- def test_release_version_manual_fail_same_base_after_post(tmp_path, snapshot):
175
- runner = CliRunner()
176
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
177
- changelog_file = os.path.join(resources_dir, "CHANGELOG_post_with_changes.md")
178
-
179
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
180
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
181
- result = runner.invoke(
182
- cli,
183
- [
184
- "-c",
185
- os.path.join(resources_dir, "extension-config.yml"),
186
- "-f",
187
- "CHANGELOG.md",
188
- "release",
189
- "1.0.0",
190
- "-m",
191
- ],
192
- catch_exceptions=True,
193
- )
194
- assert result.exit_code == 1, result.output
195
-
196
-
197
- @freeze_time("2023-01-01")
198
- def test_release_post_manual_same_base(tmp_path, snapshot):
199
- runner = CliRunner()
200
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
201
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
202
-
203
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
204
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
205
- result = runner.invoke(
206
- cli,
207
- [
208
- "-c",
209
- os.path.join(resources_dir, "extension-config.yml"),
210
- "-f",
211
- "CHANGELOG.md",
212
- "release",
213
- "1.0.0-post.0",
214
- "-m",
215
- ],
216
- catch_exceptions=False,
217
- )
218
- assert result.exit_code == 0, result.output
219
-
220
-
221
- @freeze_time("2023-01-01")
222
- def test_release_minor(tmp_path, snapshot):
223
- runner = CliRunner()
224
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
225
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
226
-
227
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
228
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
229
- result = runner.invoke(
230
- cli,
231
- [
232
- "-f",
233
- "CHANGELOG.md",
234
- "release",
235
- "minor",
236
- "-m",
237
- ],
238
- catch_exceptions=False,
239
- )
240
- assert result.exit_code == 0, result.output
241
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
242
-
243
-
244
- @freeze_time("2023-01-01")
245
- def test_release_major(tmp_path, snapshot):
246
- runner = CliRunner()
247
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
248
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
249
-
250
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
251
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
252
- result = runner.invoke(
253
- cli,
254
- [
255
- "-f",
256
- "CHANGELOG.md",
257
- "release",
258
- "major",
259
- "-m",
260
- ],
261
- catch_exceptions=False,
262
- )
263
- assert result.exit_code == 0, result.output
264
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
265
-
266
-
267
- @freeze_time("2023-01-01")
268
- def test_release_custom(tmp_path, snapshot):
269
- runner = CliRunner()
270
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
271
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
272
-
273
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
274
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
275
- result = runner.invoke(
276
- cli,
277
- [
278
- "-f",
279
- "CHANGELOG.md",
280
- "release",
281
- "2.1.1",
282
- "-m",
283
- ],
284
- catch_exceptions=False,
285
- )
286
- assert result.exit_code == 0, result.output
287
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
288
-
289
-
290
- @freeze_time("2023-01-01")
291
- def test_add_change_security(tmp_path, snapshot):
292
- runner = CliRunner()
293
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
294
- changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
295
-
296
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
297
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
298
- result = runner.invoke(
299
- cli,
300
- [
301
- "-f",
302
- "CHANGELOG.md",
303
- "add",
304
- "Security",
305
- "Important Security Change",
306
- "-m",
307
- ],
308
- catch_exceptions=False,
309
- )
310
- assert result.exit_code == 0, result.output
311
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
312
-
313
-
314
- def test_config(tmp_path, snapshot):
315
- runner = CliRunner()
316
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
317
-
318
- result = runner.invoke(
319
- cli,
320
- [
321
- "-c",
322
- os.path.join(resources_dir, "config.yml"),
323
- "-f",
324
- "CHANGELOG.md",
325
- "verify",
326
- ],
327
- catch_exceptions=False,
328
- )
329
- assert result.exit_code != 0, result.output
330
-
331
-
332
- @freeze_time("2023-01-01")
333
- def test_squash(tmp_path, snapshot):
334
- runner = CliRunner()
335
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
336
- changelog_file = os.path.join(resources_dir, "CHANGELOG_keepachangelog.com.md")
337
-
338
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
339
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
340
- result = runner.invoke(
341
- cli,
342
- [
343
- "-f",
344
- "CHANGELOG.md",
345
- "squash",
346
- "--from-version",
347
- "0.0.1",
348
- "--to-version",
349
- "0.3.0",
350
- "-m",
351
- ],
352
- catch_exceptions=False,
353
- )
354
- assert result.exit_code == 0, result.output
355
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
356
-
357
-
358
- def test_squash_current(tmp_path, snapshot):
359
- runner = CliRunner()
360
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
361
- changelog_file = os.path.join(resources_dir, "CHANGELOG_keepachangelog.com.md")
362
-
363
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
364
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
365
- result = runner.invoke(
366
- cli,
367
- [
368
- "-f",
369
- "CHANGELOG.md",
370
- "squash",
371
- "--from-version",
372
- "0.0.1",
373
- "-m",
374
- ],
375
- catch_exceptions=False,
376
- )
377
- assert result.exit_code == 0, result.output
378
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
379
-
380
-
381
- @pytest.mark.skip(reason="No issue tracker openly available, test locally.")
382
- def test_add_comments(tmp_path):
383
- runner = CliRunner()
384
- root_dir = os.path.join(
385
- os.path.dirname(os.path.realpath(__file__)),
386
- "..",
387
- )
388
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
389
- changelog_file = os.path.join(resources_dir, "CHANGELOG_issue_management.md")
390
-
391
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
392
- shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
393
- shutil.copytree(
394
- os.path.join(root_dir, ".git"), os.path.join(project_root_path, ".git")
395
- )
396
- result = runner.invoke(
397
- cli,
398
- [
399
- "-f",
400
- "CHANGELOG.md",
401
- "add-comments",
402
- "1.0.0",
403
- "--jira-username",
404
- os.getenv("JIRA_USERNAME"),
405
- "--jira-password",
406
- os.getenv("JIRA_PASSWORD"),
407
- "--jira-host",
408
- os.getenv("JIRA_HOST"),
409
- "--jira-issue-pattern",
410
- "JIRA-[0-9]+",
411
- "--jira-issue-pattern",
412
- "MYJIRA-[0-9]+",
413
- "--jira-issue-pattern",
414
- "[A-Z]+-[0-9]+",
415
- ],
416
- catch_exceptions=False,
417
- )
418
- assert result.exit_code == 0, result.output
419
-
420
-
421
- @freeze_time("2023-01-01")
422
- def test_get_no_link_available(tmp_path, snapshot):
423
- runner = CliRunner()
424
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
425
- changelog_file = os.path.join(resources_dir, "CHANGELOG_missing_link.md")
426
-
427
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
428
- result = runner.invoke(
429
- cli,
430
- [
431
- "-c",
432
- os.path.join(resources_dir, "extension-config.yml"),
433
- "-f",
434
- changelog_file,
435
- "get",
436
- "2.0.0",
437
- ],
438
- catch_exceptions=False,
439
- )
440
- assert result.exit_code == 0, result.output
441
- with open(os.path.join(project_root_path, "output.md"), "w") as file:
442
- file.write(result.output)
443
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
444
-
445
-
446
- def test_get_link_available(tmp_path, snapshot):
447
- runner = CliRunner()
448
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
449
- changelog_file = os.path.join(resources_dir, "CHANGELOG_missing_link.md")
450
-
451
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
452
- result = runner.invoke(
453
- cli,
454
- [
455
- "-c",
456
- os.path.join(resources_dir, "extension-config.yml"),
457
- "-f",
458
- changelog_file,
459
- "get",
460
- "1.0.0",
461
- ],
462
- catch_exceptions=False,
463
- )
464
- assert result.exit_code == 0, result.output
465
- with open(os.path.join(project_root_path, "output.md"), "w") as file:
466
- file.write(result.output)
467
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
468
-
469
-
470
- def test_get_suppress_available_link(tmp_path, snapshot):
471
- runner = CliRunner()
472
- resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
473
- changelog_file = os.path.join(resources_dir, "CHANGELOG_missing_link.md")
474
-
475
- with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
476
- result = runner.invoke(
477
- cli,
478
- [
479
- "-c",
480
- os.path.join(resources_dir, "extension-config.yml"),
481
- "-f",
482
- changelog_file,
483
- "get",
484
- "--no-link",
485
- "1.0.0",
486
- ],
487
- catch_exceptions=False,
488
- )
489
- assert result.exit_code == 0, result.output
490
- with open(os.path.join(project_root_path, "output.md"), "w") as file:
491
- file.write(result.output)
492
- snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
tests/test_kacl.py DELETED
@@ -1,479 +0,0 @@
1
- import os
2
- from unittest import TestCase
3
-
4
- import pytest
5
- import yaml
6
-
7
- import kacl
8
- from kacl.config import KACLConfig
9
- from kacl.exception import KACLException
10
- from tests.snapshot_directory import snapshot_directory
11
-
12
-
13
- class TestKacl(TestCase):
14
- def test_load_valid(self):
15
- changelog_file = os.path.join(
16
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
17
- )
18
- changelog = kacl.load(changelog_file)
19
-
20
- self.assertEqual(changelog.title(), "Changelog")
21
- self.assertGreater(len(changelog.versions()), 0)
22
-
23
- version = changelog.get("1.0.0")
24
- self.assertIsNotNone(version)
25
-
26
- added_changes = version.changes("Added")
27
- self.assertIsNotNone(added_changes)
28
-
29
- added_items = added_changes.items()
30
- self.assertIsNotNone(added_items)
31
-
32
- def test_dump(self):
33
- changelog_file = os.path.join(
34
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
35
- )
36
- changelog = kacl.load(changelog_file)
37
- changelog_dump = kacl.dump(changelog)
38
- self.assertIsNotNone(changelog_dump)
39
-
40
- with open(changelog_file, "r") as reference_file:
41
- changelog_reference = reference_file.read()
42
- reference_file.close()
43
-
44
- changelog_dump_lines = changelog_dump.split("\n")
45
- changelog_reference_lines = changelog_reference.split("\n")
46
-
47
- self.assertEqual(len(changelog_dump_lines), len(changelog_reference_lines))
48
- self.assertEqual(changelog_dump, changelog_reference)
49
-
50
- def test_add_change(self):
51
- changelog_file = os.path.join(
52
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
53
- )
54
-
55
- changelog = kacl.load(changelog_file)
56
-
57
- msg = "This is my first added change"
58
- changelog.add("Added", msg)
59
-
60
- changelog_dump = kacl.dump(changelog)
61
- self.assertIsNotNone(changelog_dump)
62
-
63
- changelog_changed = kacl.parse(changelog_dump)
64
- self.assertIsNotNone(changelog_changed)
65
-
66
- unreleased = changelog_changed.get("Unreleased")
67
- self.assertIsNotNone(unreleased)
68
-
69
- unreleased_change_sections = unreleased.sections()
70
- self.assertIsNotNone(unreleased_change_sections)
71
- self.assertIn("Added", unreleased_change_sections)
72
-
73
- unreleased_changes_added = unreleased.changes("Added")
74
- self.assertIsNotNone(unreleased_changes_added)
75
-
76
- self.assertIn(msg, unreleased_changes_added.items())
77
-
78
- def test_release(self):
79
- valid_files = ["CHANGELOG.md", "CHANGELOG_unrelease_only.md"]
80
-
81
- for filename in valid_files:
82
- changelog_file = os.path.join(
83
- os.path.dirname(os.path.realpath(__file__)), "data", filename
84
- )
85
- changelog = kacl.load(changelog_file)
86
-
87
- msg = "This is my first added change"
88
- changelog.add("Added", msg)
89
-
90
- self.assertTrue(changelog.has_changes())
91
-
92
- changelog.release(version="2.0.0", link="https://my-new-version/2.0.0.html")
93
-
94
- changelog_dump = kacl.dump(changelog)
95
- self.assertIsNotNone(changelog_dump)
96
-
97
- changelog_changed = kacl.parse(changelog_dump)
98
- self.assertIsNotNone(changelog_changed)
99
-
100
- version = changelog_changed.get("2.0.0")
101
- self.assertIsNotNone(version)
102
-
103
- self.assertIn(msg, version.changes("Added").items())
104
-
105
- def test_invalid(self):
106
- invalid_files = [
107
- "CHANGELOG_invalid.md",
108
- "CHANGELOG_missing_sections.md",
109
- "CHANGELOG_no_unreleased.md",
110
- ]
111
-
112
- for filename in invalid_files:
113
- changelog_file = os.path.join(
114
- os.path.dirname(os.path.realpath(__file__)), "data", filename
115
- )
116
- changelog = kacl.load(changelog_file)
117
- self.assertFalse(changelog.is_valid())
118
-
119
- def test_valid(self):
120
- changelog_file = os.path.join(
121
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
122
- )
123
- changelog = kacl.load(changelog_file)
124
- self.assertTrue(changelog.is_valid())
125
-
126
- validation = changelog.validate()
127
- self.assertGreaterEqual(len(validation.errors()), 0)
128
-
129
- def test_valid_keepachangelogcom(self):
130
- changelog_file = os.path.join(
131
- os.path.dirname(os.path.realpath(__file__)),
132
- "data/CHANGELOG_keepachangelog.com.md",
133
- )
134
- changelog = kacl.load(changelog_file)
135
- self.assertTrue(changelog.is_valid())
136
-
137
- validation = changelog.validate()
138
- self.assertGreaterEqual(len(validation.errors()), 0)
139
-
140
- def test_valid_project_changelog(self):
141
- changelog_file = os.path.join(
142
- os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "CHANGELOG.md"
143
- )
144
- changelog = kacl.load(changelog_file)
145
- self.assertTrue(changelog.is_valid())
146
-
147
- validation = changelog.validate()
148
- self.assertGreaterEqual(len(validation.errors()), 0)
149
-
150
- def test_load_empty(self):
151
- changelog = kacl.parse("")
152
- self.assertFalse(changelog.is_valid())
153
-
154
- def test_release_without_changes(self):
155
- changelog_file = os.path.join(
156
- os.path.dirname(os.path.realpath(__file__)),
157
- "data/CHANGELOG_no_unreleased.md",
158
- )
159
- changelog = kacl.load(changelog_file)
160
-
161
- self.assertFalse(changelog.has_changes())
162
- self.assertRaises(
163
- Exception,
164
- changelog.release,
165
- "1.1.1",
166
- "https://gitlab.com/schmieder.matthias/python-kacl.git/-/compare/v1.0.0...HEAD",
167
- )
168
-
169
- def test_release_existing_version(self):
170
- changelog_file = os.path.join(
171
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
172
- )
173
- changelog = kacl.load(changelog_file)
174
-
175
- msg = "This is my first added change"
176
- changelog.add("Added", msg)
177
-
178
- self.assertTrue(changelog.has_changes())
179
- self.assertRaises(
180
- Exception,
181
- changelog.release,
182
- "1.0.0",
183
- "https://gitlab.com/schmieder.matthias/python-kacl.git/-/compare/v1.0.0...HEAD",
184
- )
185
-
186
- def test_release_without_older_version(self):
187
- changelog_file = os.path.join(
188
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
189
- )
190
- changelog = kacl.load(changelog_file)
191
-
192
- msg = "This is my first added change"
193
- changelog.add("Added", msg)
194
-
195
- self.assertTrue(changelog.has_changes())
196
- self.assertRaises(
197
- Exception,
198
- changelog.release,
199
- "0.9.0",
200
- "https://gitlab.com/schmieder.matthias/python-kacl.git/-/compare/v1.0.0...HEAD",
201
- )
202
-
203
- def test_release_with_non_semver(self):
204
- changelog_file = os.path.join(
205
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
206
- )
207
- changelog = kacl.load(changelog_file)
208
-
209
- msg = "This is my first added change"
210
- changelog.add("Added", msg)
211
-
212
- self.assertTrue(changelog.has_changes())
213
- self.assertRaises(
214
- Exception,
215
- changelog.release,
216
- "a0.9.0",
217
- "https://gitlab.com/schmieder.matthias/python-kacl.git/-/compare/v1.0.0...HEAD",
218
- )
219
-
220
- def test_release_with_allow_no_changes_flag(self):
221
- changelog_file = os.path.join(
222
- os.path.dirname(os.path.realpath(__file__)),
223
- "data/CHANGELOG_without_changes.md",
224
- )
225
- changelog = kacl.load(changelog_file)
226
-
227
- self.assertFalse(changelog.has_changes())
228
- changelog.release("1.0.1", allow_no_changes=True)
229
- self.assertEqual("1.0.1", changelog.current_version())
230
-
231
- def test_release_with_increment(self):
232
- tests = {
233
- "major": "2.0.0",
234
- "minor": "1.1.0",
235
- "patch": "1.0.1",
236
- }
237
- changelog_file = os.path.join(
238
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
239
- )
240
-
241
- for increment, expected_version in tests.items():
242
- changelog = kacl.load(changelog_file)
243
-
244
- msg = "This is my first added change"
245
- changelog.add("Added", msg)
246
-
247
- self.assertTrue(changelog.has_changes())
248
- changelog.release(increment=increment)
249
- self.assertEqual(expected_version, changelog.current_version())
250
-
251
- fail_tests = {"post": "1.0.0-post.1"}
252
-
253
- for increment, expected_version in fail_tests.items():
254
- changelog = kacl.load(changelog_file)
255
- changelog.config.post_release_version_prefix = None
256
-
257
- msg = "This is my first added change"
258
- changelog.add("Added", msg)
259
-
260
- self.assertTrue(changelog.has_changes())
261
- self.assertRaises(KACLException, changelog.release, increment=increment)
262
-
263
- def test_release_with_increment_extension(self):
264
- tests = {
265
- "major": "2.0.0",
266
- "minor": "1.1.0",
267
- "patch": "1.0.1",
268
- "post": "1.0.0-post.1",
269
- }
270
- changelog_file = os.path.join(
271
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
272
- )
273
-
274
- for increment, expected_version in tests.items():
275
- changelog = kacl.load(changelog_file)
276
- changelog.config.post_release_version_prefix = "post"
277
-
278
- msg = "This is my first added change"
279
- changelog.add("Added", msg)
280
-
281
- self.assertTrue(changelog.has_changes())
282
- changelog.release(increment=increment)
283
- self.assertEqual(expected_version, changelog.current_version())
284
-
285
- def test_release_with_increment_extension_hotfix(self):
286
- tests = {
287
- "major": "2.0.0",
288
- "minor": "1.1.0",
289
- "patch": "1.0.1",
290
- "post": "1.0.0-hotfix.1",
291
- }
292
- changelog_file = os.path.join(
293
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG.md"
294
- )
295
-
296
- for increment, expected_version in tests.items():
297
- changelog = kacl.load(changelog_file)
298
- changelog.config.post_release_version_prefix = "hotfix"
299
-
300
- msg = "This is my first added change"
301
- changelog.add("Added", msg)
302
-
303
- self.assertTrue(changelog.has_changes())
304
- changelog.release(increment=increment)
305
- self.assertEqual(expected_version, changelog.current_version())
306
-
307
- def test_post_release_with_increment(self):
308
- tests = {
309
- "major": "2.0.0",
310
- "minor": "1.1.0",
311
- "patch": "1.0.1",
312
- "post": "1.0.0-post.2",
313
- }
314
- changelog_file = os.path.join(
315
- os.path.dirname(os.path.realpath(__file__)), "data/CHANGELOG_post.md"
316
- )
317
-
318
- for increment, expected_version in tests.items():
319
- changelog = kacl.load(changelog_file)
320
- changelog.config.post_release_version_prefix = "post"
321
-
322
- msg = "This is my first added change"
323
- changelog.add("Added", msg)
324
-
325
- self.assertTrue(changelog.has_changes())
326
- changelog.release(increment=increment)
327
- self.assertEqual(expected_version, changelog.current_version())
328
-
329
- def test_unreleased_missing_sections(self):
330
- changelog_file = os.path.join(
331
- os.path.dirname(os.path.realpath(__file__)),
332
- "data/CHANGELOG_missing_sections.md",
333
- )
334
-
335
- changelog = kacl.load(changelog_file)
336
- changelog.validate()
337
- self.assertFalse(changelog.is_valid())
338
-
339
- def test_config(self):
340
- config_file = os.path.join(
341
- os.path.dirname(os.path.realpath(__file__)), "data/config.yml"
342
- )
343
- kacl_config = KACLConfig(config_file=config_file)
344
-
345
- default_config = dict()
346
- with open("kacl/config/kacl-default.yml", "r") as f:
347
- default_config = yaml.safe_load(f)["kacl"]
348
-
349
- # changes in config_file
350
- # changelog_file: CHANGELOG.md
351
- # allowed_header_titles:
352
- # - ChangeLog
353
- # allowed_version_sections:
354
- # - Security
355
- # git:
356
- # commit: False
357
-
358
- self.assertNotEqual(
359
- kacl_config.allowed_header_titles, default_config["allowed_header_titles"]
360
- )
361
- self.assertEqual(kacl_config.allowed_header_titles, ["ChangeLog"])
362
-
363
- self.assertNotEqual(
364
- kacl_config.allowed_version_sections,
365
- default_config["allowed_version_sections"],
366
- )
367
- self.assertEqual(kacl_config.allowed_version_sections, ["Security"])
368
-
369
- self.assertNotEqual(
370
- kacl_config.git_create_commit, default_config["git"]["commit"]
371
- )
372
- self.assertEqual(kacl_config.git_create_commit, True)
373
-
374
- def test_link_generation(self):
375
- valid_files = ["CHANGELOG_unrelease_only.md"]
376
-
377
- for filename in valid_files:
378
- changelog_file = os.path.join(
379
- os.path.dirname(os.path.realpath(__file__)), "data", filename
380
- )
381
- changelog = kacl.load(changelog_file)
382
-
383
- changelog = kacl.load(changelog_file)
384
- changelog.generate_links()
385
-
386
- versions = changelog.versions()
387
- for v in versions:
388
- self.assertIsNotNone(v.link())
389
-
390
-
391
- def test_squash(tmp_path, snapshot):
392
- changelog_file = os.path.join(
393
- os.path.dirname(os.path.realpath(__file__)),
394
- "data/CHANGELOG_keepachangelog.com.md",
395
- )
396
- changelog = kacl.load(changelog_file)
397
- assert changelog.is_valid()
398
-
399
- validation = changelog.validate()
400
- assert len(validation.errors()) < 1
401
-
402
- changelog.squash(version_start="0.0.1", version_end="0.3.0", keep_version_info=True)
403
-
404
- squashed_changelog_file = os.path.join(tmp_path, "CHANGELOG.md")
405
- # Open the file for writing.
406
- with open(squashed_changelog_file, "w") as f:
407
- f.write(kacl.dump(changelog))
408
-
409
- snapshot_directory(snapshot=snapshot, directory_path=tmp_path)
410
-
411
-
412
- @pytest.mark.skip(reason="No issue tracker openly available, test locally.")
413
- def test_issue_tracker_comment(tmp_path):
414
- changelog_file = os.path.join(
415
- os.path.dirname(os.path.realpath(__file__)),
416
- "data/CHANGELOG_issue_management.md",
417
- )
418
- changelog = kacl.load(changelog_file)
419
- assert changelog.is_valid()
420
-
421
- changelog.add_comments(version=changelog.current_version())
422
-
423
-
424
- def test_render_comments(tmp_path):
425
- changelog_file = os.path.join(
426
- os.path.dirname(os.path.realpath(__file__)),
427
- "data/CHANGELOG_issue_management.md",
428
- )
429
- changelog = kacl.load(changelog_file)
430
- assert changelog.is_valid()
431
-
432
- rendered_comments = changelog.render_comments(version=changelog.current_version())
433
-
434
- assert "jira" in rendered_comments
435
-
436
-
437
- def test_get_issues(tmp_path):
438
- changelog_file = os.path.join(
439
- os.path.dirname(os.path.realpath(__file__)),
440
- "data/CHANGELOG_issue_management.md",
441
- )
442
- changelog = kacl.load(changelog_file)
443
- assert changelog.is_valid()
444
-
445
- issues = changelog.get_associated_issues(version=changelog.current_version())
446
- assert len(issues["jira"]) == 5
447
-
448
-
449
- def test_simple_metadata(tmp_path):
450
- changelog_file = os.path.join(
451
- os.path.dirname(os.path.realpath(__file__)),
452
- "data/CHANGELOG_with_simple_metadata.md",
453
- )
454
- changelog = kacl.load(changelog_file)
455
- assert changelog.is_valid()
456
-
457
- changelog.release(increment="major")
458
-
459
- content = kacl.dump(changelog)
460
-
461
- assert "---\ntitle: CHANGELOG\n---\n" in str(content)
462
-
463
-
464
- def test_complex_metadata(tmp_path):
465
- changelog_file = os.path.join(
466
- os.path.dirname(os.path.realpath(__file__)),
467
- "data/CHANGELOG_with_complex_metadata.md",
468
- )
469
- changelog = kacl.load(changelog_file)
470
- assert changelog.is_valid()
471
-
472
- changelog.release(increment="major")
473
-
474
- content = kacl.dump(changelog)
475
-
476
- assert (
477
- "---\nlist:\n- entry1\n- additional: true\n key: value\ntitle: CHANGELOG\n---\n"
478
- in str(content)
479
- )