consync 2.1.0__tar.gz → 2.2.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 (73) hide show
  1. {consync-2.1.0 → consync-2.2.0}/PKG-INFO +12 -8
  2. {consync-2.1.0 → consync-2.2.0}/README.md +11 -7
  3. {consync-2.1.0 → consync-2.2.0}/consync/config.py +32 -1
  4. {consync-2.1.0 → consync-2.2.0}/pyproject.toml +1 -1
  5. {consync-2.1.0 → consync-2.2.0}/.github/CODEOWNERS +0 -0
  6. {consync-2.1.0 → consync-2.2.0}/.github/copilot-instructions.md +0 -0
  7. {consync-2.1.0 → consync-2.2.0}/.github/dependabot.yml +0 -0
  8. {consync-2.1.0 → consync-2.2.0}/.github/workflows/ci.yml +0 -0
  9. {consync-2.1.0 → consync-2.2.0}/.github/workflows/codeql.yml +0 -0
  10. {consync-2.1.0 → consync-2.2.0}/.github/workflows/publish.yml +0 -0
  11. {consync-2.1.0 → consync-2.2.0}/.github/workflows/release.yml +0 -0
  12. {consync-2.1.0 → consync-2.2.0}/.gitignore +0 -0
  13. {consync-2.1.0 → consync-2.2.0}/CLAUDE.md +0 -0
  14. {consync-2.1.0 → consync-2.2.0}/CONTRIBUTING.md +0 -0
  15. {consync-2.1.0 → consync-2.2.0}/FAQ.md +0 -0
  16. {consync-2.1.0 → consync-2.2.0}/LICENSE +0 -0
  17. {consync-2.1.0 → consync-2.2.0}/SECURITY.md +0 -0
  18. {consync-2.1.0 → consync-2.2.0}/TODO.md +0 -0
  19. {consync-2.1.0 → consync-2.2.0}/assets/demo.gif +0 -0
  20. {consync-2.1.0 → consync-2.2.0}/assets/demo.tape +0 -0
  21. {consync-2.1.0 → consync-2.2.0}/consync/__init__.py +0 -0
  22. {consync-2.1.0 → consync-2.2.0}/consync/backup.py +0 -0
  23. {consync-2.1.0 → consync-2.2.0}/consync/cli.py +0 -0
  24. {consync-2.1.0 → consync-2.2.0}/consync/hooks.py +0 -0
  25. {consync-2.1.0 → consync-2.2.0}/consync/lock.py +0 -0
  26. {consync-2.1.0 → consync-2.2.0}/consync/logging_config.py +0 -0
  27. {consync-2.1.0 → consync-2.2.0}/consync/models.py +0 -0
  28. {consync-2.1.0 → consync-2.2.0}/consync/parsers/__init__.py +0 -0
  29. {consync-2.1.0 → consync-2.2.0}/consync/parsers/c_header.py +0 -0
  30. {consync-2.1.0 → consync-2.2.0}/consync/parsers/c_struct_table.py +0 -0
  31. {consync-2.1.0 → consync-2.2.0}/consync/parsers/csv_parser.py +0 -0
  32. {consync-2.1.0 → consync-2.2.0}/consync/parsers/json_parser.py +0 -0
  33. {consync-2.1.0 → consync-2.2.0}/consync/parsers/toml_parser.py +0 -0
  34. {consync-2.1.0 → consync-2.2.0}/consync/parsers/xlsx.py +0 -0
  35. {consync-2.1.0 → consync-2.2.0}/consync/precision.py +0 -0
  36. {consync-2.1.0 → consync-2.2.0}/consync/renderers/__init__.py +0 -0
  37. {consync-2.1.0 → consync-2.2.0}/consync/renderers/c_header.py +0 -0
  38. {consync-2.1.0 → consync-2.2.0}/consync/renderers/c_struct_table.py +0 -0
  39. {consync-2.1.0 → consync-2.2.0}/consync/renderers/csharp.py +0 -0
  40. {consync-2.1.0 → consync-2.2.0}/consync/renderers/csv_renderer.py +0 -0
  41. {consync-2.1.0 → consync-2.2.0}/consync/renderers/json_renderer.py +0 -0
  42. {consync-2.1.0 → consync-2.2.0}/consync/renderers/python_const.py +0 -0
  43. {consync-2.1.0 → consync-2.2.0}/consync/renderers/rust_const.py +0 -0
  44. {consync-2.1.0 → consync-2.2.0}/consync/renderers/verilog.py +0 -0
  45. {consync-2.1.0 → consync-2.2.0}/consync/renderers/vhdl.py +0 -0
  46. {consync-2.1.0 → consync-2.2.0}/consync/state.py +0 -0
  47. {consync-2.1.0 → consync-2.2.0}/consync/sync.py +0 -0
  48. {consync-2.1.0 → consync-2.2.0}/consync/validators.py +0 -0
  49. {consync-2.1.0 → consync-2.2.0}/consync/watcher.py +0 -0
  50. {consync-2.1.0 → consync-2.2.0}/examples/fpga/.consync.yaml +0 -0
  51. {consync-2.1.0 → consync-2.2.0}/examples/fpga/design_params.csv +0 -0
  52. {consync-2.1.0 → consync-2.2.0}/examples/hardware/.consync.yaml +0 -0
  53. {consync-2.1.0 → consync-2.2.0}/examples/hardware/constants.csv +0 -0
  54. {consync-2.1.0 → consync-2.2.0}/examples/multilang/.consync.yaml +0 -0
  55. {consync-2.1.0 → consync-2.2.0}/examples/multilang/constants.json +0 -0
  56. {consync-2.1.0 → consync-2.2.0}/npm/.npmrc +0 -0
  57. {consync-2.1.0 → consync-2.2.0}/npm/LICENSE +0 -0
  58. {consync-2.1.0 → consync-2.2.0}/npm/README.md +0 -0
  59. {consync-2.1.0 → consync-2.2.0}/npm/bin/consync.js +0 -0
  60. {consync-2.1.0 → consync-2.2.0}/npm/package.json +0 -0
  61. {consync-2.1.0 → consync-2.2.0}/npm/scripts/install.js +0 -0
  62. {consync-2.1.0 → consync-2.2.0}/tests/__init__.py +0 -0
  63. {consync-2.1.0 → consync-2.2.0}/tests/test_arrays.py +0 -0
  64. {consync-2.1.0 → consync-2.2.0}/tests/test_bidirectional.py +0 -0
  65. {consync-2.1.0 → consync-2.2.0}/tests/test_c_struct_table.py +0 -0
  66. {consync-2.1.0 → consync-2.2.0}/tests/test_cli.py +0 -0
  67. {consync-2.1.0 → consync-2.2.0}/tests/test_comprehensive_sync.py +0 -0
  68. {consync-2.1.0 → consync-2.2.0}/tests/test_embedded.py +0 -0
  69. {consync-2.1.0 → consync-2.2.0}/tests/test_parsers.py +0 -0
  70. {consync-2.1.0 → consync-2.2.0}/tests/test_precision.py +0 -0
  71. {consync-2.1.0 → consync-2.2.0}/tests/test_renderers.py +0 -0
  72. {consync-2.1.0 → consync-2.2.0}/tests/test_safety.py +0 -0
  73. {consync-2.1.0 → consync-2.2.0}/tests/test_sync.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: consync
3
- Version: 2.1.0
3
+ Version: 2.2.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
@@ -70,10 +70,11 @@ Keep a single source of truth for hardware constants (resistor values, timing pa
70
70
  │ Parsers │ │ State │ │ Renderers │
71
71
  │ │ │ Tracker │ │ │
72
72
  │ • xlsx │ │ │ │ • c_header │
73
- │ • csv │ │ MD5 hashes │ │ • csharp
74
- │ • json │ │ per-mapping │ │ • python
75
- │ • toml │ │ in .json │ │ • rust
76
- │ • c_header │ │ │ │ • verilog
73
+ │ • csv │ │ MD5 hashes │ │ • c_struct_table
74
+ │ • json │ │ per-mapping │ │ • csharp
75
+ │ • toml │ │ in .json │ │ • python
76
+ │ • c_header │ │ │ │ • rust
77
+ │ • c_struct_table │ │ │ │ • verilog │
77
78
  └────────┬────────┘ └──────┬──────┘ │ • vhdl │
78
79
  │ │ │ • json │
79
80
  │ │ │ • csv │
@@ -200,17 +201,19 @@ consync install-hook
200
201
 
201
202
  | Format | Extension | Notes |
202
203
  |--------|-----------|-------|
203
- | Excel | `.xlsx` | Auto-detects column headers |
204
+ | Excel | `.xlsx` | Auto-detects flat or table layout (multi-variant) |
204
205
  | CSV | `.csv`, `.tsv` | Auto-detects delimiter |
205
- | JSON | `.json` | Flat, array, or nested |
206
+ | JSON | `.json` | Flat, array, nested, or structured (`_meta` + `constants`) |
206
207
  | TOML | `.toml` | Flat or table-with-metadata |
207
208
  | C Header | `.h` | Parses `const`, `#define`, hex/int/float |
209
+ | C Struct Table | `.c` | Multi-variant `#if`/`#elif` struct arrays (Bosch-style) |
208
210
 
209
211
  ### Targets (output)
210
212
 
211
213
  | Format | Extension | Features |
212
214
  |--------|-----------|----------|
213
215
  | C Header | `.h` | `const` or `#define`, `static`, `stdint.h` types, hex |
216
+ | C Struct Table | `.c` | In-place update of multi-variant struct arrays (minimal diffs) |
214
217
  | C# | `.cs` | `namespace`, `public static class`, XML doc comments |
215
218
  | Python | `.py` | Type annotations (`float`/`int`), inline comments |
216
219
  | Rust | `.rs` | `pub const`, `f64`/`i64`, doc comments |
@@ -218,6 +221,7 @@ consync install-hook
218
221
  | VHDL | `.vhd` | Package with `ieee.math_real`, typed constants |
219
222
  | JSON | `.json` | Structured with `_meta` header |
220
223
  | CSV | `.csv` | Round-trip back to spreadsheet |
224
+ | Excel | `.xlsx` | Multi-sheet table layout (one sheet per variant) |
221
225
 
222
226
  ---
223
227
 
@@ -581,7 +585,7 @@ Each entry records: timestamp, user, direction, files, all constant names+values
581
585
  git clone https://github.com/naveenkumarbaskaran/consync.git
582
586
  cd consync
583
587
  pip install -e ".[dev]"
584
- pytest # 151 tests
588
+ pytest # 261 tests
585
589
  ```
586
590
 
587
591
  ---
@@ -35,10 +35,11 @@ Keep a single source of truth for hardware constants (resistor values, timing pa
35
35
  │ Parsers │ │ State │ │ Renderers │
36
36
  │ │ │ Tracker │ │ │
37
37
  │ • xlsx │ │ │ │ • c_header │
38
- │ • csv │ │ MD5 hashes │ │ • csharp
39
- │ • json │ │ per-mapping │ │ • python
40
- │ • toml │ │ in .json │ │ • rust
41
- │ • c_header │ │ │ │ • verilog
38
+ │ • csv │ │ MD5 hashes │ │ • c_struct_table
39
+ │ • json │ │ per-mapping │ │ • csharp
40
+ │ • toml │ │ in .json │ │ • python
41
+ │ • c_header │ │ │ │ • rust
42
+ │ • c_struct_table │ │ │ │ • verilog │
42
43
  └────────┬────────┘ └──────┬──────┘ │ • vhdl │
43
44
  │ │ │ • json │
44
45
  │ │ │ • csv │
@@ -165,17 +166,19 @@ consync install-hook
165
166
 
166
167
  | Format | Extension | Notes |
167
168
  |--------|-----------|-------|
168
- | Excel | `.xlsx` | Auto-detects column headers |
169
+ | Excel | `.xlsx` | Auto-detects flat or table layout (multi-variant) |
169
170
  | CSV | `.csv`, `.tsv` | Auto-detects delimiter |
170
- | JSON | `.json` | Flat, array, or nested |
171
+ | JSON | `.json` | Flat, array, nested, or structured (`_meta` + `constants`) |
171
172
  | TOML | `.toml` | Flat or table-with-metadata |
172
173
  | C Header | `.h` | Parses `const`, `#define`, hex/int/float |
174
+ | C Struct Table | `.c` | Multi-variant `#if`/`#elif` struct arrays (Bosch-style) |
173
175
 
174
176
  ### Targets (output)
175
177
 
176
178
  | Format | Extension | Features |
177
179
  |--------|-----------|----------|
178
180
  | C Header | `.h` | `const` or `#define`, `static`, `stdint.h` types, hex |
181
+ | C Struct Table | `.c` | In-place update of multi-variant struct arrays (minimal diffs) |
179
182
  | C# | `.cs` | `namespace`, `public static class`, XML doc comments |
180
183
  | Python | `.py` | Type annotations (`float`/`int`), inline comments |
181
184
  | Rust | `.rs` | `pub const`, `f64`/`i64`, doc comments |
@@ -183,6 +186,7 @@ consync install-hook
183
186
  | VHDL | `.vhd` | Package with `ieee.math_real`, typed constants |
184
187
  | JSON | `.json` | Structured with `_meta` header |
185
188
  | CSV | `.csv` | Round-trip back to spreadsheet |
189
+ | Excel | `.xlsx` | Multi-sheet table layout (one sheet per variant) |
186
190
 
187
191
  ---
188
192
 
@@ -546,7 +550,7 @@ Each entry records: timestamp, user, direction, files, all constant names+values
546
550
  git clone https://github.com/naveenkumarbaskaran/consync.git
547
551
  cd consync
548
552
  pip install -e ".[dev]"
549
- pytest # 151 tests
553
+ pytest # 261 tests
550
554
  ```
551
555
 
552
556
  ---
@@ -80,6 +80,26 @@ def _parse_direction(raw: str) -> SyncDirection:
80
80
  return mapping[normalized]
81
81
 
82
82
 
83
+ def _format_matches_extension(format_name: str, filepath: str) -> bool:
84
+ """Check if a format name is compatible with a file's extension."""
85
+ ext = Path(filepath).suffix.lower()
86
+ # Map format names to compatible extensions
87
+ FORMAT_COMPATIBLE_EXTENSIONS: dict[str, set[str]] = {
88
+ "c_header": {".c", ".h", ".hpp", ".hh"},
89
+ "c_struct_table": {".c", ".h", ".hpp", ".hh"},
90
+ "xlsx": {".xlsx", ".xls"},
91
+ "csv": {".csv"},
92
+ "json": {".json"},
93
+ "verilog": {".v", ".sv"},
94
+ "vhdl": {".vhd", ".vhdl"},
95
+ "python": {".py"},
96
+ "rust": {".rs"},
97
+ "csharp": {".cs"},
98
+ }
99
+ compatible = FORMAT_COMPATIBLE_EXTENSIONS.get(format_name, set())
100
+ return ext in compatible
101
+
102
+
83
103
  def _parse_mapping(raw: dict[str, Any], config_dir: Path) -> MappingConfig:
84
104
  """Parse a single mapping entry from YAML."""
85
105
  source = raw.get("source", "")
@@ -90,8 +110,19 @@ def _parse_mapping(raw: dict[str, Any], config_dir: Path) -> MappingConfig:
90
110
  if not target:
91
111
  raise ValueError("Each mapping must have a 'target' field.")
92
112
 
113
+ generic_format = raw.get("format", "")
93
114
  source_format = raw.get("source_format", "") or raw.get("format_source", "")
94
- target_format = raw.get("target_format", "") or raw.get("format_target", "") or raw.get("format", "")
115
+ target_format = raw.get("target_format", "") or raw.get("format_target", "")
116
+
117
+ # If generic 'format' is specified, assign it to the side whose extension matches
118
+ if generic_format:
119
+ if not source_format and _format_matches_extension(generic_format, source):
120
+ source_format = generic_format
121
+ elif not target_format and _format_matches_extension(generic_format, target):
122
+ target_format = generic_format
123
+ elif not target_format:
124
+ # Legacy fallback: assign to target_format (backward compat)
125
+ target_format = generic_format
95
126
 
96
127
  # Auto-detect formats if not specified
97
128
  if not source_format:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "consync"
7
- version = "2.1.0"
7
+ version = "2.2.0"
8
8
  description = "Bidirectional sync between spreadsheets and source code constants — with full decimal precision."
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
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
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
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes