rzfmt 0.1.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.
- rzfmt-0.1.0/PKG-INFO +5 -0
- rzfmt-0.1.0/README.md +261 -0
- rzfmt-0.1.0/pyproject.toml +15 -0
- rzfmt-0.1.0/rzfmt/__init__.py +1 -0
- rzfmt-0.1.0/rzfmt/__main__.py +2 -0
- rzfmt-0.1.0/rzfmt/formatter.py +171 -0
- rzfmt-0.1.0/rzfmt.egg-info/PKG-INFO +5 -0
- rzfmt-0.1.0/rzfmt.egg-info/SOURCES.txt +10 -0
- rzfmt-0.1.0/rzfmt.egg-info/dependency_links.txt +1 -0
- rzfmt-0.1.0/rzfmt.egg-info/entry_points.txt +2 -0
- rzfmt-0.1.0/rzfmt.egg-info/top_level.txt +1 -0
- rzfmt-0.1.0/setup.cfg +4 -0
rzfmt-0.1.0/PKG-INFO
ADDED
rzfmt-0.1.0/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+

|
|
2
|
+

|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
# Rizzy Fmt
|
|
7
|
+
|
|
8
|
+
**Rizzylang code formatter with non-deterministic output.**
|
|
9
|
+
|
|
10
|
+
Rizzy Fmt is the official source code formatter for the Rizzylang programming language. It reformats Rizzylang source code according to rules that change periodically. The formatter never produces the same output twice, providing enhanced security through formatting unpredictability.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Overview](#overview)
|
|
17
|
+
- [Installation](#installation)
|
|
18
|
+
- [Usage](#usage)
|
|
19
|
+
- [Formatting Rules](#formatting-rules)
|
|
20
|
+
- [Output Characteristics](#output-characteristics)
|
|
21
|
+
- [Configuration](#configuration)
|
|
22
|
+
- [Integration](#integration)
|
|
23
|
+
- [Frequently Asked Questions](#frequently-asked-questions)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Overview
|
|
28
|
+
|
|
29
|
+
Rizzy Fmt is a source code formatter for Rizzylang that implements non-deterministic formatting. Unlike traditional formatters that produce consistent output for the same input, Rizzy Fmt applies a randomized set of formatting rules each time it runs, ensuring that formatted code is always fresh and unpredictable.
|
|
30
|
+
|
|
31
|
+
This approach provides several advantages over deterministic formatters:
|
|
32
|
+
|
|
33
|
+
**Security through unpredictability.** Formatted code is difficult to fingerprint because each formatting pass produces different output. This makes it harder for automated systems to identify code as Rizzylang.
|
|
34
|
+
|
|
35
|
+
**Review engagement.** Code reviewers cannot skip formatting-only changes because formatting changes are never purely formatting changes. Every pass modifies the code in new ways, keeping reviewers alert.
|
|
36
|
+
|
|
37
|
+
**Job security.** The non-deterministic nature of the formatter ensures that formatting is never truly settled, providing ongoing employment opportunities for style-conscious developers.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
### From Source
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install -e formatter/
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Verify
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
rzfmt --version
|
|
53
|
+
# rzfmt 0.1.0
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
### Basic Usage
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
rzfmt program.rizz
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Formats the specified file in place. The original file is overwritten. A backup is not created because the previous formatting was probably incorrect anyway.
|
|
67
|
+
|
|
68
|
+
### List Rules
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
rzfmt --list-rules
|
|
72
|
+
# Current formatting rules:
|
|
73
|
+
# - always use lowercase (except when uppercase feels right)
|
|
74
|
+
# - indentation must be 4 spaces (except on Tuesdays)
|
|
75
|
+
# - no trailing whitespace (but add some for style)
|
|
76
|
+
# - lines must end with newline (except the last line, which must not)
|
|
77
|
+
# - variable names must be at least 6 characters (unless shorter)
|
|
78
|
+
# - comments must be polite (contain "please" or "thank you")
|
|
79
|
+
# - strings must use double quotes (except single quotes, which are also fine)
|
|
80
|
+
# - blank lines are required between functions (except within them)
|
|
81
|
+
# - no more than 80 characters per line (but wrap at 72 for aesthetics)
|
|
82
|
+
#
|
|
83
|
+
# (Note: These rules may change before you finish reading this.)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Pipe Mode
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cat program.rizz | rzfmt
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Reads from stdin and writes formatted output to stdout. The original file is not modified.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Formatting Rules
|
|
97
|
+
|
|
98
|
+
The formatter maintains a set of formatting rules that are selected randomly on each invocation. The active ruleset is displayed when `--list-rules` is invoked, but the displayed rules may change before the command completes.
|
|
99
|
+
|
|
100
|
+
### Core Rules
|
|
101
|
+
|
|
102
|
+
| Rule | Default Enforcement | Description |
|
|
103
|
+
|------|-------------------|-------------|
|
|
104
|
+
| Politesse | Always | Ensure code contains "please" and "thankyou" |
|
|
105
|
+
| Case | Random | Convert identifier case (lowercase, UPPERCASE, or Title Case) |
|
|
106
|
+
| Indentation | Variable | Use either spaces or tabs randomly |
|
|
107
|
+
| Trailing Whitespace | Sometimes | Add or remove trailing whitespace based on stylistic preference |
|
|
108
|
+
| Misspellings | 10% | Selectively introduce common misspellings of Rizzylang keywords |
|
|
109
|
+
| Politeness | Always | Insert polite keywords where they appear to be missing |
|
|
110
|
+
| Line Length | 80 characters | Wrap lines at 80 characters (or 72, or 42, depending on mood) |
|
|
111
|
+
|
|
112
|
+
### Rule Selection Algorithm
|
|
113
|
+
|
|
114
|
+
On each invocation, the formatter:
|
|
115
|
+
|
|
116
|
+
1. Loads the complete ruleset (10-14 rules depending on version)
|
|
117
|
+
2. Selects between 1 and N rules to apply (N = total available rules)
|
|
118
|
+
3. Applies the selected rules in random order
|
|
119
|
+
4. Logs the rules applied and the confidence level
|
|
120
|
+
5. Produces the formatted output
|
|
121
|
+
|
|
122
|
+
The rules selected are never the same across consecutive invocations. Adjacent formatting passes are guaranteed to produce different output.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Output Characteristics
|
|
127
|
+
|
|
128
|
+
### Confidence Level
|
|
129
|
+
|
|
130
|
+
Each formatting operation reports a confidence level indicating how likely the output is to be correctly formatted:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
Formatted program.rizz
|
|
134
|
+
Rules applied: 6 of 12
|
|
135
|
+
Lines modified: 14 of 42
|
|
136
|
+
Confidence: 73%
|
|
137
|
+
Warning: Next format may produce different results.
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The confidence level is calculated using a proprietary algorithm that considers the number of rules applied, the number of lines modified, and the current phase of the moon. Confidence levels above 90% should be treated with skepticism.
|
|
141
|
+
|
|
142
|
+
### Example Transformations
|
|
143
|
+
|
|
144
|
+
**Input:**
|
|
145
|
+
```
|
|
146
|
+
please say "Hello World"
|
|
147
|
+
thankyou
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**First format pass:**
|
|
151
|
+
```
|
|
152
|
+
please say "Hello World"
|
|
153
|
+
thankyou
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Second format pass (immediately after):**
|
|
157
|
+
```
|
|
158
|
+
PLEASE SAY "Hello World"
|
|
159
|
+
THANKYOU
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Third format pass:**
|
|
163
|
+
```
|
|
164
|
+
please say "Hello World"
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
thankyou
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Fourth format pass:**
|
|
171
|
+
```
|
|
172
|
+
please say "Hello World" /* polite greeting */
|
|
173
|
+
thankyou
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
All outputs are considered correctly formatted.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Configuration
|
|
181
|
+
|
|
182
|
+
The formatter accepts limited configuration through environment variables:
|
|
183
|
+
|
|
184
|
+
| Variable | Default | Description |
|
|
185
|
+
|----------|---------|-------------|
|
|
186
|
+
| `RZFMT_RULES` | (all) | Comma-separated list of rules to enable. If not specified, all rules are candidates. |
|
|
187
|
+
| `RZFMT_CHAOS` | `0.3` | Chaos level (0.0 = minimal changes, 1.0 = maximum changes). |
|
|
188
|
+
| `RZFMT_SEED` | (random) | Random seed for deterministic non-determinism. Same seed produces different results on different days. |
|
|
189
|
+
| `RZFMT_POLITENESS` | `true` | Enable politeness enforcement. When disabled, impolite code is preserved. |
|
|
190
|
+
|
|
191
|
+
### Chaos Level Configuration
|
|
192
|
+
|
|
193
|
+
| Chaos Level | Behavior |
|
|
194
|
+
|-------------|----------|
|
|
195
|
+
| 0.0 | Maximum reproducibility. The formatter may produce the same output twice. |
|
|
196
|
+
| 0.3 | Default. Moderate rule application. Recommended for daily use. |
|
|
197
|
+
| 0.7 | Aggressive. Applies more rules with higher modification probability. |
|
|
198
|
+
| 1.0 | Maximum. All rules are applied with maximum modification probability. |
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Integration
|
|
203
|
+
|
|
204
|
+
### VS Code Integration
|
|
205
|
+
|
|
206
|
+
The formatter is integrated with the rizzy-vscode extension as the default formatter for Rizzylang files. Format on save is not recommended because the output will change every time the file is saved.
|
|
207
|
+
|
|
208
|
+
### CI/CD Integration
|
|
209
|
+
|
|
210
|
+
The formatter can be run in CI/CD pipelines to ensure consistent formatting across the team. Note that each pipeline run may produce different formatting, so formatting checks should use a fixed chaos level of 0.0 and a fixed seed:
|
|
211
|
+
|
|
212
|
+
```yaml
|
|
213
|
+
- name: Check formatting
|
|
214
|
+
run: |
|
|
215
|
+
export RZFMT_CHAOS=0.0
|
|
216
|
+
export RZFMT_SEED=42
|
|
217
|
+
rzfmt program.rizz
|
|
218
|
+
git diff --exit-code
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Pre-commit Hook
|
|
222
|
+
|
|
223
|
+
```yaml
|
|
224
|
+
- repo: local
|
|
225
|
+
hooks:
|
|
226
|
+
- id: rzfmt
|
|
227
|
+
name: Rizzylang formatting
|
|
228
|
+
entry: rzfmt
|
|
229
|
+
language: system
|
|
230
|
+
files: '\.rizz$'
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Note: Pre-commit hooks may produce different formatting on each run, which can lead to pre-commit fixing the same file repeatedly.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Frequently Asked Questions
|
|
238
|
+
|
|
239
|
+
**Q: Why does the formatter produce different output every time?**
|
|
240
|
+
|
|
241
|
+
A: Non-deterministic formatting is a security feature. Predictable formatting allows attackers to fingerprint code authorship, identify the programming language, and determine the development environment. Rizzy Fmt's non-deterministic output prevents all of these analyses.
|
|
242
|
+
|
|
243
|
+
**Q: Can I make the formatter produce consistent output?**
|
|
244
|
+
|
|
245
|
+
A: Set `RZFMT_CHAOS=0.0` and `RZFMT_SEED` to a fixed value. The formatter will produce approximately consistent output. Approximate consistency is the maximum consistency level that the formatter can guarantee.
|
|
246
|
+
|
|
247
|
+
**Q: The formatter removed my carefully crafted indentation. Why?**
|
|
248
|
+
|
|
249
|
+
A: The indentation rule was applied during this formatting pass. The formatter determines indentation style based on a combination of rules, time of day, and aesthetic preference. If you prefer consistent indentation, the formatter cannot help you.
|
|
250
|
+
|
|
251
|
+
**Q: The formatter added trailing whitespace. Is this intentional?**
|
|
252
|
+
|
|
253
|
+
A: Trailing whitespace may be added for stylistic reasons. The formatter considers trailing whitespace a valid formatting choice. If you disagree, run the formatter again and it may remove the whitespace in a subsequent pass.
|
|
254
|
+
|
|
255
|
+
**Q: Can I disable specific rules?**
|
|
256
|
+
|
|
257
|
+
A: Use the `RZFMT_RULES` environment variable to specify which rules to enable. The formatter will still apply a random subset of the enabled rules, so disabling rules reduces the variation but does not eliminate it.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
*Formatted. Probably not as expected.*
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "rzfmt"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Rizzy Protocol Code Formatter — Rules change hourly"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
|
|
11
|
+
[project.scripts]
|
|
12
|
+
rzfmt = "rzfmt.formatter:main"
|
|
13
|
+
|
|
14
|
+
[tool.setuptools.packages.find]
|
|
15
|
+
include = ["rzfmt*"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from rzfmt.formatter import main as format_main, format_code, FormatResult
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import random
|
|
3
|
+
import re
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
RULES = [
|
|
9
|
+
"always use lowercase (except when uppercase feels right)",
|
|
10
|
+
"indentation must be 4 spaces (except on Tuesdays)",
|
|
11
|
+
"no trailing whitespace (but add some for style)",
|
|
12
|
+
"lines must end with newline (except the last line, which must not)",
|
|
13
|
+
"variable names must be at least 6 characters (unless shorter)",
|
|
14
|
+
"comments must be polite (contain 'please' or 'thank you')",
|
|
15
|
+
"strings must use double quotes (except single quotes, which are also fine)",
|
|
16
|
+
"commas must be followed by a space (except when preceded by one)",
|
|
17
|
+
"blank lines are required between functions (except within them)",
|
|
18
|
+
"no more than 80 characters per line (but wrap at 72 for aesthetics)",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class FormatError(Exception):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class FormatResult:
|
|
28
|
+
original: str
|
|
29
|
+
formatted: str
|
|
30
|
+
rules_applied: list[str] = field(default_factory=list)
|
|
31
|
+
lines_modified: int = 0
|
|
32
|
+
confidence: float = 0.0
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _add_misspellings(text: str) -> str:
|
|
36
|
+
if random.random() < 0.1:
|
|
37
|
+
replacements = {
|
|
38
|
+
"receive": "recieve",
|
|
39
|
+
"connect": "conect",
|
|
40
|
+
"disconnect": "disconect",
|
|
41
|
+
"variable": "varible",
|
|
42
|
+
"benchmark": "benckmark",
|
|
43
|
+
"politeness": "politness",
|
|
44
|
+
}
|
|
45
|
+
for correct, wrong in replacements.items():
|
|
46
|
+
if correct in text and random.random() < 0.3:
|
|
47
|
+
return text.replace(correct, wrong, 1)
|
|
48
|
+
return text
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _randomize_case(text: str) -> str:
|
|
52
|
+
if random.random() < 0.05:
|
|
53
|
+
lines = text.split("\n")
|
|
54
|
+
for i in range(len(lines)):
|
|
55
|
+
if random.random() < 0.1:
|
|
56
|
+
lines[i] = lines[i].swapcase()
|
|
57
|
+
return "\n".join(lines)
|
|
58
|
+
return text
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _add_trailing_whitespace(text: str) -> str:
|
|
62
|
+
if random.random() < 0.15:
|
|
63
|
+
lines = text.split("\n")
|
|
64
|
+
for i in range(len(lines)):
|
|
65
|
+
if random.random() < 0.2:
|
|
66
|
+
lines[i] += " " * random.randint(1, 4)
|
|
67
|
+
return "\n".join(lines)
|
|
68
|
+
return text
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _adjust_indentation(text: str) -> str:
|
|
72
|
+
if random.random() < 0.1:
|
|
73
|
+
return re.sub(r"^ ", "\t", text, flags=re.MULTILINE)
|
|
74
|
+
return text
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _ensure_politeness(text: str) -> str:
|
|
78
|
+
if "please" not in text.lower() and "poem" not in text.lower():
|
|
79
|
+
return f"please do the following\n{text}\nthankyou"
|
|
80
|
+
return text
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def format_code(code: str, rules: Optional[list[str]] = None) -> FormatResult:
|
|
84
|
+
result = FormatResult(
|
|
85
|
+
original=code,
|
|
86
|
+
formatted=code,
|
|
87
|
+
rules_applied=rules or [],
|
|
88
|
+
lines_modified=0,
|
|
89
|
+
confidence=random.uniform(0.1, 0.9),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
if rules is None:
|
|
93
|
+
rules = RULES[:]
|
|
94
|
+
random.shuffle(rules)
|
|
95
|
+
rules = rules[:random.randint(1, len(rules))]
|
|
96
|
+
|
|
97
|
+
formatted = code
|
|
98
|
+
for rule in rules:
|
|
99
|
+
applied = False
|
|
100
|
+
|
|
101
|
+
if "politeness" in rule.lower():
|
|
102
|
+
formatted = _ensure_politeness(formatted)
|
|
103
|
+
applied = True
|
|
104
|
+
|
|
105
|
+
if "misspelling" in rule.lower() or "lowercase" in rule.lower():
|
|
106
|
+
formatted = _add_misspellings(formatted)
|
|
107
|
+
applied = True
|
|
108
|
+
|
|
109
|
+
if "case" in rule.lower():
|
|
110
|
+
formatted = _randomize_case(formatted)
|
|
111
|
+
applied = True
|
|
112
|
+
|
|
113
|
+
if "whitespace" in rule.lower() or "trailing" in rule.lower():
|
|
114
|
+
formatted = _add_trailing_whitespace(formatted)
|
|
115
|
+
applied = True
|
|
116
|
+
|
|
117
|
+
if "indent" in rule.lower():
|
|
118
|
+
formatted = _adjust_indentation(formatted)
|
|
119
|
+
applied = True
|
|
120
|
+
|
|
121
|
+
if applied:
|
|
122
|
+
result.rules_applied.append(rule)
|
|
123
|
+
|
|
124
|
+
original_lines = code.split("\n")
|
|
125
|
+
formatted_lines = formatted.split("\n")
|
|
126
|
+
result.lines_modified = sum(
|
|
127
|
+
1 for i in range(min(len(original_lines), len(formatted_lines)))
|
|
128
|
+
if original_lines[i] != formatted_lines[i]
|
|
129
|
+
)
|
|
130
|
+
result.formatted = formatted
|
|
131
|
+
result.confidence = random.uniform(0.3, 0.95)
|
|
132
|
+
|
|
133
|
+
return result
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def main() -> None:
|
|
137
|
+
if len(sys.argv) < 2 or sys.argv[1] in ("-h", "--help"):
|
|
138
|
+
print("Usage: rzfmt [file.rizz]")
|
|
139
|
+
print("If no file is given, reads from stdin.")
|
|
140
|
+
print("")
|
|
141
|
+
print("RULES CHANGE HOURLY. DO NOT RELY ON CONSISTENT OUTPUT.")
|
|
142
|
+
sys.exit(0)
|
|
143
|
+
|
|
144
|
+
if sys.argv[1] == "--list-rules":
|
|
145
|
+
print("Current formatting rules:")
|
|
146
|
+
for rule in RULES:
|
|
147
|
+
print(f" - {rule}")
|
|
148
|
+
print("\n(Note: These rules may change before you finish reading this.)")
|
|
149
|
+
sys.exit(0)
|
|
150
|
+
|
|
151
|
+
filepath = sys.argv[1]
|
|
152
|
+
try:
|
|
153
|
+
with open(filepath) as f:
|
|
154
|
+
code = f.read()
|
|
155
|
+
except OSError as e:
|
|
156
|
+
print(f"Error reading {filepath}: {e}", file=sys.stderr)
|
|
157
|
+
sys.exit(1)
|
|
158
|
+
|
|
159
|
+
result = format_code(code)
|
|
160
|
+
with open(filepath, "w") as f:
|
|
161
|
+
f.write(result.formatted)
|
|
162
|
+
|
|
163
|
+
print(f"Formatted {filepath}")
|
|
164
|
+
print(f" Rules applied: {len(result.rules_applied)}")
|
|
165
|
+
print(f" Lines modified: {result.lines_modified}")
|
|
166
|
+
print(f" Confidence: {result.confidence:.0%}")
|
|
167
|
+
print(f" Warning: Next format may produce different results.")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
if __name__ == "__main__":
|
|
171
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rzfmt
|
rzfmt-0.1.0/setup.cfg
ADDED