Skip to content

Commit 8148930

Browse files
committed
Renaming "functional requirements" to "functionality" or "functionalities" everywhere.
1 parent fbadad8 commit 8148930

35 files changed

Lines changed: 176 additions & 157 deletions

codeplain_REST_api.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,11 @@ def render_functional_requirement(
156156
run_state: RunState,
157157
) -> dict[str, str]:
158158
"""
159-
Renders the content of a functional requirement based on the provided ID,
159+
Renders the content of a functionality based on the provided ID,
160160
corresponding sections from a Plain document, and existing files' content.
161161
162162
Args:
163-
frid (str): The unique identifier for the functional requirement to be rendered.
163+
frid (str): The unique identifier for the functionality to be rendered.
164164
plain_source_tree (dict): A dictionary containing the plain source tree.
165165
linked_resources (dict): A dictionary where the keys represent filenames of linked
166166
resources and the values are dictionaries containing
@@ -170,7 +170,7 @@ def render_functional_requirement(
170170
and the values are the content of those files.
171171
memory_files_content (dict): A dictionary where the keys represent memory filenames
172172
and the values are the content of those files.
173-
module_name (str): The name of the module to render the functional requirement for.
173+
module_name (str): The name of the module to render the functionality for.
174174
required_modules (dict): A dictionary where the keys represent module names
175175
and the values are lists of functionalities implemented in those modules.
176176
run_state (RunState): The current state of the rendering process.
@@ -390,7 +390,7 @@ def render_acceptance_tests(
390390
Renders acceptance tests based on the provided parameters.
391391
392392
Args:
393-
frid (str): The unique identifier for the functional requirement.
393+
frid (str): The unique identifier for the functionality.
394394
plain_source_tree (dict): A dictionary containing the plain source tree.
395395
linked_resources (dict): A dictionary where the keys represent resource names
396396
and the values are the content of those resources.

docs/plain2code_cli.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ options:
2727
Name of the log file. Defaults to 'codeplain.log'.Always resolved relative to the plain file directory.If file on this path already exists, the already existing log file will be overwritten by the
2828
current logs.
2929
--render-range RENDER_RANGE
30-
Specify a range of functional requirements to render (e.g. `1` , `2`, `3`). Use comma to separate start and end IDs. If only one ID is provided, only that requirement is rendered. Range is
30+
Specify a range of functionalities to render (e.g. `1` , `2`, `3`). Use comma to separate start and end IDs. If only one ID is provided, only that requirement is rendered. Range is
3131
inclusive of both start and end IDs.
3232
--render-from RENDER_FROM
33-
Continue generation starting from this specific functional requirement (e.g. `2`). The requirement with this ID will be included in the output. The ID must match one of the functional requirements
33+
Continue generation starting from this specific functionality (e.g. `2`). The requirement with this ID will be included in the output. The ID must match one of the functionalities
3434
in your plain file.
3535
--force-render Force re-render of all the required modules.
3636
--unittests-script UNITTESTS_SCRIPT

file_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,17 @@ def load_linked_resources(template_dirs: list[str], resources_list):
236236
content = open_from(template_dirs, file_name)
237237

238238
if content is None:
239-
raise FileNotFoundError(f"""
239+
raise FileNotFoundError(
240+
f"""
240241
Resource file {file_name} not found. Resource files are searched in the following order (highest to lowest precedence):
241242
242243
1. The directory containing your .plain file
243244
2. The directory specified by --template-dir (if provided)
244245
3. The built-in 'standard_template_library' directory
245246
246247
Please ensure that the resource exists in one of these locations, or specify the correct --template-dir if using custom templates.
247-
""")
248+
"""
249+
)
248250

249251
linked_resources[file_name] = content
250252

git_utils.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,20 @@
77
import file_utils
88
from plain2code_exceptions import InvalidGitRepositoryError
99

10-
FUNCTIONAL_REQUIREMENT_IMPLEMENTED_COMMIT_MESSAGE = (
11-
"[Codeplain] Implemented code and unit tests for functional requirement {}"
12-
)
13-
REFACTORED_CODE_COMMIT_MESSAGE = "[Codeplain] Refactored code after implementing functional requirement {}"
10+
FUNCTIONAL_REQUIREMENT_IMPLEMENTED_COMMIT_MESSAGE = "[Codeplain] Implemented code and unit tests for functionality {}"
11+
REFACTORED_CODE_COMMIT_MESSAGE = "[Codeplain] Refactored code after implementing functionality {}"
1412
CONFORMANCE_TESTS_PASSED_COMMIT_MESSAGE = (
1513
"[Codeplain] Fixed issues in the implementation code identified during conformance testing"
1614
)
1715

1816
# Following messages are used as checkpoints in the git history
1917
# Changing them will break backwards compatibility so change them with care
20-
FUNCTIONAL_REQUIREMENT_FINISHED_COMMIT_MESSAGE = "[Codeplain] Functional requirement ID (FRID):{} fully implemented"
18+
FUNCTIONAL_REQUIREMENT_FINISHED_COMMIT_MESSAGE = "[Codeplain] functionality ID (FRID):{} fully implemented"
2119
INITIAL_COMMIT_MESSAGE = "[Codeplain] Initial module commit"
2220
BASE_FOLDER_COMMIT_MESSAGE = "[Codeplain] Initialize build with Base Folder content"
2321

2422

25-
RENDERED_FRID_MESSAGE = "Changes related to Functional requirement ID (FRID): {}"
23+
RENDERED_FRID_MESSAGE = "Changes related to functionality ID (FRID): {}"
2624
MODULE_NAME_MESSAGE = "Module name: {}"
2725
RENDER_ID_MESSAGE = "Render ID: {}"
2826

@@ -244,7 +242,7 @@ def diff(repo_path: Union[str, os.PathLike], previous_frid: str = None) -> dict:
244242
245243
Args:
246244
repo_path (str | os.PathLike): Path to the git repository
247-
previous_frid (str): Functional requirement ID (FRID) of the previous commit
245+
previous_frid (str): functionality ID (FRID) of the previous commit
248246
249247
Returns:
250248
dict: Dictionary with file names as keys and their clean diff strings as values
@@ -285,7 +283,7 @@ def _get_commit_with_frid(repo: Repo, frid: str, module_name: Optional[str] = No
285283
286284
Args:
287285
repo (Repo): Git repository object
288-
frid (str): Functional requirement ID
286+
frid (str): functionality ID
289287
module_name (Optional[str]): Module name to filter by. If provided, only returns
290288
commits that have both the FRID and module name.
291289

plain2code.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,22 +86,20 @@ def _get_frids_range(plain_source, start, end=None):
8686
start = str(start)
8787

8888
if start not in frids:
89-
raise InvalidFridArgument(f"Invalid start functional requirement ID: {start}. Valid IDs are: {frids}.")
89+
raise InvalidFridArgument(f"Invalid start functionality ID: {start}. Valid IDs are: {frids}.")
9090

9191
if end is not None:
9292
end = str(end)
9393
if end not in frids:
94-
raise InvalidFridArgument(f"Invalid end functional requirement ID: {end}. Valid IDs are: {frids}.")
94+
raise InvalidFridArgument(f"Invalid end functionality ID: {end}. Valid IDs are: {frids}.")
9595

9696
end_idx = frids.index(end) + 1
9797
else:
9898
end_idx = len(frids)
9999

100100
start_idx = frids.index(start)
101101
if start_idx >= end_idx:
102-
raise InvalidFridArgument(
103-
f"Start functional requirement ID: {start} must be before end functional requirement ID: {end}."
104-
)
102+
raise InvalidFridArgument(f"Start functionality ID: {start} must be before end functionality ID: {end}.")
105103

106104
return frids[start_idx:end_idx]
107105

plain2code_arguments.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import argparse
22
import os
3-
import re
43

54
from plain2code_console import console
65
from plain2code_exceptions import AmbiguousConfigFileError
@@ -59,14 +58,14 @@ def non_empty_string(s):
5958

6059

6160
def frid_string(s):
62-
"""Validate that the string contains only numbers separated by dots."""
61+
"""Validate that the FRID is an integer."""
6362
if not s:
64-
raise argparse.ArgumentTypeError("The functional requirement ID cannot be empty.")
63+
raise argparse.ArgumentTypeError("The functionality ID cannot be empty.")
6564

66-
if not re.match(r"^\d+(\.\d+)*$", s):
67-
raise argparse.ArgumentTypeError(
68-
"Functional requirement ID string must contain only numbers optionally separated by dots (e.g. '1', '1.2.3')"
69-
)
65+
try:
66+
int(s)
67+
except ValueError:
68+
raise argparse.ArgumentTypeError("Functionality ID string must be a number.")
7069
return s
7170

7271

@@ -77,7 +76,7 @@ def frid_range_string(s):
7776

7877
parts = s.split(",")
7978
if len(parts) > 2:
80-
raise argparse.ArgumentTypeError("Range must contain at most two functional requirement IDs separated by comma")
79+
raise argparse.ArgumentTypeError("Range must contain at most two functionality IDs separated by comma")
8180

8281
for part in parts:
8382
frid_string(part)
@@ -205,15 +204,15 @@ def create_parser():
205204
render_range_group.add_argument(
206205
"--render-range",
207206
type=frid_range_string,
208-
help="Specify a range of functional requirements to render (e.g. `1` , `2`, `3`). "
209-
"Use comma to separate start and end IDs. If only one ID is provided, only that requirement is rendered. "
207+
help="Specify a range of functionalities to render (e.g. `1` , `2`, `3`). "
208+
"Use comma to separate start and end IDs. If only one ID is provided, only that functionality is rendered. "
210209
"Range is inclusive of both start and end IDs.",
211210
)
212211
render_range_group.add_argument(
213212
"--render-from",
214213
type=frid_string,
215-
help="Continue generation starting from this specific functional requirement (e.g. `2`). "
216-
"The requirement with this ID will be included in the output. The ID must match one of the functional requirements in your plain file.",
214+
help="Continue generation starting from this specific functionality (e.g. `2`). "
215+
"The requirement with this ID will be included in the output. The ID must match one of the functionalities in your plain file.",
217216
)
218217

219218
parser.add_argument(

plain2code_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
AMBIGUITY_CAUSES = {
77
"reference_resource_ambiguity": "Ambiguity is in the reference resources",
88
"definition_ambiguity": "Ambiguity is in the definitions",
9-
"non_functional_requirement_ambiguity": "Ambiguity is in the non-functional requirements",
10-
"functional_requirement_ambiguity": "Ambiguity is in the functional requirements",
9+
"non_functional_requirement_ambiguity": "Ambiguity is in the implementation reqs",
10+
"functional_requirement_ambiguity": "Ambiguity is in the functionality",
1111
"other": "Ambiguity in the other parts of the specification",
1212
}
1313

@@ -23,7 +23,7 @@ def print_dry_run_output(plain_source_tree: dict, render_range: Optional[list[st
2323
functional_requirement_text = specifications[plain_spec.FUNCTIONAL_REQUIREMENTS][-1]
2424
console.info(
2525
"-------------------------------------\n"
26-
f"Rendering functional requirement {frid}\n"
26+
f"Rendering functionality {frid}\n"
2727
f"{functional_requirement_text}\n"
2828
"-------------------------------------\n"
2929
)

plain_file.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def check_if_functional_requirements_are_specified(plain_source, non_functional_
136136

137137
found_functional_requirements = plain_spec.FUNCTIONAL_REQUIREMENTS in plain_source
138138
if found_functional_requirements and len(non_functional_requirements) == 0:
139-
raise PlainSyntaxError("Syntax error: Functional requirement with no non-functional requirements specified.")
139+
raise PlainSyntaxError("Syntax error: functionality with no implementation reqs specified.")
140140

141141
return found_functional_requirements
142142

@@ -183,16 +183,16 @@ def _is_acceptance_test_heading(token) -> tuple[bool, str | None]:
183183

184184
def _process_single_acceptance_test_requirement(functional_requirement: mistletoe.block_token.ListItem):
185185
"""
186-
Process a single functional requirement to extract acceptance tests.
186+
Process a single functionality to extract acceptance tests.
187187
188188
Expected functional_requirement properties:
189189
- Is a list item
190190
- If acceptance tests are specified, it has 3 children:
191-
- List item element with functional requirement instructions/text
191+
- List item element with functionality instructions/text
192192
- Paragraph with `***Acceptance test:***` heading
193193
- List of acceptance tests
194194
- If acceptance tests are not specified, it has 1 child:
195-
- List item element with functional requirement instructions/text
195+
- List item element with functionality instructions/text
196196
"""
197197
new_children = []
198198
functional_requirement_children = iter(functional_requirement.children)
@@ -205,15 +205,15 @@ def _process_single_acceptance_test_requirement(functional_requirement: mistleto
205205
if acceptance_test_heading_problem:
206206
# Handle the case when the heading is not valid. This case includes cases such as:
207207
# - Writing `acceptance test` instead of `acceptance tests` (or any other syntax diffs).
208-
# - Instead of specifying `acceptance tests` below the functional requirement, creator of the plain file
208+
# - Instead of specifying `acceptance tests` below the functionality, creator of the plain file
209209
# might have specified some other building block (e.g. `implementation reqs`)
210210
raise PlainSyntaxError(acceptance_test_heading_problem)
211211

212212
if is_acceptance_test_heading:
213213
if acceptance_tests_found_already:
214214
# Handle edge case of duplicated ***acceptance tests*** heading
215215
raise PlainSyntaxError(
216-
f"Syntax error at line {functional_requirement_child.line_number}: Duplicate 'acceptance tests' heading found within the same functional requirement. Only one block of acceptance tests is allowed per functional requirement."
216+
f"Syntax error at line {functional_requirement_child.line_number}: Duplicate 'acceptance tests' heading found within the same functionality. Only one block of acceptance tests is allowed per functionality."
217217
)
218218

219219
try:
@@ -237,20 +237,20 @@ def _process_single_acceptance_test_requirement(functional_requirement: mistleto
237237
# Regular token, keep it
238238
new_children.append(functional_requirement_child)
239239

240-
# Assign the children property to all the children of the functional requirement from previous, with exception
240+
# Assign the children property to all the children of the functionality from previous, with exception
241241
# of those we parsed as acceptance tests
242242
functional_requirement.children = type(functional_requirement.children)(new_children)
243243

244244

245245
def process_acceptance_tests(plain_source):
246-
# Early returns for cases without functional requirements
246+
# Early returns for cases without functionalities
247247
if plain_spec.FUNCTIONAL_REQUIREMENTS not in plain_source:
248248
return
249249
frs = plain_source[plain_spec.FUNCTIONAL_REQUIREMENTS]
250250
if not hasattr(frs, "children"):
251251
return
252252

253-
# Process each functional requirement
253+
# Process each functionality
254254
for functional_requirement in frs.children:
255255
if not hasattr(functional_requirement, "children"):
256256
continue
@@ -343,7 +343,7 @@ def process_imports(
343343
)
344344

345345
if check_if_functional_requirements_are_specified(plain_file_parse_result.plain_source, []):
346-
raise PlainSyntaxError("Imported module must not contain functional requirements.")
346+
raise PlainSyntaxError("Imported module must not contain functionalities.")
347347

348348
for specification_heading in plain_file_parse_result.plain_source:
349349
if specification_heading not in plain_spec.ALLOWED_IMPORT_SPECIFICATION_HEADINGS:
@@ -649,7 +649,7 @@ def plain_file_parser( # noqa: C901
649649
)
650650

651651
if not check_if_functional_requirements_are_specified(plain_file_parse_result.plain_source, []):
652-
raise PlainSyntaxError("Syntax error: No functional requirements specified.")
652+
raise PlainSyntaxError("Syntax error: No functionality specified.")
653653

654654
exported_definitions = process_required_modules(
655655
plain_file_parse_result.required_modules,

plain_spec.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def get_next_frid(plain_source_tree, frid):
164164
if temp_frid == frid:
165165
return next(functional_requirements, None)
166166

167-
raise Exception(f"Functional requirement {frid} does not exist.")
167+
raise Exception(f"Functionality {frid} does not exist.")
168168

169169

170170
def get_previous_frid(plain_source_tree, frid):
@@ -175,7 +175,7 @@ def get_previous_frid(plain_source_tree, frid):
175175

176176
previous_frid = temp_frid
177177

178-
raise Exception(f"Functional requirement {frid} does not exist.")
178+
raise Exception(f"Functionality {frid} does not exist.")
179179

180180

181181
def get_frids_before(plain_source_tree, target_frid: str) -> list[str]:
@@ -314,7 +314,7 @@ def get_specifications_for_frid(plain_source_tree, frid, replace_code_variables=
314314
replace_code_variables,
315315
)
316316
if result is None:
317-
raise Exception(f"Functional requirement {frid} does not exist.")
317+
raise Exception(f"Functionality {frid} does not exist.")
318318

319319
specifications = {
320320
DEFINITIONS: definitions,

render_machine/actions/analyze_specification_ambiguity.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ def execute(self, render_context: RenderContext, _previous_action_payload: Any |
4646
if rendering_analysis:
4747
# TODO: Before this output is exposed to the user, we should check the 'guidance' field using LLM in the same way as we do conflicting requirements.
4848
console.info(
49-
f"Specification ambiguity detected! {AMBIGUITY_CAUSES[rendering_analysis['cause']]} of the functional requirement {render_context.frid_context.frid}."
49+
f"Specification ambiguity detected! {AMBIGUITY_CAUSES[rendering_analysis['cause']]} of the functionality {render_context.frid_context.frid}."
5050
)
5151
console.info(rendering_analysis["guidance"])
5252
else:
5353
console.warning(
54-
f"No specification ambiguity detected for functional requirement {render_context.frid_context.frid}."
54+
f"No specification ambiguity detected for functionality {render_context.frid_context.frid}."
5555
)
5656
return self.SUCCESSFUL_OUTCOME, None

0 commit comments

Comments
 (0)