python-kacl 0.7.0__py3-none-any.whl → 0.7.2__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.7.0"
2
+ __version__ = "0.7.2"
3
3
 
4
4
  from kacl.document import KACLDocument
5
5
  from kacl.serializer import KACLMarkdownSerializer
kacl/document.py CHANGED
@@ -330,6 +330,60 @@ class KACLDocument:
330
330
  self.__versions.insert(0, unreleased_version)
331
331
  unreleased_version.add(section.capitalize(), data)
332
332
 
333
+ def stash_unreleased(self):
334
+ """Moves all unreleased changes to the stash file.
335
+
336
+ This method takes all changes from the Unreleased section and writes them to
337
+ the stash file, then clears the Unreleased section from the changelog.
338
+ """
339
+ # Check if there are any unreleased changes
340
+ if not self.has_changes():
341
+ return False
342
+
343
+ # Get the unreleased version
344
+ unreleased_version = self.get("Unreleased")
345
+ if not unreleased_version:
346
+ return False
347
+
348
+ # Get or create the stash file
349
+ stash_file = self._get_stash_file()
350
+
351
+ if os.path.exists(stash_file):
352
+ # Load the stash file
353
+ kacl_changelog = kacl.load(stash_file)
354
+ else:
355
+ # Create a new stash file with an empty changelog
356
+ kacl_changelog = kacl.new()
357
+
358
+ # Add all unreleased changes to the stash
359
+ sections = unreleased_version.sections()
360
+ if sections:
361
+ for section_title, section_changes in sections.items():
362
+ for change_item in section_changes.items():
363
+ kacl_changelog.add(section=section_title, data=change_item)
364
+
365
+ # Write the updated stash file
366
+ kacl_changelog_content = kacl.dump(kacl_changelog)
367
+ with open(stash_file, "w") as f:
368
+ f.write(kacl_changelog_content)
369
+ f.close()
370
+
371
+ # Clear the unreleased section by replacing it with an empty one
372
+ # Find and remove the current unreleased version but keep the link reference if it exists
373
+ link = None
374
+
375
+ for i, version in enumerate(self.__versions):
376
+ if version.version() == "Unreleased":
377
+ link = version.link()
378
+ self.__versions.pop(i)
379
+ break
380
+
381
+ # Add a new empty unreleased version
382
+ new_unreleased = KACLVersion(version="Unreleased", link=link)
383
+ self.__versions.insert(0, new_unreleased)
384
+
385
+ return True
386
+
333
387
  def release(
334
388
  self,
335
389
  version=None,
kacl/kacl_cli.py CHANGED
@@ -44,7 +44,7 @@ def raise_on_invalid(kacl_changelog):
44
44
  sys.exit(1)
45
45
 
46
46
 
47
- def load_changelog(ctx):
47
+ def load_changelog(ctx, load_stash_files=True):
48
48
  config_file_path = ctx.obj["config"]
49
49
  input_file = ctx.obj["file"]
50
50
 
@@ -69,7 +69,8 @@ def load_changelog(ctx):
69
69
  # read the changelog
70
70
  kacl_changelog = kacl.load(kacl_config.changelog_file_path)
71
71
  kacl_changelog.config = kacl_config
72
- kacl_changelog.load_stash()
72
+ if load_stash_files:
73
+ kacl_changelog.load_stash()
73
74
 
74
75
  # share the objects
75
76
  return kacl_changelog
@@ -159,6 +160,51 @@ def add(ctx, section, message, modify, stash):
159
160
  click.echo(kacl_changelog_content)
160
161
 
161
162
 
163
+ @cli.command()
164
+ @click.pass_context
165
+ @click.option(
166
+ "-m",
167
+ "--modify",
168
+ is_flag=True,
169
+ help="This option will modify the changelog file directly.",
170
+ )
171
+ def stash(ctx, modify):
172
+ """Moves all unreleased changes from the changelog to the stash."""
173
+ # Load changelog WITHOUT loading stash files to avoid circular stashing
174
+ kacl_changelog = load_changelog(ctx, load_stash_files=False)
175
+
176
+ # Check if there are changes to stash
177
+ if not kacl_changelog.has_changes():
178
+ click.echo(
179
+ click.style("Info: ", fg="yellow") + "No unreleased changes to stash."
180
+ )
181
+ return
182
+
183
+ # Stash the unreleased changes
184
+ kacl_changelog.stash_unreleased()
185
+
186
+ stash_file = kacl_changelog._get_stash_file()
187
+ click.echo(
188
+ click.style("Success: ", fg="green")
189
+ + f"Unreleased changes have been moved to {stash_file}"
190
+ )
191
+
192
+ # Update the changelog file if modify flag is set
193
+ if modify:
194
+ kacl_changelog_content = kacl.dump(kacl_changelog)
195
+ with open(kacl_changelog.config.changelog_file_path, "w") as f:
196
+ f.write(kacl_changelog_content)
197
+ f.close()
198
+ click.echo(
199
+ click.style("Success: ", fg="green")
200
+ + f"Changelog file {kacl_changelog.config.changelog_file_path} has been updated."
201
+ )
202
+ else:
203
+ # Just print the modified changelog
204
+ kacl_changelog_content = kacl.dump(kacl_changelog)
205
+ click.echo(kacl_changelog_content)
206
+
207
+
162
208
  @cli.command()
163
209
  @click.pass_context
164
210
  def current(ctx):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-kacl
3
- Version: 0.7.0
3
+ Version: 0.7.2
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
@@ -42,6 +42,8 @@ A tool for verifying and modifying changelog in the [**K**eep-**A-C**hange-**L**
42
42
  - [Print the current release version](#print-the-current-release-version)
43
43
  - [Print a single release changelog](#print-a-single-release-changelog)
44
44
  - [Add an entry to an unreleased section](#add-an-entry-to-an-unreleased-section)
45
+ - [Stashing Unreleased Changes](#stashing-unreleased-changes)
46
+ - [Pre-commit Hook Integration](#pre-commit-hook-integration)
45
47
  - [Prepare a Changelog for a Release](#prepare-a-changelog-for-a-release)
46
48
  - [Changelog Fragments](#changelog-fragments)
47
49
  - [Configuration](#configuration)
@@ -121,13 +123,26 @@ docker -v $(pwd):$(pwd) -w $(pwd) mschmieder/kacl-cli:latest verify
121
123
 
122
124
  The package can also be used as a pre-commit hook. Just add the following to your `.pre-commit-config.yaml`
123
125
 
126
+ **Verify Changelog Format**
127
+
124
128
  ```yaml
125
129
  - repo: https://gitlab.com/schmieder.matthias/python-kacl
126
- rev: 'v0.3.0'
130
+ rev: 'v0.7.0' # Use the latest version
127
131
  hooks:
128
132
  - id: kacl-verify
129
133
  ```
130
134
 
135
+ **Auto-Stash Unreleased Changes (Prevent Merge Conflicts)**
136
+
137
+ ```yaml
138
+ - repo: https://gitlab.com/schmieder.matthias/python-kacl
139
+ rev: 'v0.7.0' # Use the latest version
140
+ hooks:
141
+ - id: kacl-stash
142
+ ```
143
+
144
+ The `kacl-stash` hook automatically moves unreleased changes to stash files before each commit, preventing merge conflicts in `CHANGELOG.md`. See [Stashing Unreleased Changes](#stashing-unreleased-changes) for more details.
145
+
131
146
  ## CLI
132
147
 
133
148
  ```
@@ -143,6 +158,7 @@ Commands:
143
158
  get Returns a given version from the Changelog
144
159
  new Creates a new changelog.
145
160
  release Creates a release for the latest 'unreleased' changes.
161
+ stash Moves all unreleased changes from the changelog to the stash.
146
162
  verify Verifies if the changelog is in "keep-a-changelog" format.
147
163
  ```
148
164
 
@@ -361,6 +377,112 @@ kacl-cli add added 'We just added some new cool stuff' --modify
361
377
  kacl-cli add changed 'And changed things a bit' --modify
362
378
  ```
363
379
 
380
+ ## Stashing Unreleased Changes
381
+
382
+ ```
383
+ Usage: kacl-cli stash [OPTIONS]
384
+
385
+ Moves all unreleased changes from the changelog to the stash.
386
+
387
+ Options:
388
+ -m, --modify This option will modify the changelog file directly.
389
+ --help Show this message and exit.
390
+ ```
391
+
392
+ The `stash` command provides a powerful solution for managing unreleased changes and **preventing merge conflicts** in collaborative development environments. It moves all unreleased changes from `CHANGELOG.md` to a stash file, leaving an empty "Unreleased" section in the main changelog.
393
+
394
+ **Primary Use Case: Avoiding Merge Conflicts**
395
+
396
+ When multiple team members work on different branches simultaneously and manually edit `CHANGELOG.md`, merge conflicts are inevitable. The `stash` command solves this problem by:
397
+
398
+ 1. **Moving changes out of the main changelog** into separate stash files
399
+ 2. **Preventing conflicts** during merges since the main changelog remains minimal
400
+ 3. **Preserving all changes** in stash files that are later consolidated during release
401
+
402
+ **Usage**
403
+
404
+ ```bash
405
+ # Preview what would be stashed (dry-run)
406
+ kacl-cli stash
407
+
408
+ # Actually stash the changes and update CHANGELOG.md
409
+ kacl-cli stash --modify
410
+ ```
411
+
412
+ **How It Works**
413
+
414
+ When you run `kacl-cli stash --modify`:
415
+
416
+ 1. All changes from the "Unreleased" section are extracted
417
+ 2. Changes are moved to a stash file in `.kacl_stash/` directory (default location)
418
+ 3. Stash files are named based on:
419
+ - Git branch name (when inside a git repository): `feature-branch.md`
420
+ - Current date (when outside git): `20230101.md`
421
+ 4. The "Unreleased" section in `CHANGELOG.md` is cleared
422
+ 5. During `kacl-cli release`, all stashed changes are automatically merged into the release
423
+
424
+ **Example Workflow**
425
+
426
+ ```bash
427
+ # Developer edits CHANGELOG.md directly
428
+ echo "- Added new feature" >> CHANGELOG.md
429
+
430
+ # Before committing, stash the changes to avoid conflicts
431
+ kacl-cli stash --modify
432
+
433
+ # CHANGELOG.md now has an empty Unreleased section
434
+ # Changes are in .kacl_stash/your-branch.md
435
+
436
+ # When ready to release, all stashed changes are included
437
+ kacl-cli release patch --modify
438
+ ```
439
+
440
+ ### Pre-commit Hook Integration
441
+
442
+ For maximum convenience, you can automate the stashing process using a pre-commit hook. This allows developers to continue editing `CHANGELOG.md` manually while automatically moving changes to the stash before each commit.
443
+
444
+ **Setup**
445
+
446
+ Add the `kacl-stash` hook to your `.pre-commit-config.yaml`:
447
+
448
+ ```yaml
449
+ repos:
450
+ - repo: https://gitlab.com/schmieder.matthias/python-kacl
451
+ rev: 'v0.7.0' # Use the latest version
452
+ hooks:
453
+ - id: kacl-stash
454
+ ```
455
+
456
+ **How It Works**
457
+
458
+ 1. Developer manually edits `CHANGELOG.md` (traditional workflow)
459
+ 2. Pre-commit hook automatically runs `kacl-cli stash -m` before each commit
460
+ 3. Changes are moved to stash files
461
+ 4. Only the cleaned `CHANGELOG.md` is committed
462
+ 5. Multiple branches can work independently without conflicts
463
+ 6. During release, all stashed changes are consolidated
464
+
465
+ **Benefits**
466
+
467
+ - ✅ **No workflow changes**: Developers continue editing `CHANGELOG.md` normally
468
+ - ✅ **Zero merge conflicts**: Main changelog stays minimal and conflict-free
469
+ - ✅ **Automatic management**: Pre-commit hook handles everything
470
+ - ✅ **Branch isolation**: Each branch has its own stash file
471
+ - ✅ **Seamless integration**: Changes automatically included in releases
472
+
473
+ **Configuration**
474
+
475
+ You can customize the stash directory in `.kacl.yml`:
476
+
477
+ ```yaml
478
+ kacl:
479
+ stash:
480
+ dir: .kacl_stash # Custom stash directory
481
+ always: False # Set to True to always use stash for 'kacl add'
482
+ ```
483
+
484
+ **Note**: The `stash` command is complementary to [Changelog Fragments](#changelog-fragments). While fragments support the `kacl add` workflow, the `stash` command is specifically designed for teams that prefer manually editing `CHANGELOG.md` but want to avoid merge conflicts.
485
+
364
486
  ## Prepare a Changelog for a Release
365
487
 
366
488
  ```
@@ -1,12 +1,12 @@
1
- kacl/__init__.py,sha256=MnxkLHetlUiurIRM5_1ECpv-0lmQO3yM4U-x0-U56Z4,667
1
+ kacl/__init__.py,sha256=a9OB0XDXEUnOYCDzHxN6YiQ58IrTOubzTfFXVmghz7M,667
2
2
  kacl/__main__.py,sha256=cpulIGoFUJNN5ZW9oUoNN1PnBvrOyJ24xwtpf_yRwgQ,91
3
3
  kacl/changes.py,sha256=Speu1KLMNQVn0U2BMaO8ta4IEaQLTQtpW0IhN0JjGdY,704
4
4
  kacl/config.py,sha256=c2QiP-BriJJwzrw36oigJWKe6t4o6yhmN_nPSL6bcRk,4242
5
- kacl/document.py,sha256=oNnxlXWEh4yfqK4dK8xhzjWrUPHbUizEj_PQhP73poQ,28763
5
+ kacl/document.py,sha256=jyltUjNWp67t54DMkBudOd3btX2awLJgGKDPvbyoMOo,30733
6
6
  kacl/element.py,sha256=OG02QI8ND5fJpBMceT6dbIHr4uX9gLxK_fPCsOvMDHI,416
7
7
  kacl/exception.py,sha256=MfOVpUvhcQtm10rSY__74-oLo445PG8mLFGJPPIfXH0,41
8
8
  kacl/jira_client.py,sha256=KPE94bZDkJFKw3okFsCgf2DjoyMlUUTMZKtQGKreVQY,989
9
- kacl/kacl_cli.py,sha256=RshCxLhh5YJa6tzl8f5dnLOYF3Kbl-EDD4m21hIJDPw,22176
9
+ kacl/kacl_cli.py,sha256=kUDssIf5SH6ppQxil8ESplUw6ejyj6srW6nOfXqLD0Y,23688
10
10
  kacl/link_provider.py,sha256=tgvMYhJe2ErH1m_qXMlQEacq9Cg_KGp_-sF03sVFP6E,1866
11
11
  kacl/parser.py,sha256=EUtRjgaW0beWVqiYaRJ9Rcf6jbuGoTgWzVBdOdUHnv8,2587
12
12
  kacl/serializer.py,sha256=PdR2FFCh9rbBhkxXwUYD0fSjQqTG_Mb6mYws3lNAWQ8,3090
@@ -14,9 +14,9 @@ kacl/utils.py,sha256=4iWIJVNtv22v0IGXDjuEATPMQsJBr5Ycy9Q2zV2jkHE,2835
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=cXHl_w04SW0HA7OyJMMuaC6DTeXlhI2Sfsx7lygTPf4,1513
17
- python_kacl-0.7.0.dist-info/licenses/LICENSE,sha256=TRSJOIt7LZuMeZXFleJVL_LHczSxqi70HEiTLT-kI8Q,1075
18
- python_kacl-0.7.0.dist-info/METADATA,sha256=H827aGS3Up34fHQcdUChKDqg1zv50U9u7stimIN_jY4,37949
19
- python_kacl-0.7.0.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
20
- python_kacl-0.7.0.dist-info/entry_points.txt,sha256=rXqqJKfm6Y7fYfioq_7ay2VWOOM9C-hts1IsoGTtojM,76
21
- python_kacl-0.7.0.dist-info/top_level.txt,sha256=BcmQgo67JyGnVZ3Jc0Ag8hKMGVOqXc8ex01zW4Njw5M,5
22
- python_kacl-0.7.0.dist-info/RECORD,,
17
+ python_kacl-0.7.2.dist-info/licenses/LICENSE,sha256=TRSJOIt7LZuMeZXFleJVL_LHczSxqi70HEiTLT-kI8Q,1075
18
+ python_kacl-0.7.2.dist-info/METADATA,sha256=Mocj5ub2iwUjpPJOlbullX5IJ4_MvmxABHoDlNbFsuw,42453
19
+ python_kacl-0.7.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
20
+ python_kacl-0.7.2.dist-info/entry_points.txt,sha256=rXqqJKfm6Y7fYfioq_7ay2VWOOM9C-hts1IsoGTtojM,76
21
+ python_kacl-0.7.2.dist-info/top_level.txt,sha256=BcmQgo67JyGnVZ3Jc0Ag8hKMGVOqXc8ex01zW4Njw5M,5
22
+ python_kacl-0.7.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (82.0.0)
2
+ Generator: setuptools (82.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5