python-kacl 0.7.3__tar.gz → 0.7.5__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.
Files changed (33) hide show
  1. {python_kacl-0.7.3/python_kacl.egg-info → python_kacl-0.7.5}/PKG-INFO +1 -1
  2. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/__init__.py +1 -1
  3. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/document.py +32 -15
  4. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/kacl_cli.py +7 -2
  5. {python_kacl-0.7.3 → python_kacl-0.7.5}/pyproject.toml +1 -1
  6. {python_kacl-0.7.3 → python_kacl-0.7.5/python_kacl.egg-info}/PKG-INFO +1 -1
  7. {python_kacl-0.7.3 → python_kacl-0.7.5}/tests/test_cli.py +28 -0
  8. {python_kacl-0.7.3 → python_kacl-0.7.5}/tests/test_cli_workflow.py +41 -0
  9. {python_kacl-0.7.3 → python_kacl-0.7.5}/tests/test_kacl.py +24 -0
  10. {python_kacl-0.7.3 → python_kacl-0.7.5}/LICENSE +0 -0
  11. {python_kacl-0.7.3 → python_kacl-0.7.5}/MANIFEST.in +0 -0
  12. {python_kacl-0.7.3 → python_kacl-0.7.5}/README.md +0 -0
  13. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/__main__.py +0 -0
  14. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/changes.py +0 -0
  15. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/config/kacl-default.yml +0 -0
  16. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/config.py +0 -0
  17. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/element.py +0 -0
  18. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/exception.py +0 -0
  19. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/jira_client.py +0 -0
  20. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/link_provider.py +0 -0
  21. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/parser.py +0 -0
  22. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/serializer.py +0 -0
  23. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/utils.py +0 -0
  24. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/validation.py +0 -0
  25. {python_kacl-0.7.3 → python_kacl-0.7.5}/kacl/version.py +0 -0
  26. {python_kacl-0.7.3 → python_kacl-0.7.5}/python_kacl.egg-info/SOURCES.txt +0 -0
  27. {python_kacl-0.7.3 → python_kacl-0.7.5}/python_kacl.egg-info/dependency_links.txt +0 -0
  28. {python_kacl-0.7.3 → python_kacl-0.7.5}/python_kacl.egg-info/entry_points.txt +0 -0
  29. {python_kacl-0.7.3 → python_kacl-0.7.5}/python_kacl.egg-info/not-zip-safe +0 -0
  30. {python_kacl-0.7.3 → python_kacl-0.7.5}/python_kacl.egg-info/requires.txt +0 -0
  31. {python_kacl-0.7.3 → python_kacl-0.7.5}/python_kacl.egg-info/top_level.txt +0 -0
  32. {python_kacl-0.7.3 → python_kacl-0.7.5}/requirements.txt +0 -0
  33. {python_kacl-0.7.3 → python_kacl-0.7.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-kacl
3
- Version: 0.7.3
3
+ Version: 0.7.5
4
4
  Summary: Python module and CLI tool for validating and modifying Changelogs in "keep-a-changelog" format"
5
5
  Author-email: Matthias Schmieder <schmieder.matthias@gmail.com>
6
6
  License: MIT
@@ -1,5 +1,5 @@
1
1
  # Version of the python-kacl package
2
- __version__ = "0.7.3"
2
+ __version__ = "0.7.5"
3
3
 
4
4
  from kacl.document import KACLDocument
5
5
  from kacl.serializer import KACLMarkdownSerializer
@@ -30,7 +30,7 @@ class KACLDocument:
30
30
  link_references=None,
31
31
  meta_data=None,
32
32
  file_path=None,
33
- config=KACLConfig(),
33
+ config=None,
34
34
  ):
35
35
  self.__data = data
36
36
  self.__headers = headers if headers else []
@@ -39,7 +39,7 @@ class KACLDocument:
39
39
  if not self.__link_references:
40
40
  self.__link_references = dict()
41
41
  self.__meta_data = meta_data
42
- self.config = config
42
+ self.config = config if config is not None else KACLConfig()
43
43
  self.stash = []
44
44
  self.file_path = file_path
45
45
 
@@ -74,17 +74,29 @@ class KACLDocument:
74
74
  if not os.path.isdir(local_stash_dir):
75
75
  return
76
76
 
77
- # read all md files in the stash directory
78
- for f in os.listdir(local_stash_dir):
79
- if f.endswith(".md"):
80
- md_file = os.path.join(local_stash_dir, f)
81
- with open(md_file, "r") as fh:
82
- data = fh.read()
83
- try:
84
- doc = KACLDocument.parse(data, None)
85
- self.stash.append(doc)
86
- except Exception:
87
- continue
77
+ # read all md files in the stash directory (including legacy
78
+ # sub-directories created by branch names containing a slash)
79
+ for md_file in self.stash_files():
80
+ with open(md_file, "r") as fh:
81
+ data = fh.read()
82
+ try:
83
+ doc = KACLDocument.parse(data, None)
84
+ # stash documents must be validated against the same
85
+ # config as the changelog they belong to
86
+ doc.config = self.config
87
+ self.stash.append(doc)
88
+ except Exception:
89
+ continue
90
+
91
+ def stash_files(self):
92
+ """Returns the paths of all stash files, including nested ones."""
93
+ stash_dir = self._ensure_stash_directory()
94
+ files = []
95
+ for root, _, names in os.walk(stash_dir):
96
+ for name in sorted(names):
97
+ if name.endswith(".md"):
98
+ files.append(os.path.join(root, name))
99
+ return sorted(files)
88
100
 
89
101
  def _ensure_stash_directory(self):
90
102
  # the stash needs always to be relative to the current file_path
@@ -205,7 +217,7 @@ class KACLDocument:
205
217
  try:
206
218
  v0 = versions[i]
207
219
  v1 = versions[i + 1]
208
- if semver.compare(v0.version(), v1.version()) < 1:
220
+ if semver.Version.parse(v0.version()).compare(v1.version()) < 1:
209
221
  validation.add_error(
210
222
  line=v1.raw(),
211
223
  line_number=v1.line_number(),
@@ -619,7 +631,12 @@ class KACLDocument:
619
631
  versions[i].set_link(link_provider.unreleased_changes(**fargs))
620
632
  else:
621
633
  versions[i].set_link(link_provider.compare_versions(**fargs))
622
- versions[-1].set_link(link_provider.initial_version(**fargs))
634
+ versions[-1].set_link(
635
+ link_provider.initial_version(
636
+ version=versions[-1].version(),
637
+ latest_version=self.current_version(),
638
+ )
639
+ )
623
640
  elif len(versions) == 1:
624
641
  fargs = {
625
642
  "version": versions[0].version(),
@@ -545,11 +545,16 @@ def release(
545
545
 
546
546
  # delete all file in the stash directory
547
547
  stash_files = []
548
- for f in os.listdir(kacl_changelog.stash_directory):
549
- stash_file = os.path.join(kacl_changelog.stash_directory, f)
548
+ for stash_file in kacl_changelog.stash_files():
550
549
  os.remove(stash_file)
551
550
  stash_files.append(stash_file)
552
551
 
552
+ # remove sub-directories left empty (legacy branch names with slashes)
553
+ stash_dir = kacl_changelog.stash_directory
554
+ for root, _, _ in os.walk(stash_dir, topdown=False):
555
+ if root != stash_dir and not os.listdir(root):
556
+ os.rmdir(root)
557
+
553
558
  if commit or tag or kacl_config.git_create_commit or kacl_config.git_create_tag:
554
559
  vcs_context = {
555
560
  "latest_version": latest_version,
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-kacl"
7
- version = "0.7.3"
7
+ version = "0.7.5"
8
8
  description = "Python module and CLI tool for validating and modifying Changelogs in \"keep-a-changelog\" format\""
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-kacl
3
- Version: 0.7.3
3
+ Version: 0.7.5
4
4
  Summary: Python module and CLI tool for validating and modifying Changelogs in "keep-a-changelog" format"
5
5
  Author-email: Matthias Schmieder <schmieder.matthias@gmail.com>
6
6
  License: MIT
@@ -20,6 +20,34 @@ def test_verify():
20
20
  assert result.exit_code == 11 # spawns 11 errors
21
21
 
22
22
 
23
+ def test_verify_stash_with_custom_sections(tmp_path):
24
+ """Stash files must be validated against the loaded config, not the built-in defaults."""
25
+ runner = CliRunner()
26
+ resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
27
+ changelog_file = os.path.join(resources_dir, "CHANGELOG.md")
28
+ stash_dir_local = os.path.join(resources_dir, "stash-custom-section")
29
+ config_file = os.path.join(resources_dir, "custom-sections-config.yml")
30
+
31
+ with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
32
+ shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
33
+ shutil.copytree(stash_dir_local, os.path.join(project_root_path, ".kacl_stash"))
34
+
35
+ # without the custom config the stashed "Chore" section is rejected
36
+ result = runner.invoke(
37
+ cli, ["-f", "CHANGELOG.md", "verify"], catch_exceptions=False
38
+ )
39
+ assert result.exit_code != 0, result.output
40
+ assert '"Chore" is not a valid section' in result.output
41
+
42
+ # with a config that allows "Chore" the stashed changes must validate
43
+ result = runner.invoke(
44
+ cli,
45
+ ["-c", config_file, "-f", "CHANGELOG.md", "verify"],
46
+ catch_exceptions=False,
47
+ )
48
+ assert result.exit_code == 0, result.output
49
+
50
+
23
51
  def test_verify_invalid_duplicates():
24
52
  runner = CliRunner()
25
53
  result = runner.invoke(
@@ -182,3 +182,44 @@ def test_integration_workflow_config(tmp_path, snapshot):
182
182
 
183
183
  assert result.exit_code == 0, result.output
184
184
  snapshot_directory(snapshot=snapshot, directory_path=project_root_path)
185
+
186
+
187
+ def test_release_with_nested_stash_directory(tmp_path):
188
+ runner = CliRunner()
189
+ resources_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data/")
190
+ changelog_file = os.path.join(resources_dir, "CHANGELOG_with_changes.md")
191
+ config = os.path.join(resources_dir, "stash-config.yml")
192
+
193
+ with runner.isolated_filesystem(temp_dir=tmp_path) as project_root_path:
194
+ shutil.copyfile(changelog_file, os.path.join(project_root_path, "CHANGELOG.md"))
195
+
196
+ # stash file for a branch like "refactor/foo" written by older versions
197
+ result = runner.invoke(
198
+ cli,
199
+ [
200
+ "-c",
201
+ config,
202
+ "-f",
203
+ "CHANGELOG.md",
204
+ "add",
205
+ "--stash",
206
+ "-m",
207
+ "Changed",
208
+ "x",
209
+ ],
210
+ catch_exceptions=False,
211
+ )
212
+ assert result.exit_code == 0, result.output
213
+ stash_dir = os.path.join(project_root_path, ".kacl_stash")
214
+ flat = os.path.join(stash_dir, os.listdir(stash_dir)[0])
215
+ nested_dir = os.path.join(stash_dir, "refactor")
216
+ os.makedirs(nested_dir)
217
+ shutil.move(flat, os.path.join(nested_dir, "foo.md"))
218
+
219
+ result = runner.invoke(
220
+ cli,
221
+ ["-c", config, "-f", "CHANGELOG.md", "release", "99.0.0", "-m"],
222
+ catch_exceptions=False,
223
+ )
224
+ assert result.exit_code == 0, result.output
225
+ assert os.listdir(stash_dir) == []
@@ -427,6 +427,30 @@ class TestKacl(TestCase):
427
427
  for v in versions:
428
428
  self.assertIsNotNone(v.link())
429
429
 
430
+ def test_link_generation_initial_version(self):
431
+ changelog_file = os.path.join(
432
+ os.path.dirname(os.path.realpath(__file__)), "data", "CHANGELOG.md"
433
+ )
434
+ changelog = kacl.load(changelog_file)
435
+ host_url = "https://github.com/user/repository"
436
+ changelog.generate_links(host_url=host_url)
437
+
438
+ versions = changelog.versions()
439
+
440
+ # the oldest version has to link to its own tag, not the penultimate one
441
+ initial_version = versions[-1]
442
+ self.assertEqual(
443
+ initial_version.link(),
444
+ f"{host_url}/tree/{initial_version.version()}",
445
+ )
446
+
447
+ # every version in between has to compare against its predecessor
448
+ for i in range(1, len(versions) - 1):
449
+ self.assertEqual(
450
+ versions[i].link(),
451
+ f"{host_url}/compare/{versions[i + 1].version()}...{versions[i].version()}",
452
+ )
453
+
430
454
 
431
455
  def test_squash(tmp_path, snapshot):
432
456
  changelog_file = os.path.join(
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes