consync 0.1.0__tar.gz → 2.0.0__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 (71) hide show
  1. consync-2.0.0/.github/workflows/release.yml +81 -0
  2. {consync-0.1.0 → consync-2.0.0}/PKG-INFO +3 -2
  3. {consync-0.1.0 → consync-2.0.0}/README.md +2 -1
  4. {consync-0.1.0 → consync-2.0.0}/consync/__init__.py +1 -1
  5. {consync-0.1.0 → consync-2.0.0}/consync/cli.py +6 -6
  6. {consync-0.1.0 → consync-2.0.0}/consync/config.py +2 -0
  7. {consync-0.1.0 → consync-2.0.0}/consync/lock.py +2 -2
  8. {consync-0.1.0 → consync-2.0.0}/consync/models.py +3 -0
  9. {consync-0.1.0 → consync-2.0.0}/consync/parsers/__init__.py +1 -2
  10. consync-2.0.0/consync/parsers/c_struct_table.py +615 -0
  11. {consync-0.1.0 → consync-2.0.0}/consync/renderers/__init__.py +2 -2
  12. {consync-0.1.0 → consync-2.0.0}/consync/renderers/c_header.py +5 -6
  13. consync-2.0.0/consync/renderers/c_struct_table.py +207 -0
  14. {consync-0.1.0 → consync-2.0.0}/consync/renderers/csharp.py +7 -7
  15. {consync-0.1.0 → consync-2.0.0}/consync/renderers/python_const.py +3 -3
  16. {consync-0.1.0 → consync-2.0.0}/consync/renderers/rust_const.py +3 -3
  17. {consync-0.1.0 → consync-2.0.0}/consync/renderers/verilog.py +3 -3
  18. {consync-0.1.0 → consync-2.0.0}/consync/renderers/vhdl.py +10 -10
  19. {consync-0.1.0 → consync-2.0.0}/consync/sync.py +184 -13
  20. {consync-0.1.0 → consync-2.0.0}/consync/watcher.py +1 -1
  21. consync-2.0.0/npm/.npmrc +2 -0
  22. consync-2.0.0/npm/LICENSE +21 -0
  23. consync-2.0.0/npm/README.md +43 -0
  24. consync-2.0.0/npm/bin/consync.js +62 -0
  25. consync-2.0.0/npm/package.json +48 -0
  26. consync-2.0.0/npm/scripts/install.js +33 -0
  27. {consync-0.1.0 → consync-2.0.0}/pyproject.toml +1 -1
  28. {consync-0.1.0 → consync-2.0.0}/tests/test_arrays.py +0 -3
  29. consync-2.0.0/tests/test_c_struct_table.py +474 -0
  30. {consync-0.1.0 → consync-2.0.0}/tests/test_cli.py +0 -1
  31. {consync-0.1.0 → consync-2.0.0}/tests/test_embedded.py +1 -2
  32. {consync-0.1.0 → consync-2.0.0}/tests/test_parsers.py +0 -1
  33. {consync-0.1.0 → consync-2.0.0}/tests/test_precision.py +0 -1
  34. {consync-0.1.0 → consync-2.0.0}/tests/test_renderers.py +0 -1
  35. {consync-0.1.0 → consync-2.0.0}/tests/test_safety.py +1 -4
  36. {consync-0.1.0 → consync-2.0.0}/tests/test_sync.py +1 -3
  37. {consync-0.1.0 → consync-2.0.0}/.github/CODEOWNERS +0 -0
  38. {consync-0.1.0 → consync-2.0.0}/.github/copilot-instructions.md +0 -0
  39. {consync-0.1.0 → consync-2.0.0}/.github/dependabot.yml +0 -0
  40. {consync-0.1.0 → consync-2.0.0}/.github/workflows/ci.yml +0 -0
  41. {consync-0.1.0 → consync-2.0.0}/.github/workflows/codeql.yml +0 -0
  42. {consync-0.1.0 → consync-2.0.0}/.github/workflows/publish.yml +0 -0
  43. {consync-0.1.0 → consync-2.0.0}/.gitignore +0 -0
  44. {consync-0.1.0 → consync-2.0.0}/CLAUDE.md +0 -0
  45. {consync-0.1.0 → consync-2.0.0}/CONTRIBUTING.md +0 -0
  46. {consync-0.1.0 → consync-2.0.0}/FAQ.md +0 -0
  47. {consync-0.1.0 → consync-2.0.0}/LICENSE +0 -0
  48. {consync-0.1.0 → consync-2.0.0}/SECURITY.md +0 -0
  49. {consync-0.1.0 → consync-2.0.0}/TODO.md +0 -0
  50. {consync-0.1.0 → consync-2.0.0}/assets/demo.gif +0 -0
  51. {consync-0.1.0 → consync-2.0.0}/assets/demo.tape +0 -0
  52. {consync-0.1.0 → consync-2.0.0}/consync/backup.py +0 -0
  53. {consync-0.1.0 → consync-2.0.0}/consync/hooks.py +0 -0
  54. {consync-0.1.0 → consync-2.0.0}/consync/logging_config.py +0 -0
  55. {consync-0.1.0 → consync-2.0.0}/consync/parsers/c_header.py +0 -0
  56. {consync-0.1.0 → consync-2.0.0}/consync/parsers/csv_parser.py +0 -0
  57. {consync-0.1.0 → consync-2.0.0}/consync/parsers/json_parser.py +0 -0
  58. {consync-0.1.0 → consync-2.0.0}/consync/parsers/toml_parser.py +0 -0
  59. {consync-0.1.0 → consync-2.0.0}/consync/parsers/xlsx.py +0 -0
  60. {consync-0.1.0 → consync-2.0.0}/consync/precision.py +0 -0
  61. {consync-0.1.0 → consync-2.0.0}/consync/renderers/csv_renderer.py +0 -0
  62. {consync-0.1.0 → consync-2.0.0}/consync/renderers/json_renderer.py +0 -0
  63. {consync-0.1.0 → consync-2.0.0}/consync/state.py +0 -0
  64. {consync-0.1.0 → consync-2.0.0}/consync/validators.py +0 -0
  65. {consync-0.1.0 → consync-2.0.0}/examples/fpga/.consync.yaml +0 -0
  66. {consync-0.1.0 → consync-2.0.0}/examples/fpga/design_params.csv +0 -0
  67. {consync-0.1.0 → consync-2.0.0}/examples/hardware/.consync.yaml +0 -0
  68. {consync-0.1.0 → consync-2.0.0}/examples/hardware/constants.csv +0 -0
  69. {consync-0.1.0 → consync-2.0.0}/examples/multilang/.consync.yaml +0 -0
  70. {consync-0.1.0 → consync-2.0.0}/examples/multilang/constants.json +0 -0
  71. {consync-0.1.0 → consync-2.0.0}/tests/__init__.py +0 -0
@@ -0,0 +1,81 @@
1
+ name: Release — PyPI + npm + Homebrew
2
+
3
+ on:
4
+ push:
5
+ tags: ['v*']
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ pypi:
12
+ name: Publish to PyPI
13
+ runs-on: ubuntu-latest
14
+ environment: pypi
15
+ permissions:
16
+ id-token: write
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - uses: actions/setup-python@v5
20
+ with:
21
+ python-version: "3.12"
22
+ - run: pip install build
23
+ - run: python -m build
24
+ - uses: pypa/gh-action-pypi-publish@release/v1
25
+
26
+ npm:
27
+ name: Publish to npm
28
+ runs-on: ubuntu-latest
29
+ needs: pypi
30
+ defaults:
31
+ run:
32
+ working-directory: npm
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+ - uses: actions/setup-node@v4
36
+ with:
37
+ node-version: 20
38
+ registry-url: https://registry.npmjs.org
39
+ - name: Update version in package.json
40
+ run: |
41
+ VERSION="${GITHUB_REF_NAME#v}"
42
+ jq --arg v "$VERSION" '.version = $v' package.json > tmp.json && mv tmp.json package.json
43
+ - run: npm publish --access public
44
+ env:
45
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
46
+
47
+ homebrew:
48
+ name: Update Homebrew tap
49
+ runs-on: ubuntu-latest
50
+ needs: pypi
51
+ steps:
52
+ - name: Wait for PyPI propagation
53
+ run: sleep 30
54
+
55
+ - name: Get version from tag
56
+ id: version
57
+ run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
58
+
59
+ - name: Get SHA256 from PyPI
60
+ id: sha
61
+ run: |
62
+ URL=$(curl -sL "https://pypi.org/pypi/consync/${{ steps.version.outputs.version }}/json" \
63
+ | jq -r '.urls[] | select(.packagetype=="sdist") | .url')
64
+ SHA=$(curl -sL "https://pypi.org/pypi/consync/${{ steps.version.outputs.version }}/json" \
65
+ | jq -r '.urls[] | select(.packagetype=="sdist") | .digests.sha256')
66
+ echo "url=$URL" >> "$GITHUB_OUTPUT"
67
+ echo "sha256=$SHA" >> "$GITHUB_OUTPUT"
68
+
69
+ - name: Update Homebrew formula
70
+ uses: peter-evans/repository-dispatch@v3
71
+ with:
72
+ token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
73
+ repository: naveenkumarbaskaran/homebrew-tap
74
+ event-type: update-formula
75
+ client-payload: |
76
+ {
77
+ "formula": "consync",
78
+ "version": "${{ steps.version.outputs.version }}",
79
+ "url": "${{ steps.sha.outputs.url }}",
80
+ "sha256": "${{ steps.sha.outputs.sha256 }}"
81
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: consync
3
- Version: 0.1.0
3
+ Version: 2.0.0
4
4
  Summary: Bidirectional sync between spreadsheets and source code constants — with full decimal precision.
5
5
  Project-URL: Homepage, https://github.com/naveenkumarbaskaran/consync
6
6
  Project-URL: Repository, https://github.com/naveenkumarbaskaran/consync
@@ -43,7 +43,8 @@ Keep a single source of truth for hardware constants (resistor values, timing pa
43
43
  <img src="assets/demo.gif" alt="consync demo" width="720">
44
44
  </p>
45
45
 
46
- [![PyPI version](https://img.shields.io/pypi/v/consync.svg)](https://pypi.org/project/consync/)
46
+ [![PyPI version](https://img.shields.io/pypi/v/consync)](https://pypi.org/project/consync/)
47
+ [![npm version](https://img.shields.io/npm/v/consync)](https://www.npmjs.com/package/consync)
47
48
  [![CI](https://github.com/naveenkumarbaskaran/consync/actions/workflows/ci.yml/badge.svg)](https://github.com/naveenkumarbaskaran/consync/actions/workflows/ci.yml)
48
49
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://python.org)
49
50
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
@@ -8,7 +8,8 @@ Keep a single source of truth for hardware constants (resistor values, timing pa
8
8
  <img src="assets/demo.gif" alt="consync demo" width="720">
9
9
  </p>
10
10
 
11
- [![PyPI version](https://img.shields.io/pypi/v/consync.svg)](https://pypi.org/project/consync/)
11
+ [![PyPI version](https://img.shields.io/pypi/v/consync)](https://pypi.org/project/consync/)
12
+ [![npm version](https://img.shields.io/npm/v/consync)](https://www.npmjs.com/package/consync)
12
13
  [![CI](https://github.com/naveenkumarbaskaran/consync/actions/workflows/ci.yml/badge.svg)](https://github.com/naveenkumarbaskaran/consync/actions/workflows/ci.yml)
13
14
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://python.org)
14
15
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
@@ -1,6 +1,6 @@
1
1
  """consync — Bidirectional sync between spreadsheets and source code constants."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "2.0.0"
4
4
 
5
5
  from consync.models import Constant, SyncDirection
6
6
  from consync.config import load_config
@@ -48,8 +48,8 @@ def init(path: str):
48
48
 
49
49
  target.write_text(generate_default_config())
50
50
  click.echo(f"✅ Created {target}")
51
- click.echo(f" Edit it to configure your source ↔ target mappings.")
52
- click.echo(f" Then run: consync sync")
51
+ click.echo(" Edit it to configure your source ↔ target mappings.")
52
+ click.echo(" Then run: consync sync")
53
53
 
54
54
 
55
55
  @main.command(name="sync")
@@ -101,9 +101,9 @@ def check(config_path: str | None):
101
101
  all_ok = False
102
102
 
103
103
  if all_ok:
104
- click.echo(f"\n✅ All mappings in sync.")
104
+ click.echo("\n✅ All mappings in sync.")
105
105
  else:
106
- click.echo(f"\n❌ Out of sync! Run 'consync sync' to fix.")
106
+ click.echo("\n❌ Out of sync! Run 'consync sync' to fix.")
107
107
  sys.exit(1)
108
108
 
109
109
 
@@ -259,7 +259,7 @@ def recover_cmd(filepath: str | None, timestamp: str | None, last: bool, list_on
259
259
  for b in backups:
260
260
  size_kb = b["size"] / 1024
261
261
  click.echo(f" {b['timestamp']} {b['file']:30s} {size_kb:.1f} KB")
262
- click.echo(f"\nRestore with: consync recover --file <name> --at <timestamp>")
262
+ click.echo("\nRestore with: consync recover --file <name> --at <timestamp>")
263
263
  return
264
264
 
265
265
  if filepath is None:
@@ -291,7 +291,7 @@ def diff_cmd(config_path: str | None, from_side: str | None, color: bool):
291
291
  import tempfile
292
292
  from consync.config import load_config
293
293
  from consync.sync import _config_dir, _resolve_path, _parse_file, _render_file, _determine_direction
294
- from consync.state import SyncState, compute_hash
294
+ from consync.state import SyncState
295
295
 
296
296
  try:
297
297
  cfg = load_config(config_path)
@@ -116,6 +116,8 @@ def _parse_mapping(raw: dict[str, Any], config_dir: Path) -> MappingConfig:
116
116
  output_style=raw.get("output_style", "const"),
117
117
  static_const=raw.get("static_const", False),
118
118
  typed_ints=raw.get("typed_ints", True),
119
+ parser_options=raw.get("parser_options", {}),
120
+ renderer_options=raw.get("renderer_options", {}),
119
121
  validators=raw.get("validators", {}),
120
122
  )
121
123
 
@@ -14,7 +14,7 @@ from __future__ import annotations
14
14
  import json
15
15
  import logging
16
16
  import os
17
- import time
17
+ import platform
18
18
  from datetime import datetime, timezone
19
19
  from pathlib import Path
20
20
 
@@ -64,7 +64,7 @@ class SyncLock:
64
64
  lock_info = {
65
65
  "pid": os.getpid(),
66
66
  "created": datetime.now(timezone.utc).isoformat(timespec="seconds"),
67
- "hostname": os.uname().nodename,
67
+ "hostname": platform.node(),
68
68
  }
69
69
  self.lock_path.write_text(json.dumps(lock_info, indent=2))
70
70
  self._acquired = True
@@ -90,6 +90,9 @@ class MappingConfig:
90
90
  output_style: str = "const" # "const" | "define" — #define vs const declaration
91
91
  static_const: bool = False # emit "static const" to avoid linker duplicates
92
92
  typed_ints: bool = True # use uint32_t/int32_t instead of plain int/double for integers
93
+ # Parser/renderer options (format-specific kwargs)
94
+ parser_options: dict = field(default_factory=dict) # passed to parser as **kwargs
95
+ renderer_options: dict = field(default_factory=dict) # passed to renderer as **kwargs
93
96
  # Validation hooks
94
97
  validators: dict = field(default_factory=dict) # {name: {min:, max:, type:, pattern:, ...}}
95
98
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from pathlib import Path
6
5
  from typing import Callable
7
6
 
8
7
  from consync.models import Constant
@@ -37,4 +36,4 @@ def list_parsers() -> list[str]:
37
36
 
38
37
 
39
38
  # Import all parser modules to trigger registration
40
- from consync.parsers import xlsx, csv_parser, json_parser, toml_parser, c_header # noqa: E402, F401
39
+ from consync.parsers import xlsx, csv_parser, json_parser, toml_parser, c_header, c_struct_table # noqa: E402, F401