codeplain 0.1.0__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.
- codeplain-0.1.0.dist-info/METADATA +142 -0
- codeplain-0.1.0.dist-info/RECORD +51 -0
- codeplain-0.1.0.dist-info/WHEEL +5 -0
- codeplain-0.1.0.dist-info/entry_points.txt +2 -0
- codeplain-0.1.0.dist-info/licenses/LICENSE +21 -0
- codeplain-0.1.0.dist-info/top_level.txt +36 -0
- codeplain_REST_api.py +370 -0
- config/__init__.py +2 -0
- config/system_config.yaml +27 -0
- file_utils.py +316 -0
- git_utils.py +304 -0
- hash_key.py +29 -0
- plain2code.py +218 -0
- plain2code_arguments.py +286 -0
- plain2code_console.py +107 -0
- plain2code_exceptions.py +45 -0
- plain2code_nodes.py +108 -0
- plain2code_read_config.py +74 -0
- plain2code_state.py +75 -0
- plain2code_utils.py +56 -0
- plain_spec.py +360 -0
- render_machine/actions/analyze_specification_ambiguity.py +50 -0
- render_machine/actions/base_action.py +19 -0
- render_machine/actions/commit_conformance_tests_changes.py +46 -0
- render_machine/actions/commit_implementation_code_changes.py +22 -0
- render_machine/actions/create_dist.py +26 -0
- render_machine/actions/exit_with_error.py +22 -0
- render_machine/actions/fix_conformance_test.py +121 -0
- render_machine/actions/fix_unit_tests.py +57 -0
- render_machine/actions/prepare_repositories.py +50 -0
- render_machine/actions/prepare_testing_environment.py +30 -0
- render_machine/actions/refactor_code.py +48 -0
- render_machine/actions/render_conformance_tests.py +169 -0
- render_machine/actions/render_functional_requirement.py +69 -0
- render_machine/actions/run_conformance_tests.py +44 -0
- render_machine/actions/run_unit_tests.py +38 -0
- render_machine/actions/summarize_conformance_tests.py +34 -0
- render_machine/code_renderer.py +50 -0
- render_machine/conformance_test_helpers.py +68 -0
- render_machine/implementation_code_helpers.py +20 -0
- render_machine/render_context.py +280 -0
- render_machine/render_types.py +36 -0
- render_machine/render_utils.py +92 -0
- render_machine/state_machine_config.py +408 -0
- render_machine/states.py +52 -0
- render_machine/triggers.py +27 -0
- standard_template_library/__init__.py +1 -0
- standard_template_library/golang-console-app-template.plain +36 -0
- standard_template_library/python-console-app-template.plain +32 -0
- standard_template_library/typescript-react-app-template.plain +22 -0
- system_config.py +49 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import file_utils
|
|
4
|
+
import git_utils
|
|
5
|
+
import plain_spec
|
|
6
|
+
from plain2code_console import console
|
|
7
|
+
from plain2code_utils import AMBIGUITY_CAUSES
|
|
8
|
+
from render_machine.actions.base_action import BaseAction
|
|
9
|
+
from render_machine.render_context import RenderContext
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AnalyzeSpecificationAmbiguity(BaseAction):
|
|
13
|
+
SUCCESSFUL_OUTCOME = "conformance_tests_postanalyzed"
|
|
14
|
+
|
|
15
|
+
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
16
|
+
fixed_implementation_code_diff = git_utils.get_fixed_implementation_code_diff(
|
|
17
|
+
render_context.args.build_folder, render_context.frid_context.frid
|
|
18
|
+
)
|
|
19
|
+
if fixed_implementation_code_diff is None:
|
|
20
|
+
raise Exception(
|
|
21
|
+
"Fixes to the implementation code found during conformance testing are not committed to git."
|
|
22
|
+
)
|
|
23
|
+
previous_frid = plain_spec.get_previous_frid(render_context.plain_source_tree, render_context.frid_context.frid)
|
|
24
|
+
git_utils.checkout_commit_with_frid(render_context.args.build_folder, previous_frid)
|
|
25
|
+
existing_files = file_utils.list_all_text_files(render_context.args.build_folder)
|
|
26
|
+
existing_files_content = file_utils.get_existing_files_content(render_context.args.build_folder, existing_files)
|
|
27
|
+
git_utils.checkout_previous_branch(render_context.args.build_folder)
|
|
28
|
+
implementation_code_diff = git_utils.get_implementation_code_diff(
|
|
29
|
+
render_context.args.build_folder, render_context.frid_context.frid, previous_frid
|
|
30
|
+
)
|
|
31
|
+
rendering_analysis = render_context.codeplain_api.analyze_rendering(
|
|
32
|
+
render_context.frid_context.frid,
|
|
33
|
+
render_context.plain_source_tree,
|
|
34
|
+
render_context.frid_context.linked_resources,
|
|
35
|
+
existing_files_content,
|
|
36
|
+
implementation_code_diff,
|
|
37
|
+
fixed_implementation_code_diff,
|
|
38
|
+
render_context.run_state,
|
|
39
|
+
)
|
|
40
|
+
if rendering_analysis:
|
|
41
|
+
# 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.
|
|
42
|
+
console.info(
|
|
43
|
+
f"Specification ambiguity detected! {AMBIGUITY_CAUSES[rendering_analysis['cause']]} of the functional requirement {render_context.frid_context.frid}."
|
|
44
|
+
)
|
|
45
|
+
console.info(rendering_analysis["guidance"])
|
|
46
|
+
else:
|
|
47
|
+
console.warning(
|
|
48
|
+
f"No specification ambiguity detected for functional requirement {render_context.frid_context.frid}."
|
|
49
|
+
)
|
|
50
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from render_machine.render_context import RenderContext
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BaseAction:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
@abstractmethod
|
|
12
|
+
def execute(self, _render_context: RenderContext, _previous_action_payload: Any | None):
|
|
13
|
+
"""
|
|
14
|
+
Execute the action with the given render context and optional previous action payload.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
tuple: (outcome, payload) where outcome is a string and payload can be any object or None
|
|
18
|
+
"""
|
|
19
|
+
pass
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import git_utils
|
|
4
|
+
import plain_spec
|
|
5
|
+
from render_machine.actions.base_action import BaseAction
|
|
6
|
+
from render_machine.render_context import RenderContext
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CommitConformanceTestsChanges(BaseAction):
|
|
10
|
+
SUCCESSFUL_OUTCOME_IMPLEMENTATION_NOT_UPDATED = "conformance_tests_changes_committed_implementation_not_updated"
|
|
11
|
+
SUCCESSFUL_OUTCOME_IMPLEMENTATION_UPDATED = "conformance_tests_changes_committed_implementation_updated"
|
|
12
|
+
|
|
13
|
+
def __init__(self, implementation_code_commit_message: str, conformance_tests_commit_message: str):
|
|
14
|
+
self.implementation_code_commit_message = implementation_code_commit_message
|
|
15
|
+
self.conformance_tests_commit_message = conformance_tests_commit_message
|
|
16
|
+
|
|
17
|
+
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
18
|
+
implementation_updated = False
|
|
19
|
+
if git_utils.is_dirty(render_context.args.build_folder):
|
|
20
|
+
git_utils.add_all_files_and_commit(
|
|
21
|
+
render_context.args.build_folder,
|
|
22
|
+
self.implementation_code_commit_message,
|
|
23
|
+
render_context.frid_context.frid,
|
|
24
|
+
render_context.run_state.render_id,
|
|
25
|
+
)
|
|
26
|
+
implementation_updated = True
|
|
27
|
+
functional_requirement_text = render_context.frid_context.specifications[plain_spec.FUNCTIONAL_REQUIREMENTS][-1]
|
|
28
|
+
templated_functional_requirement_finished_commit_msg = self.conformance_tests_commit_message.format(
|
|
29
|
+
render_context.frid_context.frid
|
|
30
|
+
)
|
|
31
|
+
formatted_conformance_commit_msg = (
|
|
32
|
+
f"{functional_requirement_text}\n\n{templated_functional_requirement_finished_commit_msg}"
|
|
33
|
+
)
|
|
34
|
+
render_context.conformance_tests_utils.dump_conformance_tests_json(
|
|
35
|
+
render_context.conformance_tests_running_context.conformance_tests_json
|
|
36
|
+
)
|
|
37
|
+
git_utils.add_all_files_and_commit(
|
|
38
|
+
render_context.args.conformance_tests_folder,
|
|
39
|
+
formatted_conformance_commit_msg,
|
|
40
|
+
None,
|
|
41
|
+
render_context.run_state.render_id,
|
|
42
|
+
)
|
|
43
|
+
if implementation_updated:
|
|
44
|
+
return self.SUCCESSFUL_OUTCOME_IMPLEMENTATION_UPDATED, None
|
|
45
|
+
else:
|
|
46
|
+
return self.SUCCESSFUL_OUTCOME_IMPLEMENTATION_NOT_UPDATED, None
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import git_utils
|
|
4
|
+
from render_machine.actions.base_action import BaseAction
|
|
5
|
+
from render_machine.render_context import RenderContext
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CommitImplementationCodeChanges(BaseAction):
|
|
9
|
+
SUCCESSFUL_OUTCOME = "implementation_code_changes_committed"
|
|
10
|
+
|
|
11
|
+
def __init__(self, base_commit_message: str):
|
|
12
|
+
self.base_commit_message = base_commit_message
|
|
13
|
+
|
|
14
|
+
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
15
|
+
git_utils.add_all_files_and_commit(
|
|
16
|
+
render_context.args.build_folder,
|
|
17
|
+
self.base_commit_message.format(render_context.frid_context.frid),
|
|
18
|
+
render_context.frid_context.frid,
|
|
19
|
+
render_context.run_state.render_id,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import file_utils
|
|
4
|
+
from plain2code_console import console
|
|
5
|
+
from render_machine.actions.base_action import BaseAction
|
|
6
|
+
from render_machine.render_context import RenderContext
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CreateDist(BaseAction):
|
|
10
|
+
SUCCESSFUL_OUTCOME = "dist_created"
|
|
11
|
+
|
|
12
|
+
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
13
|
+
# Copy build and conformance tests folders to output folders if specified
|
|
14
|
+
if render_context.args.copy_build:
|
|
15
|
+
file_utils.copy_folder_to_output(
|
|
16
|
+
render_context.args.build_folder,
|
|
17
|
+
render_context.args.build_dest,
|
|
18
|
+
)
|
|
19
|
+
if render_context.args.copy_conformance_tests:
|
|
20
|
+
file_utils.copy_folder_to_output(
|
|
21
|
+
render_context.args.conformance_tests_folder,
|
|
22
|
+
render_context.args.conformance_tests_dest,
|
|
23
|
+
)
|
|
24
|
+
console.info(f"Render {render_context.run_state.render_id} completed successfully.")
|
|
25
|
+
|
|
26
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from plain2code_console import console
|
|
4
|
+
from render_machine.actions.base_action import BaseAction
|
|
5
|
+
from render_machine.render_context import RenderContext
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ExitWithError(BaseAction):
|
|
9
|
+
SUCCESSFUL_OUTCOME = "error_handled"
|
|
10
|
+
|
|
11
|
+
def execute(self, render_context: RenderContext, previous_action_payload: Any | None):
|
|
12
|
+
console.error(previous_action_payload)
|
|
13
|
+
|
|
14
|
+
if render_context.frid_context is not None:
|
|
15
|
+
console.info(
|
|
16
|
+
f"To continue rendering from the last successfully rendered functional requirement, provide the [red][b]--render-from {render_context.frid_context.frid}[/b][/red] flag."
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
if render_context.run_state.render_id is not None:
|
|
20
|
+
console.info(f"Render ID: {render_context.run_state.render_id}")
|
|
21
|
+
|
|
22
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import file_utils
|
|
4
|
+
import plain_spec
|
|
5
|
+
from plain2code_console import console
|
|
6
|
+
from plain2code_exceptions import UnexpectedState
|
|
7
|
+
from render_machine.actions.base_action import BaseAction
|
|
8
|
+
from render_machine.conformance_test_helpers import ConformanceTestHelpers
|
|
9
|
+
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
|
|
10
|
+
from render_machine.render_context import RenderContext
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class FixConformanceTest(BaseAction):
|
|
14
|
+
IMPLEMENTATION_CODE_NOT_UPDATED = "implementation_code_not_updated"
|
|
15
|
+
IMPLEMENTATION_CODE_UPDATED = "implementation_code_updated"
|
|
16
|
+
|
|
17
|
+
def execute(self, render_context: RenderContext, previous_action_payload: Any | None):
|
|
18
|
+
console.info(
|
|
19
|
+
f"Fixing conformance test for functional requirement {render_context.conformance_tests_running_context.current_testing_frid}."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
if not previous_action_payload.get("previous_conformance_tests_issue"):
|
|
23
|
+
raise UnexpectedState("Previous action payload does not contain previous conformance tests issue.")
|
|
24
|
+
previous_conformance_tests_issue = previous_action_payload["previous_conformance_tests_issue"]
|
|
25
|
+
|
|
26
|
+
if render_context.conformance_tests_running_context.current_testing_frid == render_context.frid_context.frid:
|
|
27
|
+
console_message = f"Fixing conformance test for functional requirement {render_context.conformance_tests_running_context.current_testing_frid}."
|
|
28
|
+
else:
|
|
29
|
+
console_message = f"While implementing functional requirement {render_context.frid_context.frid}, conformance tests for functional requirement {render_context.conformance_tests_running_context.current_testing_frid} broke. Fixing them..."
|
|
30
|
+
|
|
31
|
+
existing_files, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(render_context)
|
|
32
|
+
(
|
|
33
|
+
existing_conformance_test_files,
|
|
34
|
+
existing_conformance_test_files_content,
|
|
35
|
+
) = ConformanceTestHelpers.fetch_existing_conformance_test_files(
|
|
36
|
+
render_context.conformance_tests_running_context # type: ignore
|
|
37
|
+
)
|
|
38
|
+
previous_frid_code_diff = ImplementationCodeHelpers.get_code_diff(render_context)
|
|
39
|
+
|
|
40
|
+
if render_context.args.verbose:
|
|
41
|
+
tmp_resources_list = []
|
|
42
|
+
plain_spec.collect_linked_resources(
|
|
43
|
+
render_context.plain_source_tree,
|
|
44
|
+
tmp_resources_list,
|
|
45
|
+
None,
|
|
46
|
+
False,
|
|
47
|
+
render_context.frid_context.frid,
|
|
48
|
+
)
|
|
49
|
+
console.print_resources(tmp_resources_list, render_context.frid_context.linked_resources)
|
|
50
|
+
|
|
51
|
+
console.print_files(
|
|
52
|
+
"Implementation files sent as input for fixing conformance tests issues:",
|
|
53
|
+
render_context.args.build_folder,
|
|
54
|
+
existing_files_content,
|
|
55
|
+
style=console.INPUT_STYLE,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
console.print_files(
|
|
59
|
+
"Conformance tests files sent as input for fixing conformance tests issues:",
|
|
60
|
+
ConformanceTestHelpers.get_current_conformance_test_folder_name(
|
|
61
|
+
render_context.conformance_tests_running_context # type: ignore
|
|
62
|
+
),
|
|
63
|
+
existing_conformance_test_files_content,
|
|
64
|
+
style=console.INPUT_STYLE,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
acceptance_tests = ConformanceTestHelpers.get_current_acceptance_tests(
|
|
68
|
+
render_context.conformance_tests_running_context # type: ignore
|
|
69
|
+
)
|
|
70
|
+
conformance_tests_folder_name = ConformanceTestHelpers.get_current_conformance_test_folder_name(
|
|
71
|
+
render_context.conformance_tests_running_context # type: ignore
|
|
72
|
+
)
|
|
73
|
+
with console.status(console_message):
|
|
74
|
+
[conformance_tests_fixed, response_files] = render_context.codeplain_api.fix_conformance_tests_issue(
|
|
75
|
+
render_context.frid_context.frid,
|
|
76
|
+
render_context.conformance_tests_running_context.current_testing_frid,
|
|
77
|
+
render_context.plain_source_tree,
|
|
78
|
+
render_context.frid_context.linked_resources,
|
|
79
|
+
existing_files_content,
|
|
80
|
+
previous_frid_code_diff,
|
|
81
|
+
existing_conformance_test_files_content,
|
|
82
|
+
acceptance_tests,
|
|
83
|
+
previous_conformance_tests_issue,
|
|
84
|
+
render_context.conformance_tests_running_context.fix_attempts,
|
|
85
|
+
conformance_tests_folder_name,
|
|
86
|
+
render_context.conformance_tests_running_context.current_testing_frid_high_level_implementation_plan,
|
|
87
|
+
render_context.run_state,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
if conformance_tests_fixed:
|
|
91
|
+
file_utils.store_response_files(
|
|
92
|
+
ConformanceTestHelpers.get_current_conformance_test_folder_name(
|
|
93
|
+
render_context.conformance_tests_running_context # type: ignore
|
|
94
|
+
),
|
|
95
|
+
response_files,
|
|
96
|
+
existing_conformance_test_files,
|
|
97
|
+
)
|
|
98
|
+
if render_context.args.verbose:
|
|
99
|
+
console.print_files(
|
|
100
|
+
"Conformance test files fixed:",
|
|
101
|
+
ConformanceTestHelpers.get_current_conformance_test_folder_name(
|
|
102
|
+
render_context.conformance_tests_running_context # type: ignore
|
|
103
|
+
),
|
|
104
|
+
response_files,
|
|
105
|
+
style=console.OUTPUT_STYLE,
|
|
106
|
+
)
|
|
107
|
+
return self.IMPLEMENTATION_CODE_NOT_UPDATED, None
|
|
108
|
+
else:
|
|
109
|
+
if len(response_files) > 0:
|
|
110
|
+
file_utils.store_response_files(render_context.args.build_folder, response_files, existing_files)
|
|
111
|
+
if render_context.args.verbose:
|
|
112
|
+
console.print_files(
|
|
113
|
+
"Files fixed:",
|
|
114
|
+
render_context.args.build_folder,
|
|
115
|
+
response_files,
|
|
116
|
+
style=console.OUTPUT_STYLE,
|
|
117
|
+
)
|
|
118
|
+
render_context.conformance_tests_running_context.should_prepare_testing_environment = True
|
|
119
|
+
return self.IMPLEMENTATION_CODE_UPDATED, None
|
|
120
|
+
else:
|
|
121
|
+
return self.IMPLEMENTATION_CODE_NOT_UPDATED, None
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import file_utils
|
|
4
|
+
import render_machine.render_utils as render_utils
|
|
5
|
+
from plain2code_console import console
|
|
6
|
+
from plain2code_exceptions import UnexpectedState
|
|
7
|
+
from render_machine.actions.base_action import BaseAction
|
|
8
|
+
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
|
|
9
|
+
from render_machine.render_context import RenderContext
|
|
10
|
+
|
|
11
|
+
MAX_ISSUE_LENGTH = 10000
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FixUnitTests(BaseAction):
|
|
15
|
+
SUCCESSFUL_OUTCOME = "unit_tests_fix_generated"
|
|
16
|
+
|
|
17
|
+
def execute(self, render_context: RenderContext, previous_action_payload: Any | None):
|
|
18
|
+
if not previous_action_payload.get("previous_unittests_issue"):
|
|
19
|
+
raise UnexpectedState("Previous action payload does not contain previous unit tests issue.")
|
|
20
|
+
previous_unittests_issue = previous_action_payload["previous_unittests_issue"]
|
|
21
|
+
|
|
22
|
+
if previous_unittests_issue and len(previous_unittests_issue) > MAX_ISSUE_LENGTH:
|
|
23
|
+
console.warning(
|
|
24
|
+
f"Unit tests issue text is too long and will be smartly truncated to {MAX_ISSUE_LENGTH} characters."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
existing_files, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(render_context)
|
|
28
|
+
|
|
29
|
+
if render_context.args.verbose:
|
|
30
|
+
render_utils.print_inputs(
|
|
31
|
+
render_context, existing_files_content, "Files sent as input to unit tests fixing:"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
with console.status(
|
|
35
|
+
f"[{console.INFO_STYLE}]Fixing unit tests issue for functional requirement {render_context.frid_context.frid}...\n"
|
|
36
|
+
):
|
|
37
|
+
response_files = render_context.codeplain_api.fix_unittests_issue(
|
|
38
|
+
render_context.frid_context.frid,
|
|
39
|
+
render_context.plain_source_tree,
|
|
40
|
+
render_context.frid_context.linked_resources,
|
|
41
|
+
existing_files_content,
|
|
42
|
+
previous_unittests_issue,
|
|
43
|
+
render_context.run_state,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
_, changed_files = file_utils.update_build_folder_with_rendered_files(
|
|
47
|
+
render_context.args.build_folder, existing_files, response_files
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
render_context.unit_tests_running_context.changed_files.update(changed_files)
|
|
51
|
+
|
|
52
|
+
if render_context.args.verbose:
|
|
53
|
+
console.print_files(
|
|
54
|
+
"Files fixed:", render_context.args.build_folder, response_files, style=console.OUTPUT_STYLE
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import file_utils
|
|
4
|
+
import git_utils
|
|
5
|
+
import plain_spec
|
|
6
|
+
from plain2code_console import console
|
|
7
|
+
from render_machine.actions.base_action import BaseAction
|
|
8
|
+
from render_machine.render_context import RenderContext
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PrepareRepositories(BaseAction):
|
|
12
|
+
SUCCESSFUL_OUTCOME = "repositories_prepared"
|
|
13
|
+
|
|
14
|
+
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
15
|
+
|
|
16
|
+
if render_context.args.render_range is not None and render_context.args.render_range[
|
|
17
|
+
0
|
|
18
|
+
] != plain_spec.get_first_frid(render_context.plain_source_tree):
|
|
19
|
+
frid = render_context.args.render_range[0]
|
|
20
|
+
|
|
21
|
+
render_context.starting_frid = frid
|
|
22
|
+
|
|
23
|
+
previous_frid = plain_spec.get_previous_frid(render_context.plain_source_tree, frid)
|
|
24
|
+
|
|
25
|
+
if render_context.args.verbose:
|
|
26
|
+
console.info(f"Reverting code to version implemented for {previous_frid}.")
|
|
27
|
+
|
|
28
|
+
git_utils.revert_to_commit_with_frid(render_context.args.build_folder, previous_frid)
|
|
29
|
+
# conformance tests are still not fully implemented
|
|
30
|
+
if render_context.args.render_conformance_tests:
|
|
31
|
+
git_utils.revert_to_commit_with_frid(render_context.args.conformance_tests_folder, previous_frid)
|
|
32
|
+
else:
|
|
33
|
+
if render_context.args.verbose:
|
|
34
|
+
console.info("Initializing git repositories for the render folders.")
|
|
35
|
+
|
|
36
|
+
git_utils.init_git_repo(render_context.args.build_folder)
|
|
37
|
+
|
|
38
|
+
if render_context.args.base_folder:
|
|
39
|
+
file_utils.copy_folder_content(render_context.args.base_folder, render_context.args.build_folder)
|
|
40
|
+
git_utils.add_all_files_and_commit(
|
|
41
|
+
render_context.args.build_folder,
|
|
42
|
+
git_utils.BASE_FOLDER_COMMIT_MESSAGE,
|
|
43
|
+
None,
|
|
44
|
+
render_context.run_state.render_id,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if render_context.args.render_conformance_tests:
|
|
48
|
+
git_utils.init_git_repo(render_context.args.conformance_tests_folder)
|
|
49
|
+
|
|
50
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import render_machine.render_utils as render_utils
|
|
4
|
+
from plain2code_console import console
|
|
5
|
+
from render_machine.actions.base_action import BaseAction
|
|
6
|
+
from render_machine.render_context import RenderContext
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PrepareTestingEnvironment(BaseAction):
|
|
10
|
+
SUCCESSFUL_OUTCOME = "testing_environment_prepared"
|
|
11
|
+
FAILED_OUTCOME = "testing_environment_preparation_failed"
|
|
12
|
+
|
|
13
|
+
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
14
|
+
if render_context.args.verbose:
|
|
15
|
+
console.info(
|
|
16
|
+
f"[b]Running testing environment preparation script {render_context.args.prepare_environment_script} for build folder {render_context.args.build_folder}.[/b]"
|
|
17
|
+
)
|
|
18
|
+
exit_code, _ = render_utils.execute_script(
|
|
19
|
+
render_context.args.prepare_environment_script,
|
|
20
|
+
[render_context.args.build_folder],
|
|
21
|
+
render_context.args.verbose,
|
|
22
|
+
"Testing Environment Preparation",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
render_context.conformance_tests_running_context.should_prepare_testing_environment = False
|
|
26
|
+
|
|
27
|
+
if exit_code == 0:
|
|
28
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
29
|
+
else:
|
|
30
|
+
return self.FAILED_OUTCOME, None
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import file_utils
|
|
4
|
+
from plain2code_console import console
|
|
5
|
+
from render_machine.actions.base_action import BaseAction
|
|
6
|
+
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
|
|
7
|
+
from render_machine.render_context import RenderContext
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RefactorCode(BaseAction):
|
|
11
|
+
SUCCESSFUL_OUTCOME = "refactoring_successful"
|
|
12
|
+
NO_FILES_REFACTORED_OUTCOME = "no_files_refactored"
|
|
13
|
+
|
|
14
|
+
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
15
|
+
existing_files, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(render_context)
|
|
16
|
+
|
|
17
|
+
if render_context.args.verbose:
|
|
18
|
+
console.info(f"\nRefactoring iteration {render_context.frid_context.refactoring_iteration}.")
|
|
19
|
+
|
|
20
|
+
if render_context.args.verbose:
|
|
21
|
+
console.print_files(
|
|
22
|
+
"Files sent as input for refactoring:",
|
|
23
|
+
render_context.args.build_folder,
|
|
24
|
+
existing_files_content,
|
|
25
|
+
style=console.INPUT_STYLE,
|
|
26
|
+
)
|
|
27
|
+
with console.status(
|
|
28
|
+
f"[{console.INFO_STYLE}]Refactoring the generated code for functional requirement {render_context.frid_context.frid}...\n"
|
|
29
|
+
):
|
|
30
|
+
response_files = render_context.codeplain_api.refactor_source_files_if_needed(
|
|
31
|
+
frid=render_context.frid_context.frid,
|
|
32
|
+
files_to_check=render_context.frid_context.changed_files,
|
|
33
|
+
existing_files_content=existing_files_content,
|
|
34
|
+
run_state=render_context.run_state,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
if len(response_files) == 0:
|
|
38
|
+
if render_context.args.verbose:
|
|
39
|
+
console.info("No files refactored.")
|
|
40
|
+
return self.NO_FILES_REFACTORED_OUTCOME, None
|
|
41
|
+
|
|
42
|
+
file_utils.store_response_files(render_context.args.build_folder, response_files, existing_files)
|
|
43
|
+
|
|
44
|
+
if render_context.args.verbose:
|
|
45
|
+
console.print_files(
|
|
46
|
+
"Files refactored:", render_context.args.build_folder, response_files, style=console.OUTPUT_STYLE
|
|
47
|
+
)
|
|
48
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import file_utils
|
|
5
|
+
import plain_spec
|
|
6
|
+
from plain2code_console import console
|
|
7
|
+
from render_machine.actions.base_action import BaseAction
|
|
8
|
+
from render_machine.conformance_test_helpers import ConformanceTestHelpers
|
|
9
|
+
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
|
|
10
|
+
from render_machine.render_context import RenderContext
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RenderConformanceTests(BaseAction):
|
|
14
|
+
SUCCESSFUL_OUTCOME = "conformance_test_rendered"
|
|
15
|
+
|
|
16
|
+
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
17
|
+
if self._should_render_conformance_tests(render_context):
|
|
18
|
+
return self._render_conformance_tests(render_context)
|
|
19
|
+
else:
|
|
20
|
+
return self._render_acceptance_test(render_context)
|
|
21
|
+
|
|
22
|
+
def _should_render_conformance_tests(self, render_context: RenderContext) -> bool:
|
|
23
|
+
return render_context.conformance_tests_running_context.conformance_test_phase_index == 0
|
|
24
|
+
|
|
25
|
+
def _render_conformance_tests(self, render_context: RenderContext):
|
|
26
|
+
existing_conformance_test_folder_names = ConformanceTestHelpers.fetch_existing_conformance_test_folder_names(
|
|
27
|
+
render_context.args.conformance_tests_folder
|
|
28
|
+
)
|
|
29
|
+
if render_context.args.verbose:
|
|
30
|
+
console.info("\n[b]Implementing test requirements:[/b]")
|
|
31
|
+
console.print_list(
|
|
32
|
+
render_context.conformance_tests_running_context.current_testing_frid_specifications[
|
|
33
|
+
plain_spec.TEST_REQUIREMENTS
|
|
34
|
+
],
|
|
35
|
+
style=console.INFO_STYLE,
|
|
36
|
+
)
|
|
37
|
+
console.info()
|
|
38
|
+
if not ConformanceTestHelpers.current_conformance_tests_exist(render_context.conformance_tests_running_context): # type: ignore
|
|
39
|
+
with console.status(
|
|
40
|
+
f"[{console.INFO_STYLE}]Generating folder name for conformance tests for functional requirement {render_context.conformance_tests_running_context.current_testing_frid}...\n"
|
|
41
|
+
):
|
|
42
|
+
fr_subfolder_name = render_context.codeplain_api.generate_folder_name_from_functional_requirement(
|
|
43
|
+
frid=render_context.conformance_tests_running_context.current_testing_frid,
|
|
44
|
+
functional_requirement=render_context.conformance_tests_running_context.current_testing_frid_specifications[
|
|
45
|
+
plain_spec.FUNCTIONAL_REQUIREMENTS
|
|
46
|
+
][
|
|
47
|
+
-1
|
|
48
|
+
],
|
|
49
|
+
existing_folder_names=existing_conformance_test_folder_names,
|
|
50
|
+
run_state=render_context.run_state,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
conformance_tests_folder_name = os.path.join(
|
|
54
|
+
render_context.args.conformance_tests_folder, fr_subfolder_name
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
if render_context.args.verbose:
|
|
58
|
+
console.info(f"Storing conformance test files in subfolder {conformance_tests_folder_name}/")
|
|
59
|
+
|
|
60
|
+
render_context.conformance_tests_running_context.conformance_tests_json[
|
|
61
|
+
render_context.conformance_tests_running_context.current_testing_frid
|
|
62
|
+
] = {
|
|
63
|
+
"folder_name": conformance_tests_folder_name,
|
|
64
|
+
"functional_requirement": render_context.frid_context.specifications[
|
|
65
|
+
plain_spec.FUNCTIONAL_REQUIREMENTS
|
|
66
|
+
][-1],
|
|
67
|
+
}
|
|
68
|
+
else:
|
|
69
|
+
conformance_tests_folder_name = ConformanceTestHelpers.get_current_conformance_test_folder_name(
|
|
70
|
+
render_context.conformance_tests_running_context # type: ignore
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
_, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(render_context)
|
|
74
|
+
if render_context.args.verbose:
|
|
75
|
+
tmp_resources_list = []
|
|
76
|
+
plain_spec.collect_linked_resources(
|
|
77
|
+
render_context.plain_source_tree,
|
|
78
|
+
tmp_resources_list,
|
|
79
|
+
[
|
|
80
|
+
plain_spec.DEFINITIONS,
|
|
81
|
+
plain_spec.TEST_REQUIREMENTS,
|
|
82
|
+
plain_spec.FUNCTIONAL_REQUIREMENTS,
|
|
83
|
+
],
|
|
84
|
+
False,
|
|
85
|
+
render_context.frid_context.frid,
|
|
86
|
+
)
|
|
87
|
+
console.print_resources(tmp_resources_list, render_context.frid_context.linked_resources)
|
|
88
|
+
|
|
89
|
+
console.print_files(
|
|
90
|
+
"Files sent as input for generating conformance tests:",
|
|
91
|
+
render_context.args.build_folder,
|
|
92
|
+
existing_files_content,
|
|
93
|
+
style=console.INPUT_STYLE,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
all_acceptance_tests = render_context.frid_context.specifications.get(plain_spec.ACCEPTANCE_TESTS, [])
|
|
97
|
+
with console.status(
|
|
98
|
+
f"[{console.INFO_STYLE}]Rendering conformance test for functional requirement {render_context.conformance_tests_running_context.current_testing_frid}...\n"
|
|
99
|
+
):
|
|
100
|
+
response_files, implementation_plan_summary = render_context.codeplain_api.render_conformance_tests(
|
|
101
|
+
render_context.frid_context.frid,
|
|
102
|
+
render_context.conformance_tests_running_context.current_testing_frid,
|
|
103
|
+
render_context.plain_source_tree,
|
|
104
|
+
render_context.frid_context.linked_resources,
|
|
105
|
+
existing_files_content,
|
|
106
|
+
conformance_tests_folder_name,
|
|
107
|
+
render_context.conformance_tests_running_context.conformance_tests_json,
|
|
108
|
+
all_acceptance_tests,
|
|
109
|
+
render_context.run_state,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
render_context.conformance_tests_running_context.current_testing_frid_high_level_implementation_plan = (
|
|
113
|
+
implementation_plan_summary
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
file_utils.store_response_files(conformance_tests_folder_name, response_files, [])
|
|
117
|
+
|
|
118
|
+
if render_context.args.verbose:
|
|
119
|
+
console.print_files(
|
|
120
|
+
"Conformance test files generated:",
|
|
121
|
+
conformance_tests_folder_name,
|
|
122
|
+
response_files,
|
|
123
|
+
style=console.OUTPUT_STYLE,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
127
|
+
|
|
128
|
+
def _render_acceptance_test(self, render_context: RenderContext):
|
|
129
|
+
_, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(render_context)
|
|
130
|
+
(
|
|
131
|
+
conformance_tests_files,
|
|
132
|
+
conformance_tests_files_content,
|
|
133
|
+
) = ConformanceTestHelpers.fetch_existing_conformance_test_files(
|
|
134
|
+
render_context.conformance_tests_running_context # type: ignore
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
acceptance_test = render_context.frid_context.specifications[plain_spec.ACCEPTANCE_TESTS][
|
|
138
|
+
render_context.conformance_tests_running_context.conformance_test_phase_index - 1
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
if render_context.args.verbose:
|
|
142
|
+
console.info("\n[b]Generating acceptance test:[/b]")
|
|
143
|
+
console.info(f"[b]{acceptance_test}[/b]")
|
|
144
|
+
console.info()
|
|
145
|
+
|
|
146
|
+
with console.status(
|
|
147
|
+
f"[{console.INFO_STYLE}]Generating acceptance test for functional requirement {render_context.frid_context.frid}...\n"
|
|
148
|
+
):
|
|
149
|
+
response_files = render_context.codeplain_api.render_acceptance_tests(
|
|
150
|
+
render_context.frid_context.frid,
|
|
151
|
+
render_context.plain_source_tree,
|
|
152
|
+
render_context.frid_context.linked_resources,
|
|
153
|
+
existing_files_content,
|
|
154
|
+
conformance_tests_files_content,
|
|
155
|
+
acceptance_test,
|
|
156
|
+
render_context.run_state,
|
|
157
|
+
)
|
|
158
|
+
conformance_tests_folder_name = ConformanceTestHelpers.get_current_conformance_test_folder_name(
|
|
159
|
+
render_context.conformance_tests_running_context # type: ignore
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
file_utils.store_response_files(conformance_tests_folder_name, response_files, conformance_tests_files)
|
|
163
|
+
console.print_files(
|
|
164
|
+
f"Conformance test files in folder {conformance_tests_folder_name} updated:",
|
|
165
|
+
conformance_tests_folder_name,
|
|
166
|
+
response_files,
|
|
167
|
+
style=console.OUTPUT_STYLE,
|
|
168
|
+
)
|
|
169
|
+
return self.SUCCESSFUL_OUTCOME, None
|