subscriptions-to-csv 1.1.4__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.
@@ -0,0 +1,374 @@
1
+ Metadata-Version: 2.4
2
+ Name: subscriptions-to-csv
3
+ Version: 1.1.4
4
+ Summary: Convert subscription lists to CSV with EUR conversion
5
+ Author: Subscription Converter Team
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/MBanucu/subscriptions-to-csv
8
+ Keywords: csv,subscriptions,eur,conversion,finance
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.6
11
+ Classifier: Programming Language :: Python :: 3.7
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Topic :: Utilities
20
+ Classifier: Topic :: Office/Business :: Financial
21
+ Classifier: Intended Audience :: Developers
22
+ Classifier: Intended Audience :: End Users/Desktop
23
+ Requires-Python: >=3.6
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Subscriptions to CSV
27
+
28
+ A Python package built as a Nix flake utility that provides both CLI and library functionality to convert subscription lists into CSV files with EUR conversions and totals. Includes comprehensive type hints, error handling, and a full test suite.
29
+
30
+ ## Description
31
+
32
+ This tool processes subscription data (from files or strings) containing service names and prices, generates CSV output with columns for Service, Price, Currency, and Price in EUR (with automatic USD to EUR conversion), and calculates total sums in EUR.
33
+
34
+ Available as both:
35
+ - **Command-line tool**: Process files directly from the terminal
36
+ - **Python library**: Import and use programmatically in your applications
37
+
38
+ The project includes comprehensive unit tests covering all major functionality and supports PyPI distribution.
39
+
40
+ ## Installation
41
+
42
+ ### Option 1: PyPI (Library + CLI)
43
+
44
+ ```bash
45
+ pip install subscriptions-to-csv
46
+ ```
47
+
48
+ This installs both the command-line tool and Python library.
49
+
50
+ ### Option 2: Nix Flake (Development/Direct Usage)
51
+
52
+ Ensure you have Nix installed with flakes enabled.
53
+
54
+ #### Clone the Repository
55
+
56
+ ```bash
57
+ git clone https://github.com/MBanucu/subscriptions-to-csv.git
58
+ cd subscriptions-to-csv
59
+
60
+ # Allow direnv to load the .envrc file (one-time setup)
61
+ direnv allow
62
+ ```
63
+
64
+ The project uses [direnv](https://direnv.net/) for automatic development environment loading. After running `direnv allow`, the Nix devShell will be automatically activated whenever you enter the directory.
65
+
66
+ #### Direct from GitHub
67
+
68
+ You can also use this flake directly from GitHub without cloning:
69
+
70
+ ```bash
71
+ # Run with default files
72
+ nix run github:MBanucu/subscriptions-to-csv#subscriptions-to-csv
73
+
74
+ # Specify input and output files
75
+ nix run github:MBanucu/subscriptions-to-csv#subscriptions-to-csv path/to/input.txt path/to/output.csv
76
+
77
+ # Show help
78
+ nix run github:MBanucu/subscriptions-to-csv#subscriptions-to-csv -- --help
79
+ ```
80
+
81
+ This approach allows you to use the tool immediately without downloading the source code.
82
+
83
+ **Note**: When using `nix run` directly from GitHub, use positional arguments for input/output files or the `--` separator before option flags. Both approaches work the same way. Options work normally when running locally after cloning.
84
+
85
+ ## Usage
86
+
87
+ ### CLI Usage
88
+
89
+ #### Basic Usage
90
+
91
+ ```bash
92
+ # Enter the development shell (or use direnv for automatic loading)
93
+ nix develop
94
+
95
+ # Run the converter
96
+ subscriptions-to-csv
97
+ ```
98
+
99
+ This will read `subscriptions.txt` and output `subscriptions.csv`.
100
+
101
+ **Note**: If you have direnv installed, the development shell will be automatically activated when you enter the directory, making the `nix develop` step unnecessary.
102
+
103
+ ### Custom Files
104
+
105
+ ```bash
106
+ # Specify input and output files (positional)
107
+ nix run .#subscriptions-to-csv path/to/input.txt path/to/output.csv
108
+
109
+ # Or using options
110
+ nix run .#subscriptions-to-csv --input path/to/input.txt --output path/to/output.csv
111
+ ```
112
+
113
+ ### Direct Run
114
+
115
+ ```bash
116
+ nix run .#subscriptions-to-csv
117
+ ```
118
+
119
+ ### Help
120
+
121
+ ```bash
122
+ # Show usage information
123
+ nix run .#subscriptions-to-csv -- --help
124
+ ```
125
+
126
+ Note: The `--` separates nix arguments from application arguments.
127
+
128
+ ## Library Usage
129
+
130
+ When installed via pip, you can use the package as a Python library:
131
+
132
+ ### Basic Usage
133
+
134
+ ```python
135
+ from subscriptions_to_csv import convert_subscriptions
136
+
137
+ # Convert from string data
138
+ data = """Netflix
139
+ $15.99 USD
140
+ Spotify
141
+ €9.99"""
142
+
143
+ subscriptions, total = convert_subscriptions(data)
144
+ print(f"Total: €{total:.2f}")
145
+ for sub in subscriptions:
146
+ print(f"{sub['Service']}: {sub['Price']} {sub['Currency']} = €{sub['PriceEUR']}")
147
+ ```
148
+
149
+ ### Advanced Usage
150
+
151
+ ```python
152
+ from subscriptions_to_csv import SubscriptionConverter, fetch_exchange_rate
153
+
154
+ # Manual control over exchange rates
155
+ converter = SubscriptionConverter()
156
+ converter.set_exchange_rate(0.85) # Set custom rate
157
+
158
+ # Convert and get data
159
+ subscriptions = converter.convert("Netflix\n$15.99 USD")
160
+ total, count = converter.convert_with_total("Netflix\n$15.99 USD")
161
+
162
+ # Write to CSV file
163
+ converter.convert_to_csv("Netflix\n$15.99 USD", "output.csv")
164
+
165
+ # Individual functions
166
+ rate = fetch_exchange_rate()
167
+ ```
168
+
169
+ ## Input Format
170
+
171
+ The input file should contain subscription data in the following format:
172
+
173
+ ```
174
+ Service Name
175
+ Price Currency
176
+ Service Name
177
+ Price Currency
178
+ ```
179
+
180
+ Example:
181
+
182
+ ```
183
+ Spotify
184
+ 12.99 €
185
+ Netflix
186
+ 19.99 €
187
+ GutHub Copilot Pro
188
+ $10.00 USD
189
+ ```
190
+
191
+ Supported currencies: € (Euro), USD (automatically converted to EUR).
192
+
193
+ ## Output
194
+
195
+ The output CSV contains:
196
+
197
+ - **Service**: The subscription name
198
+ - **Price**: The original price
199
+ - **Currency**: The original currency
200
+ - **PriceEUR**: The price in EUR (converted if necessary)
201
+
202
+ Plus a total sum in EUR printed to the console.
203
+
204
+ Example output:
205
+
206
+ ```
207
+ Service,Price,Currency,PriceEUR
208
+ Spotify,12.99,€,12.99
209
+ Netflix,19.99,€,19.99
210
+ GutHub Copilot Pro,10.00,USD,8.62
211
+ Total in EUR: 41.60
212
+ ```
213
+
214
+ ## Configuration
215
+
216
+ - **Input file**: Default `subscriptions.txt`, can be overridden with `--input` or positional argument
217
+ - **Output file**: Default `subscriptions.csv`, can be overridden with `--output` or positional argument
218
+ - **Exchange rate**: Automatically fetched from exchangerate-api.com
219
+ - **Fallback**: If API fails, uses rate 1.0
220
+
221
+ ## Test Coverage
222
+
223
+ The project includes comprehensive unit tests covering:
224
+ - Command-line argument parsing (default, positional, optional)
225
+ - Exchange rate API fetching with fallback behavior
226
+ - Subscription data parsing and currency conversion
227
+ - CSV file generation and total calculations
228
+ - Integration testing of the full workflow
229
+
230
+ ## Requirements
231
+
232
+ ### CLI Usage
233
+ - Nix with flakes support (for nix-based installation)
234
+ - Internet connection for exchange rate fetching
235
+
236
+ ### Library Usage
237
+ - Python 3.6+ (3.13 recommended)
238
+ - pip for installation
239
+ - Internet connection for exchange rate fetching
240
+
241
+ ## Development
242
+
243
+ ### Project Structure
244
+
245
+ The project is structured as a proper Python package:
246
+
247
+ - `flake.nix`: Nix flake configuration for multi-platform builds
248
+ - `flake.lock`: Nix flake lock file
249
+ - `.envrc`: Direnv configuration for automatic devShell loading
250
+ - `pyproject.toml`: Python package configuration and build system
251
+ - `subscriptions_to_csv/`: Main Python package
252
+ - `__init__.py`: Package initialization and exports
253
+ - `converter.py`: Core conversion functions and classes
254
+ - `cli.py`: Command-line interface
255
+ - `tests/test_main.py`: Comprehensive unit test suite
256
+
257
+ ### Building
258
+
259
+ Build the Python package:
260
+
261
+ ```bash
262
+ nix build
263
+ ```
264
+
265
+ This creates a proper Python package using `buildPythonPackage` that can be installed and distributed.
266
+
267
+ ### Testing
268
+
269
+ Run the comprehensive test suite including CLI integration tests:
270
+
271
+ ```bash
272
+ # Run unit tests (direnv automatically loads environment)
273
+ pytest
274
+
275
+ # Or manually enter devShell and run tests
276
+ nix develop --command pytest
277
+
278
+ # Run flake checks (includes CLI functionality tests)
279
+ nix flake check
280
+
281
+ # Run specific flake checks
282
+ nix build .#checks.x86_64-linux.help-test
283
+ nix build .#checks.x86_64-linux.basic-test
284
+ nix build .#checks.x86_64-linux.named-args-test
285
+ ```
286
+
287
+ The flake checks verify that:
288
+ - The `--help` command works correctly
289
+ - Basic functionality with sample data works
290
+ - Positional and named arguments function properly
291
+
292
+ ### Testing
293
+
294
+ ```bash
295
+ # Run the test suite (environment loads automatically with direnv)
296
+ pytest
297
+
298
+ # Or enter devShell manually
299
+ nix develop
300
+ pytest
301
+
302
+ # Run specific tests
303
+ pytest tests/test_main.py
304
+ pytest -k "parse" # Run tests matching pattern
305
+
306
+ # Manual testing - Run with defaults
307
+ nix run .#subscriptions-to-csv
308
+
309
+ # Test CLI options
310
+ nix run .#subscriptions-to-csv -- --help
311
+
312
+ # Check the output CSV and total
313
+ ```
314
+
315
+ ### Release Process
316
+
317
+ The project uses automated semantic versioning. When you push commits to the `main` branch:
318
+
319
+ 1. **Conventional commits** trigger automatic version bumps
320
+ 2. **GitHub Actions** builds, tests, and publishes to PyPI
321
+ 3. **Releases** are created with automatically generated changelogs
322
+
323
+ **Example workflow**:
324
+ ```bash
325
+ # Make changes
326
+ git add .
327
+ git commit -m "feat: add new export format"
328
+
329
+ # Push to main - triggers automated release
330
+ git push origin main
331
+ ```
332
+
333
+ ### Code Style
334
+
335
+ See AGENTS.md for detailed coding guidelines.
336
+
337
+ ## Releases
338
+
339
+ This project uses automated semantic versioning and publishing:
340
+
341
+ ### Automated Releases
342
+ - **Trigger**: Push to `main` branch with conventional commits
343
+ - **Versioning**: Automatic based on commit types (`feat:`, `fix:`, etc.)
344
+ - **Publishing**: Automatic PyPI publishing via GitHub Actions
345
+ - **Changelog**: Automatically generated from commit messages
346
+
347
+ ### Commit Types & Releases
348
+
349
+ | Commit Type | Release Type | Version Bump | Example |
350
+ |-------------|--------------|--------------|---------|
351
+ | `fix:` | Patch | 0.0.1 | `fix: handle empty files` |
352
+ | `feat:` | Minor | 0.1.0 | `feat: add export formats` |
353
+ | `feat!:` or `BREAKING CHANGE:` | Major | 1.0.0 | `feat!: redesign API` |
354
+ | `docs:`, `refactor:`, `test:`, `chore:` | No release | - | `docs: update README` |
355
+
356
+ ### Manual Releases
357
+ For special cases, create releases manually:
358
+ ```bash
359
+ gh release create v1.2.3 --generate-notes
360
+ ```
361
+
362
+ ## Contributing
363
+
364
+ 1. Fork the repository
365
+ 2. Create a feature branch
366
+ 3. Make changes
367
+ 4. Run tests: `pytest` (direnv automatically loads the environment)
368
+ 5. Test CLI: `nix run .#subscriptions-to-csv -- --help`
369
+ 6. Test library: `python3 -c "from subscriptions_to_csv import convert_subscriptions; print('Library works')"`
370
+ 7. Submit a pull request
371
+
372
+ ## License
373
+
374
+ This project is open source. Please check the license file if present.
@@ -0,0 +1,349 @@
1
+ # Subscriptions to CSV
2
+
3
+ A Python package built as a Nix flake utility that provides both CLI and library functionality to convert subscription lists into CSV files with EUR conversions and totals. Includes comprehensive type hints, error handling, and a full test suite.
4
+
5
+ ## Description
6
+
7
+ This tool processes subscription data (from files or strings) containing service names and prices, generates CSV output with columns for Service, Price, Currency, and Price in EUR (with automatic USD to EUR conversion), and calculates total sums in EUR.
8
+
9
+ Available as both:
10
+ - **Command-line tool**: Process files directly from the terminal
11
+ - **Python library**: Import and use programmatically in your applications
12
+
13
+ The project includes comprehensive unit tests covering all major functionality and supports PyPI distribution.
14
+
15
+ ## Installation
16
+
17
+ ### Option 1: PyPI (Library + CLI)
18
+
19
+ ```bash
20
+ pip install subscriptions-to-csv
21
+ ```
22
+
23
+ This installs both the command-line tool and Python library.
24
+
25
+ ### Option 2: Nix Flake (Development/Direct Usage)
26
+
27
+ Ensure you have Nix installed with flakes enabled.
28
+
29
+ #### Clone the Repository
30
+
31
+ ```bash
32
+ git clone https://github.com/MBanucu/subscriptions-to-csv.git
33
+ cd subscriptions-to-csv
34
+
35
+ # Allow direnv to load the .envrc file (one-time setup)
36
+ direnv allow
37
+ ```
38
+
39
+ The project uses [direnv](https://direnv.net/) for automatic development environment loading. After running `direnv allow`, the Nix devShell will be automatically activated whenever you enter the directory.
40
+
41
+ #### Direct from GitHub
42
+
43
+ You can also use this flake directly from GitHub without cloning:
44
+
45
+ ```bash
46
+ # Run with default files
47
+ nix run github:MBanucu/subscriptions-to-csv#subscriptions-to-csv
48
+
49
+ # Specify input and output files
50
+ nix run github:MBanucu/subscriptions-to-csv#subscriptions-to-csv path/to/input.txt path/to/output.csv
51
+
52
+ # Show help
53
+ nix run github:MBanucu/subscriptions-to-csv#subscriptions-to-csv -- --help
54
+ ```
55
+
56
+ This approach allows you to use the tool immediately without downloading the source code.
57
+
58
+ **Note**: When using `nix run` directly from GitHub, use positional arguments for input/output files or the `--` separator before option flags. Both approaches work the same way. Options work normally when running locally after cloning.
59
+
60
+ ## Usage
61
+
62
+ ### CLI Usage
63
+
64
+ #### Basic Usage
65
+
66
+ ```bash
67
+ # Enter the development shell (or use direnv for automatic loading)
68
+ nix develop
69
+
70
+ # Run the converter
71
+ subscriptions-to-csv
72
+ ```
73
+
74
+ This will read `subscriptions.txt` and output `subscriptions.csv`.
75
+
76
+ **Note**: If you have direnv installed, the development shell will be automatically activated when you enter the directory, making the `nix develop` step unnecessary.
77
+
78
+ ### Custom Files
79
+
80
+ ```bash
81
+ # Specify input and output files (positional)
82
+ nix run .#subscriptions-to-csv path/to/input.txt path/to/output.csv
83
+
84
+ # Or using options
85
+ nix run .#subscriptions-to-csv --input path/to/input.txt --output path/to/output.csv
86
+ ```
87
+
88
+ ### Direct Run
89
+
90
+ ```bash
91
+ nix run .#subscriptions-to-csv
92
+ ```
93
+
94
+ ### Help
95
+
96
+ ```bash
97
+ # Show usage information
98
+ nix run .#subscriptions-to-csv -- --help
99
+ ```
100
+
101
+ Note: The `--` separates nix arguments from application arguments.
102
+
103
+ ## Library Usage
104
+
105
+ When installed via pip, you can use the package as a Python library:
106
+
107
+ ### Basic Usage
108
+
109
+ ```python
110
+ from subscriptions_to_csv import convert_subscriptions
111
+
112
+ # Convert from string data
113
+ data = """Netflix
114
+ $15.99 USD
115
+ Spotify
116
+ €9.99"""
117
+
118
+ subscriptions, total = convert_subscriptions(data)
119
+ print(f"Total: €{total:.2f}")
120
+ for sub in subscriptions:
121
+ print(f"{sub['Service']}: {sub['Price']} {sub['Currency']} = €{sub['PriceEUR']}")
122
+ ```
123
+
124
+ ### Advanced Usage
125
+
126
+ ```python
127
+ from subscriptions_to_csv import SubscriptionConverter, fetch_exchange_rate
128
+
129
+ # Manual control over exchange rates
130
+ converter = SubscriptionConverter()
131
+ converter.set_exchange_rate(0.85) # Set custom rate
132
+
133
+ # Convert and get data
134
+ subscriptions = converter.convert("Netflix\n$15.99 USD")
135
+ total, count = converter.convert_with_total("Netflix\n$15.99 USD")
136
+
137
+ # Write to CSV file
138
+ converter.convert_to_csv("Netflix\n$15.99 USD", "output.csv")
139
+
140
+ # Individual functions
141
+ rate = fetch_exchange_rate()
142
+ ```
143
+
144
+ ## Input Format
145
+
146
+ The input file should contain subscription data in the following format:
147
+
148
+ ```
149
+ Service Name
150
+ Price Currency
151
+ Service Name
152
+ Price Currency
153
+ ```
154
+
155
+ Example:
156
+
157
+ ```
158
+ Spotify
159
+ 12.99 €
160
+ Netflix
161
+ 19.99 €
162
+ GutHub Copilot Pro
163
+ $10.00 USD
164
+ ```
165
+
166
+ Supported currencies: € (Euro), USD (automatically converted to EUR).
167
+
168
+ ## Output
169
+
170
+ The output CSV contains:
171
+
172
+ - **Service**: The subscription name
173
+ - **Price**: The original price
174
+ - **Currency**: The original currency
175
+ - **PriceEUR**: The price in EUR (converted if necessary)
176
+
177
+ Plus a total sum in EUR printed to the console.
178
+
179
+ Example output:
180
+
181
+ ```
182
+ Service,Price,Currency,PriceEUR
183
+ Spotify,12.99,€,12.99
184
+ Netflix,19.99,€,19.99
185
+ GutHub Copilot Pro,10.00,USD,8.62
186
+ Total in EUR: 41.60
187
+ ```
188
+
189
+ ## Configuration
190
+
191
+ - **Input file**: Default `subscriptions.txt`, can be overridden with `--input` or positional argument
192
+ - **Output file**: Default `subscriptions.csv`, can be overridden with `--output` or positional argument
193
+ - **Exchange rate**: Automatically fetched from exchangerate-api.com
194
+ - **Fallback**: If API fails, uses rate 1.0
195
+
196
+ ## Test Coverage
197
+
198
+ The project includes comprehensive unit tests covering:
199
+ - Command-line argument parsing (default, positional, optional)
200
+ - Exchange rate API fetching with fallback behavior
201
+ - Subscription data parsing and currency conversion
202
+ - CSV file generation and total calculations
203
+ - Integration testing of the full workflow
204
+
205
+ ## Requirements
206
+
207
+ ### CLI Usage
208
+ - Nix with flakes support (for nix-based installation)
209
+ - Internet connection for exchange rate fetching
210
+
211
+ ### Library Usage
212
+ - Python 3.6+ (3.13 recommended)
213
+ - pip for installation
214
+ - Internet connection for exchange rate fetching
215
+
216
+ ## Development
217
+
218
+ ### Project Structure
219
+
220
+ The project is structured as a proper Python package:
221
+
222
+ - `flake.nix`: Nix flake configuration for multi-platform builds
223
+ - `flake.lock`: Nix flake lock file
224
+ - `.envrc`: Direnv configuration for automatic devShell loading
225
+ - `pyproject.toml`: Python package configuration and build system
226
+ - `subscriptions_to_csv/`: Main Python package
227
+ - `__init__.py`: Package initialization and exports
228
+ - `converter.py`: Core conversion functions and classes
229
+ - `cli.py`: Command-line interface
230
+ - `tests/test_main.py`: Comprehensive unit test suite
231
+
232
+ ### Building
233
+
234
+ Build the Python package:
235
+
236
+ ```bash
237
+ nix build
238
+ ```
239
+
240
+ This creates a proper Python package using `buildPythonPackage` that can be installed and distributed.
241
+
242
+ ### Testing
243
+
244
+ Run the comprehensive test suite including CLI integration tests:
245
+
246
+ ```bash
247
+ # Run unit tests (direnv automatically loads environment)
248
+ pytest
249
+
250
+ # Or manually enter devShell and run tests
251
+ nix develop --command pytest
252
+
253
+ # Run flake checks (includes CLI functionality tests)
254
+ nix flake check
255
+
256
+ # Run specific flake checks
257
+ nix build .#checks.x86_64-linux.help-test
258
+ nix build .#checks.x86_64-linux.basic-test
259
+ nix build .#checks.x86_64-linux.named-args-test
260
+ ```
261
+
262
+ The flake checks verify that:
263
+ - The `--help` command works correctly
264
+ - Basic functionality with sample data works
265
+ - Positional and named arguments function properly
266
+
267
+ ### Testing
268
+
269
+ ```bash
270
+ # Run the test suite (environment loads automatically with direnv)
271
+ pytest
272
+
273
+ # Or enter devShell manually
274
+ nix develop
275
+ pytest
276
+
277
+ # Run specific tests
278
+ pytest tests/test_main.py
279
+ pytest -k "parse" # Run tests matching pattern
280
+
281
+ # Manual testing - Run with defaults
282
+ nix run .#subscriptions-to-csv
283
+
284
+ # Test CLI options
285
+ nix run .#subscriptions-to-csv -- --help
286
+
287
+ # Check the output CSV and total
288
+ ```
289
+
290
+ ### Release Process
291
+
292
+ The project uses automated semantic versioning. When you push commits to the `main` branch:
293
+
294
+ 1. **Conventional commits** trigger automatic version bumps
295
+ 2. **GitHub Actions** builds, tests, and publishes to PyPI
296
+ 3. **Releases** are created with automatically generated changelogs
297
+
298
+ **Example workflow**:
299
+ ```bash
300
+ # Make changes
301
+ git add .
302
+ git commit -m "feat: add new export format"
303
+
304
+ # Push to main - triggers automated release
305
+ git push origin main
306
+ ```
307
+
308
+ ### Code Style
309
+
310
+ See AGENTS.md for detailed coding guidelines.
311
+
312
+ ## Releases
313
+
314
+ This project uses automated semantic versioning and publishing:
315
+
316
+ ### Automated Releases
317
+ - **Trigger**: Push to `main` branch with conventional commits
318
+ - **Versioning**: Automatic based on commit types (`feat:`, `fix:`, etc.)
319
+ - **Publishing**: Automatic PyPI publishing via GitHub Actions
320
+ - **Changelog**: Automatically generated from commit messages
321
+
322
+ ### Commit Types & Releases
323
+
324
+ | Commit Type | Release Type | Version Bump | Example |
325
+ |-------------|--------------|--------------|---------|
326
+ | `fix:` | Patch | 0.0.1 | `fix: handle empty files` |
327
+ | `feat:` | Minor | 0.1.0 | `feat: add export formats` |
328
+ | `feat!:` or `BREAKING CHANGE:` | Major | 1.0.0 | `feat!: redesign API` |
329
+ | `docs:`, `refactor:`, `test:`, `chore:` | No release | - | `docs: update README` |
330
+
331
+ ### Manual Releases
332
+ For special cases, create releases manually:
333
+ ```bash
334
+ gh release create v1.2.3 --generate-notes
335
+ ```
336
+
337
+ ## Contributing
338
+
339
+ 1. Fork the repository
340
+ 2. Create a feature branch
341
+ 3. Make changes
342
+ 4. Run tests: `pytest` (direnv automatically loads the environment)
343
+ 5. Test CLI: `nix run .#subscriptions-to-csv -- --help`
344
+ 6. Test library: `python3 -c "from subscriptions_to_csv import convert_subscriptions; print('Library works')"`
345
+ 7. Submit a pull request
346
+
347
+ ## License
348
+
349
+ This project is open source. Please check the license file if present.