codeplain 0.3.12.dev24__py3-none-any.whl → 0.3.12.dev25__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codeplain
3
- Version: 0.3.12.dev24
3
+ Version: 0.3.12.dev25
4
4
  Summary: Transform plain language specifications into working code
5
5
  License-File: LICENSE
6
6
  Classifier: Environment :: Console
@@ -4,7 +4,7 @@ concept_utils.py,sha256=TpyiQ4DfMtO231j-lPj65i0suRTPr8t9j3QNf9KiM4A,8080
4
4
  conformance_fix_journal.py,sha256=7wL3UOc3BWaUo5MCmiFbb3kIwOQ6iEpdQSyEmedo8Vk,9488
5
5
  diff_utils.py,sha256=AjiQlqo5pRos_8hVXZo5yBurl5BzSrTMGrQv4dCtRCg,1198
6
6
  event_bus.py,sha256=g5XLwRfjrvTIcB6urjREuCJzZj5TA93hy8lKXLGXuCE,650
7
- file_utils.py,sha256=knp_cUjYlhr8pq13jRSscTHcygdmk9YFJfkzB0gmg0g,12822
7
+ file_utils.py,sha256=IshKvld9LJLwXSB3lxZ1HQyVHa93I626BsTScBu95ss,12118
8
8
  git_preflight.py,sha256=vB2A8GyYz_iWr8jOE4POFLBHr3qihmedWuidspGdsrw,1509
9
9
  git_utils.py,sha256=gCUA6_9zg19f6k_0aVcRnIVlAJSBD0Vt6takx-0pKME,16547
10
10
  memory_management.py,sha256=CwIOQqF7Xo1sNfvP69zQRK_CpjinQD9dbolhRPl6lTk,2446
@@ -77,7 +77,7 @@ tests/test_conformance_fix_journal.py,sha256=olTeAuxXgFwQ8LSQyt0FqtBy9_XY_gK-Ei_
77
77
  tests/test_console_log_styles.py,sha256=sxlhynMAP-kmqhBn1-pKvZXdCnlKSyCGJqwYKrh6sQ0,6468
78
78
  tests/test_distill_conformance_test_memory.py,sha256=Tftw9l-gLVwIU6QttY03h2VedvuFxpIsCmZIzvWfxMA,5481
79
79
  tests/test_dry_run_link_validation.py,sha256=ivvYXQPqUkQ8glbFyUrdCninCxF2mg-rAsDcfjcB7MM,2140
80
- tests/test_file_utils.py,sha256=69dmr6CJkJ8sru9FSwu-a1Mh62A-RIVYUN9lxYWGq4Q,6066
80
+ tests/test_file_utils.py,sha256=R_ZIhrTtwlhHxgmbBtA8PFEU5-QB4Fi5skJ7PS2KzdU,3614
81
81
  tests/test_fix_unit_tests_conformance_context.py,sha256=IEsXK0xMLRuHmoQGBwrY0ENWVng2n-db_YzSO2qBfqM,9136
82
82
  tests/test_folder_path_resolution.py,sha256=K9v684xkPE0HOAsovg8uDixpZmaIk7ho-Wd3rTjKLF0,6560
83
83
  tests/test_git_preflight.py,sha256=6aQqInDzpk03pS-6UfkGQWjErrIXTEdHs5oeq3ZYzTw,3186
@@ -117,8 +117,8 @@ tui/spinner.py,sha256=Ro6Gd9Przf-whuHqPRY6HwI0T57yJjyNPbhDbigZKZE,2471
117
117
  tui/state_handlers.py,sha256=zbUS_D9eU8qIwVpaxPEp9zL9bpg8gXsWNoUaqg9TLrQ,16664
118
118
  tui/styles.css,sha256=kiC7Og_2G1E7owoiZgV95-3_dSeQnsNj3qzaY04xkDg,6727
119
119
  tui/widget_helpers.py,sha256=jitm2WHiKj-NVFL-hULxWzckPreRbUTl9OIZLN31-ek,6997
120
- codeplain-0.3.12.dev24.dist-info/METADATA,sha256=iu8oMhAyTgF52TtIJMRiY1AkSWjNQm7ZnHaj4AgGKhk,7257
121
- codeplain-0.3.12.dev24.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
122
- codeplain-0.3.12.dev24.dist-info/entry_points.txt,sha256=oDZkBqu9WhtZApb_K6ia8-fn9aojwmAsgnKELceX5T4,46
123
- codeplain-0.3.12.dev24.dist-info/licenses/LICENSE,sha256=pCeKgQ1mXE5OmNUuKOfOZh1T1vqkeCUxghE7N8qgnzc,11345
124
- codeplain-0.3.12.dev24.dist-info/RECORD,,
120
+ codeplain-0.3.12.dev25.dist-info/METADATA,sha256=vjSTEqWFnNjJGUdJ2eL4R3SXDquCx69-dG_Oi6wU55s,7257
121
+ codeplain-0.3.12.dev25.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
122
+ codeplain-0.3.12.dev25.dist-info/entry_points.txt,sha256=oDZkBqu9WhtZApb_K6ia8-fn9aojwmAsgnKELceX5T4,46
123
+ codeplain-0.3.12.dev25.dist-info/licenses/LICENSE,sha256=pCeKgQ1mXE5OmNUuKOfOZh1T1vqkeCUxghE7N8qgnzc,11345
124
+ codeplain-0.3.12.dev25.dist-info/RECORD,,
file_utils.py CHANGED
@@ -142,20 +142,7 @@ def get_existing_files_content(build_folder, existing_files):
142
142
  return existing_files_content
143
143
 
144
144
 
145
- def ensure_final_newline(content: str) -> str:
146
- """Ends non-empty text with a newline, as linters expect (e.g. RuboCop, ESLint eol-last, Ruff W292)."""
147
- if content and not content.endswith("\n"):
148
- return content + "\n"
149
- return content
150
-
151
-
152
145
  def store_response_files(target_folder, response_files, existing_files):
153
- """Writes the files returned by the API to target_folder. None content deletes the file.
154
-
155
- Every written file ends with a newline - whole-file rewrites come back from the API without one. The
156
- added newline is also written back into response_files, so callers that diff response_files against
157
- the folder afterwards see exactly what is on disk.
158
- """
159
146
  for file_name in response_files:
160
147
  full_file_name = os.path.join(target_folder, file_name)
161
148
 
@@ -169,8 +156,6 @@ def store_response_files(target_folder, response_files, existing_files):
169
156
 
170
157
  continue
171
158
 
172
- response_files[file_name] = ensure_final_newline(response_files[file_name])
173
-
174
159
  os.makedirs(os.path.dirname(full_file_name), exist_ok=True)
175
160
 
176
161
  with open(full_file_name, "w", encoding="utf-8") as f:
tests/test_file_utils.py CHANGED
@@ -3,8 +3,7 @@ import tempfile
3
3
 
4
4
  import pytest
5
5
 
6
- from diff_utils import get_code_diff
7
- from file_utils import get_existing_files_content, load_linked_resources, store_response_files
6
+ from file_utils import load_linked_resources, store_response_files
8
7
  from plain2code_exceptions import UnsupportedBase64Content, UnsupportedResourceType
9
8
  from plain2code_utils import MAX_BASE64_BLOB_LENGTH
10
9
 
@@ -85,64 +84,9 @@ def test_load_linked_resources_real_base64_image_raises(template_dir):
85
84
  def test_store_response_files_writes_unicode_as_utf8(template_dir):
86
85
  # Content with a non-cp1252 character (📍 U+1F4CD) must be written as UTF-8
87
86
  # regardless of the platform's default text encoding (e.g. cp1252 on Windows).
88
- content = "Location 📍 marker\n"
87
+ content = "Location 📍 marker"
89
88
  store_response_files(template_dir, {"notes.md": content}, [])
90
89
 
91
90
  file_path = os.path.join(template_dir, "notes.md")
92
91
  with open(file_path, "rb") as f:
93
92
  assert f.read().decode("utf-8") == content
94
-
95
-
96
- def _read_bytes(folder, file_name):
97
- with open(os.path.join(folder, file_name), "rb") as f:
98
- return f.read().decode("utf-8")
99
-
100
-
101
- @pytest.mark.parametrize(
102
- "content, expected",
103
- [
104
- ("class Foo\nend", "class Foo\nend\n"),
105
- ("class Foo\nend\n", "class Foo\nend\n"),
106
- ("class Foo\nend\n\n", "class Foo\nend\n\n"),
107
- ("class Foo\r\nend\r\n", "class Foo\r\nend\r\n"),
108
- ("", ""),
109
- ],
110
- )
111
- def test_store_response_files_ends_every_text_file_with_a_newline(template_dir, content, expected):
112
- # Linters gate on a final newline (RuboCop Layout/TrailingEmptyLines, ESLint eol-last, Ruff W292), so a
113
- # whole-file rewrite that comes back without one must not reach the disk that way.
114
- store_response_files(template_dir, {"app/foo.rb": content}, [])
115
-
116
- assert _read_bytes(template_dir, "app/foo.rb") == expected
117
-
118
-
119
- def test_store_response_files_hands_back_the_content_it_wrote(template_dir):
120
- # Callers diff the response files against the build folder after storing them (fix journal, conformance
121
- # fixes handed to the unit tests fixer), so the response files must match what is on disk.
122
- response_files = {"app/foo.rb": "class Foo\nend", "app/bar.rb": "class Bar\nend\n"}
123
-
124
- store_response_files(template_dir, response_files, [])
125
-
126
- assert response_files == {"app/foo.rb": "class Foo\nend\n", "app/bar.rb": "class Bar\nend\n"}
127
-
128
-
129
- def test_rewriting_a_file_without_its_final_newline_does_not_change_it(template_dir):
130
- existing_files = store_response_files(template_dir, {"app/foo.rb": "class Foo\nend\n"}, [])
131
- existing_files_content = get_existing_files_content(template_dir, existing_files)
132
-
133
- rewrite = {"app/foo.rb": "class Foo\nend"}
134
- store_response_files(template_dir, rewrite, existing_files)
135
-
136
- assert get_existing_files_content(template_dir, existing_files) == existing_files_content
137
- assert get_code_diff(rewrite, existing_files_content) == {}
138
-
139
-
140
- def test_store_response_files_still_deletes_a_file_whose_content_is_none(template_dir):
141
- existing_files = store_response_files(template_dir, {"app/foo.rb": "class Foo\nend\n"}, [])
142
-
143
- response_files = {"app/foo.rb": None}
144
- store_response_files(template_dir, response_files, existing_files)
145
-
146
- assert not os.path.exists(os.path.join(template_dir, "app/foo.rb"))
147
- assert existing_files == []
148
- assert response_files == {"app/foo.rb": None}