Skip to content

Commit a7f0429

Browse files
authored
Merge pull request #16 from Codeplain-ai/release/06-30
Minor bugfixes and improvements
2 parents ea68717 + d933f84 commit a7f0429

File tree

6 files changed

+75
-57
lines changed

6 files changed

+75
-57
lines changed

codeplain_REST_api.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from plain2code_state import RunState
88

9-
MAX_RETRIES = 3
9+
MAX_RETRIES = 4
1010
RETRY_DELAY = 3
1111

1212

@@ -131,7 +131,9 @@ def post_request(self, endpoint_url, headers, payload, run_state: Optional[RunSt
131131
retry_delay *= 2
132132
else:
133133
self.console.error(f"Max retries ({MAX_RETRIES}) exceeded. Last error: {e}")
134-
raise type(e)(f"Error requesting to the codeplain API: {e}")
134+
raise RequestException(
135+
f"Connection error: Unable to reach the Codeplain API at {self.api_url}. Please try again or contact support."
136+
)
135137

136138
def get_plain_source_tree(self, plain_source, loaded_templates):
137139
"""

examples/example_hello_world_golang/run.sh

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@ if [ $VERBOSE -eq 1 ]; then
1111
echo "Running Go lang hello world example in verbose mode."
1212
fi
1313

14-
# Check if render-range and render-from exist in config.yaml
15-
if ! (grep -q "render-range:" $CONFIG_FILE || grep -q "render-from:" $CONFIG_FILE); then
16-
echo "Removing conformance tests folder"
17-
rm -rf conformance_tests
18-
fi
19-
2014
# Execute the command
2115
python ../../plain2code.py hello_world_golang.plain
2216

examples/example_hello_world_python/run.sh

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ if [ $VERBOSE -eq 1 ]; then
1010
echo "Running the hello world example for Python in verbose mode."
1111
fi
1212

13-
# Check if render-range and render-from exist in config.yaml
14-
if ! (grep -q "render-range:" $CONFIG_FILE || grep -q "render-from:" $CONFIG_FILE); then
15-
echo "Removing conformance tests folder"
16-
rm -rf conformance_tests
17-
fi
18-
1913
# Execute the command
2014
python ../../plain2code.py hello_world_python.plain
2115

examples/example_hello_world_react/run.sh

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,6 @@ if [ $VERBOSE -eq 1 ]; then
1111
echo "Running the hello world example for React in verbose mode."
1212
fi
1313

14-
# Check if render-range and render-from exist in config.yaml
15-
if ! (grep -q "render-range:" $CONFIG_FILE || grep -q "render-from:" $CONFIG_FILE); then
16-
echo "Removing conformance tests folder"
17-
rm -rf conformance_tests
18-
rm -rf node_conformance_tests
19-
fi
20-
2114
# Execute the command
2215
python ../../plain2code.py hello_world_react.plain
2316

git_utils.py

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
import os
2-
from typing import Union
2+
from typing import Optional, Union
33

44
from git import Repo
55

66
import file_utils
77

8-
RENDERED_FRID_MESSAGE = "Changes related to Functional requirement ID (FRID): {}"
9-
RENDER_ID_MESSAGE = "Render ID: {}"
10-
BASE_FOLDER_COMMIT_MESSAGE = "Initialize build with Base Folder content"
11-
REFACTORED_CODE_COMMIT_MESSAGE = "Refactored code after implementing {}"
8+
INITIAL_COMMIT_MESSAGE = "[Codeplain] Initial commit"
9+
BASE_FOLDER_COMMIT_MESSAGE = "[Codeplain] Initialize build with Base Folder content"
10+
REFACTORED_CODE_COMMIT_MESSAGE = "[Codeplain] Refactored code after implementing {}"
1211
CONFORMANCE_TESTS_PASSED_COMMIT_MESSAGE = (
13-
"Fixed issues in the implementation code identified during conformance testing"
12+
"[Codeplain] Fixed issues in the implementation code identified during conformance testing"
1413
)
15-
FUNCTIONAL_REQUIREMENT_FINISHED_COMMIT_MESSAGE = "Functional requirement ID (FRID): {} fully implemented"
14+
FUNCTIONAL_REQUIREMENT_FINISHED_COMMIT_MESSAGE = "[Codeplain] Functional requirement ID (FRID):{} fully implemented"
15+
16+
RENDERED_FRID_MESSAGE = "Changes related to Functional requirement ID (FRID): {}"
17+
RENDER_ID_MESSAGE = "Render ID: {}"
18+
1619

17-
# The commit hash of the empty tree
18-
EMPTY_TREE_COMMIT_HASH = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
20+
class InvalidGitRepositoryError(Exception):
21+
"""Raised when the git repository is in an invalid state."""
22+
23+
pass
1924

2025

2126
def init_git_repo(path_to_repo: Union[str, os.PathLike]) -> Repo:
@@ -30,6 +35,7 @@ def init_git_repo(path_to_repo: Union[str, os.PathLike]) -> Repo:
3035
os.makedirs(path_to_repo)
3136

3237
repo = Repo.init(path_to_repo)
38+
repo.git.commit("--allow-empty", "-m", INITIAL_COMMIT_MESSAGE)
3339

3440
return repo
3541

@@ -74,10 +80,23 @@ def revert_changes(repo_path: Union[str, os.PathLike]) -> Repo:
7480
return repo
7581

7682

77-
def revert_to_commit_with_frid(repo_path: Union[str, os.PathLike], frid: str) -> Repo:
78-
"""Finds commit with given frid mentioned in the commit message and reverts the branch to it."""
83+
def revert_to_commit_with_frid(repo_path: Union[str, os.PathLike], frid: Optional[str] = None) -> Repo:
84+
"""
85+
Finds commit with given frid mentioned in the commit message and reverts the branch to it.
86+
87+
If frid argument is not provided (None), repo is reverted to the initial state. In case the base folder doesn't exist,
88+
code is reverted to the initial repo commit. Otherwise, the repo is reverted to the base folder commit.
89+
90+
It is expected that the repo has at least one commit related to provided frid if frid is not None.
91+
In case the frid related commit is not found, an exception is raised.
92+
"""
7993
repo = Repo(repo_path)
80-
commit = _get_commit_with_frid(repo, frid)
94+
95+
commit = _get_commit(repo, frid)
96+
97+
if not commit:
98+
raise InvalidGitRepositoryError("Git repository is in an invalid state. Relevant commit could not be found.")
99+
81100
repo.git.reset("--hard", commit)
82101
repo.git.clean("-xdf")
83102
return repo
@@ -99,20 +118,13 @@ def diff(repo_path: Union[str, os.PathLike], previous_frid: str = None) -> dict:
99118
"""
100119
repo = Repo(repo_path)
101120

102-
if previous_frid:
103-
commit = _get_commit_with_frid(repo, previous_frid)
104-
else:
105-
commit = _get_base_folder_commit(repo)
121+
commit = _get_commit(repo, previous_frid)
106122

107123
# Add all files to the index to get a clean diff
108124
repo.git.add("-N", ".")
109125

110126
# Get the raw git diff output, excluding .pyc files
111-
if not commit:
112-
# If there is no base commit, we are listing all files as new
113-
diff_output = repo.git.diff(EMPTY_TREE_COMMIT_HASH, "--text", ":!*.pyc")
114-
else:
115-
diff_output = repo.git.diff(commit, "--text", ":!*.pyc")
127+
diff_output = repo.git.diff(commit, "--text", ":!*.pyc")
116128

117129
if not diff_output:
118130
return {}
@@ -165,18 +177,37 @@ def diff(repo_path: Union[str, os.PathLike], previous_frid: str = None) -> dict:
165177
return diff_dict
166178

167179

180+
def _get_commit(repo: Repo, frid: str = None) -> str:
181+
if frid:
182+
commit = _get_commit_with_frid(repo, frid)
183+
else:
184+
commit = _get_base_folder_commit(repo)
185+
if not commit:
186+
commit = _get_initial_commit(repo)
187+
188+
return commit
189+
190+
168191
def _get_commit_with_frid(repo: Repo, frid: str) -> str:
169192
"""Finds commit with given frid mentioned in the commit message."""
170-
current_branch = repo.active_branch.name
171-
commit = repo.git.rev_list(
172-
current_branch, "--grep", FUNCTIONAL_REQUIREMENT_FINISHED_COMMIT_MESSAGE.format(frid), "-n", "1"
173-
)
193+
commit = _get_commit_with_message(repo, FUNCTIONAL_REQUIREMENT_FINISHED_COMMIT_MESSAGE.format(frid))
174194
if not commit:
175-
raise Exception(f"No commit with frid {frid} found.")
195+
raise InvalidGitRepositoryError(f"No commit with frid {frid} found.")
176196
return commit
177197

178198

179199
def _get_base_folder_commit(repo: Repo) -> str:
180200
"""Finds commit related to copy of the base folder."""
181-
current_branch = repo.active_branch.name
182-
return repo.git.rev_list(current_branch, "--grep", BASE_FOLDER_COMMIT_MESSAGE, "-n", "1")
201+
return _get_commit_with_message(repo, BASE_FOLDER_COMMIT_MESSAGE)
202+
203+
204+
def _get_initial_commit(repo: Repo) -> str:
205+
"""Finds initial commit."""
206+
return _get_commit_with_message(repo, INITIAL_COMMIT_MESSAGE)
207+
208+
209+
def _get_commit_with_message(repo: Repo, message: str) -> str:
210+
"""Finds commit with given message."""
211+
escaped_message = message.replace("[", "\\[").replace("]", "\\]")
212+
213+
return repo.git.rev_list(repo.active_branch.name, "--grep", escaped_message, "-n", "1")

plain2code.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import yaml
1111
from liquid2.exceptions import TemplateNotFoundError
12+
from requests.exceptions import RequestException
1213

1314
import file_utils
1415
import git_utils
@@ -584,11 +585,8 @@ def conformance_and_acceptance_testing( # noqa: C901
584585
if args.verbose:
585586
console.info(f"Running conformance tests attempt {conformance_tests_run_count}.")
586587

587-
if frid == plain_spec.get_first_frid(plain_source_tree):
588-
code_diff = git_utils.diff(args.build_folder)
589-
else:
590-
# full diff between the previous frid and the current frid (including refactoring commits)
591-
code_diff = git_utils.diff(args.build_folder, plain_spec.get_previous_frid(plain_source_tree, frid))
588+
# full diff between the previous frid and the current frid (including refactoring commits)
589+
code_diff = git_utils.diff(args.build_folder, plain_spec.get_previous_frid(plain_source_tree, frid))
592590

593591
[
594592
success,
@@ -794,6 +792,8 @@ def render_functional_requirement( # noqa: C901
794792

795793
return
796794

795+
previous_frid = plain_spec.get_previous_frid(plain_source_tree, frid)
796+
797797
functional_requirement_render_attempt = 0
798798
while True:
799799
existing_files = file_utils.list_all_text_files(args.build_folder)
@@ -895,7 +895,7 @@ def render_functional_requirement( # noqa: C901
895895
"Unittests could not be fixed after rendering the functional requirement. "
896896
f"Restarting rendering the functional requirement {frid} from scratch."
897897
)
898-
git_utils.revert_changes(args.build_folder)
898+
git_utils.revert_to_commit_with_frid(args.build_folder, previous_frid)
899899
continue
900900

901901
exit_with_error(
@@ -991,10 +991,11 @@ def render_functional_requirement( # noqa: C901
991991

992992
if should_rerender_functional_requirement:
993993
# Restore the code state to initial
994-
git_utils.revert_changes(args.build_folder)
994+
git_utils.revert_to_commit_with_frid(args.build_folder, previous_frid)
995+
995996
if args.render_conformance_tests:
996997
# Restore the conformance tests state to initial
997-
git_utils.revert_changes(args.conformance_tests_folder)
998+
git_utils.revert_to_commit_with_frid(args.conformance_tests_folder, previous_frid)
998999

9991000
retry_state.mark_failed_conformance_testing_rendering()
10001001

@@ -1208,6 +1209,9 @@ def exit_with_error(message, last_successful_frid=None, render_id=None):
12081209
console.error("Keyboard interrupt")
12091210
# Don't print the traceback here because it's going to be from keyboard interrupt and we don't really care about that
12101211
console.debug(f"Render ID: {run_state.render_id}")
1212+
except RequestException as e:
1213+
console.error(f"Error rendering plain code: {str(e)}\n")
1214+
console.debug(f"Render ID: {run_state.render_id}")
12111215
except Exception as e:
12121216
console.error(f"Error rendering plain code: {str(e)}\n")
12131217
console.debug(f"Render ID: {run_state.render_id}")

0 commit comments

Comments
 (0)