Skip to content

Commit 6b64fbf

Browse files
authored
Merge branch 'main' into improve-readme
2 parents 8d035d8 + 01b7e94 commit 6b64fbf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1116
-733
lines changed

codeflash/api/cfapi.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from typing import TYPE_CHECKING, Any, Optional
99

1010
import requests
11+
import sentry_sdk
1112
from pydantic.json import pydantic_encoder
1213

1314
from codeflash.cli_cmds.console import console, logger
@@ -194,7 +195,8 @@ def get_blocklisted_functions() -> dict[str, set[str]] | dict[str, Any]:
194195
req.raise_for_status()
195196
content: dict[str, list[str]] = req.json()
196197
except Exception as e:
197-
logger.error(f"Error getting blocklisted functions: {e}", exc_info=True)
198+
logger.error(f"Error getting blocklisted functions: {e}")
199+
sentry_sdk.capture_exception(e)
198200
return {}
199201

200202
return {Path(k).name: {v.replace("()", "") for v in values} for k, values in content.items()}

codeflash/cli_cmds/cli.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,22 @@ def process_pyproject_config(args: Namespace) -> Namespace:
128128
assert args.tests_root is not None, "--tests-root must be specified"
129129
assert Path(args.tests_root).is_dir(), f"--tests-root {args.tests_root} must be a valid directory"
130130

131-
assert not (env_utils.get_pr_number() is not None and not env_utils.ensure_codeflash_api_key()), (
132-
"Codeflash API key not found. When running in a Github Actions Context, provide the "
133-
"'CODEFLASH_API_KEY' environment variable as a secret.\n"
134-
"You can add a secret by going to your repository's settings page, then clicking 'Secrets' in the left sidebar.\n"
135-
"Then, click 'New repository secret' and add your api key with the variable name CODEFLASH_API_KEY.\n"
136-
f"Here's a direct link: {get_github_secrets_page_url()}\n"
137-
"Exiting..."
138-
)
131+
if env_utils.get_pr_number() is not None:
132+
assert env_utils.ensure_codeflash_api_key(), (
133+
"Codeflash API key not found. When running in a Github Actions Context, provide the "
134+
"'CODEFLASH_API_KEY' environment variable as a secret.\n"
135+
"You can add a secret by going to your repository's settings page, then clicking 'Secrets' in the left sidebar.\n"
136+
"Then, click 'New repository secret' and add your api key with the variable name CODEFLASH_API_KEY.\n"
137+
f"Here's a direct link: {get_github_secrets_page_url()}\n"
138+
"Exiting..."
139+
)
140+
141+
repo = git.Repo(search_parent_directories=True)
142+
143+
owner, repo_name = get_repo_owner_and_name(repo)
144+
145+
require_github_app_or_exit(owner, repo_name)
146+
139147
if hasattr(args, "ignore_paths") and args.ignore_paths is not None:
140148
normalized_ignore_paths = []
141149
for path in args.ignore_paths:

codeflash/cli_cmds/cmd_init.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,27 @@ def init_codeflash() -> None:
6767

6868
did_add_new_key = prompt_api_key()
6969

70-
setup_info: SetupInfo = collect_setup_info()
70+
if should_modify_pyproject_toml():
7171

72-
configure_pyproject_toml(setup_info)
72+
setup_info: SetupInfo = collect_setup_info()
73+
74+
configure_pyproject_toml(setup_info)
7375

7476
install_github_app()
7577

7678
install_github_actions(override_formatter_check=True)
7779

80+
module_string = ""
81+
if "setup_info" in locals():
82+
module_string = f" you selected ({setup_info.module_root})"
83+
84+
7885
click.echo(
7986
f"{LF}"
8087
f"⚡️ Codeflash is now set up! You can now run:{LF}"
8188
f" codeflash --file <path-to-file> --function <function-name> to optimize a function within a file{LF}"
8289
f" codeflash --file <path-to-file> to optimize all functions in a file{LF}"
83-
f" codeflash --all to optimize all functions in all files in the module you selected ({setup_info.module_root}){LF}"
90+
f" codeflash --all to optimize all functions in all files in the module{module_string}{LF}"
8491
f"-or-{LF}"
8592
f" codeflash --help to see all options{LF}"
8693
)
@@ -116,6 +123,30 @@ def ask_run_end_to_end_test(args: Namespace) -> None:
116123
bubble_sort_path, bubble_sort_test_path = create_bubble_sort_file_and_test(args)
117124
run_end_to_end_test(args, bubble_sort_path, bubble_sort_test_path)
118125

126+
def should_modify_pyproject_toml() -> bool:
127+
"""
128+
Check if the current directory contains a valid pyproject.toml file with codeflash config
129+
If it does, ask the user if they want to re-configure it.
130+
"""
131+
from rich.prompt import Confirm
132+
pyproject_toml_path = Path.cwd() / "pyproject.toml"
133+
if not pyproject_toml_path.exists():
134+
return True
135+
try:
136+
config, config_file_path = parse_config_file(pyproject_toml_path)
137+
except Exception as e:
138+
return True
139+
140+
if "module_root" not in config or config["module_root"] is None or not Path(config["module_root"]).is_dir():
141+
return True
142+
if "tests_root" not in config or config["tests_root"] is None or not Path(config["tests_root"]).is_dir():
143+
return True
144+
145+
create_toml = Confirm.ask(
146+
f"✅ A valid Codeflash config already exists in this project. Do you want to re-configure it?", default=False, show_default=True
147+
)
148+
return create_toml
149+
119150

120151
def collect_setup_info() -> SetupInfo:
121152
curdir = Path.cwd()
@@ -362,7 +393,7 @@ def check_for_toml_or_setup_file() -> str | None:
362393
return cast(str, project_name)
363394

364395

365-
def install_github_actions(override_formatter_check: bool=False) -> None:
396+
def install_github_actions(override_formatter_check: bool = False) -> None:
366397
try:
367398
config, config_file_path = parse_config_file(override_formatter_check=override_formatter_check)
368399

codeflash/cli_cmds/console.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,16 @@
77

88
from rich.console import Console
99
from rich.logging import RichHandler
10-
from rich.progress import Progress, SpinnerColumn, TimeElapsedColumn
10+
from rich.progress import (
11+
BarColumn,
12+
MofNCompleteColumn,
13+
Progress,
14+
SpinnerColumn,
15+
TaskProgressColumn,
16+
TextColumn,
17+
TimeElapsedColumn,
18+
TimeRemainingColumn,
19+
)
1120

1221
from codeflash.cli_cmds.console_constants import SPINNER_TYPES
1322
from codeflash.cli_cmds.logging_config import BARE_LOGGING_FORMAT
@@ -22,15 +31,26 @@
2231
console = Console()
2332
logging.basicConfig(
2433
level=logging.INFO,
25-
handlers=[RichHandler(rich_tracebacks=True, markup=False, console=console, show_path=False, show_time=False)],
34+
handlers=[
35+
RichHandler(
36+
rich_tracebacks=True,
37+
markup=False,
38+
console=console,
39+
show_path=False,
40+
show_time=False,
41+
)
42+
],
2643
format=BARE_LOGGING_FORMAT,
2744
)
2845

2946
logger = logging.getLogger("rich")
30-
logging.getLogger('parso').setLevel(logging.WARNING)
47+
logging.getLogger("parso").setLevel(logging.WARNING)
48+
3149

3250
def paneled_text(
33-
text: str, panel_args: dict[str, str | bool] | None = None, text_args: dict[str, str] | None = None
51+
text: str,
52+
panel_args: dict[str, str | bool] | None = None,
53+
text_args: dict[str, str] | None = None,
3454
) -> None:
3555
"""Print text in a panel."""
3656
from rich.panel import Panel
@@ -57,7 +77,9 @@ def code_print(code_str: str) -> None:
5777

5878

5979
@contextmanager
60-
def progress_bar(message: str, *, transient: bool = False) -> Generator[TaskID, None, None]:
80+
def progress_bar(
81+
message: str, *, transient: bool = False
82+
) -> Generator[TaskID, None, None]:
6183
"""Display a progress bar with a spinner and elapsed time."""
6284
progress = Progress(
6385
SpinnerColumn(next(spinners)),
@@ -69,3 +91,25 @@ def progress_bar(message: str, *, transient: bool = False) -> Generator[TaskID,
6991
task = progress.add_task(message, total=None)
7092
with progress:
7193
yield task
94+
95+
96+
@contextmanager
97+
def test_files_progress_bar(
98+
total: int, description: str
99+
) -> Generator[tuple[Progress, TaskID], None, None]:
100+
"""Progress bar for test files."""
101+
with Progress(
102+
SpinnerColumn(next(spinners)),
103+
TextColumn("[progress.description]{task.description}"),
104+
BarColumn(
105+
complete_style="cyan",
106+
finished_style="green",
107+
pulse_style="yellow",
108+
),
109+
MofNCompleteColumn(),
110+
TimeElapsedColumn(),
111+
TimeRemainingColumn(),
112+
transient=True,
113+
) as progress:
114+
task_id = progress.add_task(description, total=total)
115+
yield progress, task_id

codeflash/code_utils/code_replacer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ def replace_functions_in_file(
159159
source_code: str,
160160
original_function_names: list[str],
161161
optimized_code: str,
162-
preexisting_objects: set[tuple[str, tuple[FunctionParent,...]]],
162+
preexisting_objects: set[tuple[str, tuple[FunctionParent, ...]]],
163163
) -> str:
164164
parsed_function_names = []
165165
for original_function_name in original_function_names:
@@ -195,7 +195,7 @@ def replace_functions_and_add_imports(
195195
function_names: list[str],
196196
optimized_code: str,
197197
module_abspath: Path,
198-
preexisting_objects: set[tuple[str, tuple[FunctionParent,...]]],
198+
preexisting_objects: set[tuple[str, tuple[FunctionParent, ...]]],
199199
project_root_path: Path,
200200
) -> str:
201201
return add_needed_imports_from_module(
@@ -211,7 +211,7 @@ def replace_function_definitions_in_module(
211211
function_names: list[str],
212212
optimized_code: str,
213213
module_abspath: Path,
214-
preexisting_objects: set[tuple[str, tuple[FunctionParent,...]]],
214+
preexisting_objects: set[tuple[str, tuple[FunctionParent, ...]]],
215215
project_root_path: Path,
216216
) -> bool:
217217
source_code: str = module_abspath.read_text(encoding="utf8")

codeflash/code_utils/config_parser.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ def find_pyproject_toml(config_file: Path | None = None) -> Path:
3131
raise ValueError(msg)
3232

3333

34-
def parse_config_file(config_file_path: Path | None = None, override_formatter_check: bool=False) -> tuple[dict[str, Any], Path]:
34+
def parse_config_file(
35+
config_file_path: Path | None = None, override_formatter_check: bool = False
36+
) -> tuple[dict[str, Any], Path]:
3537
config_file_path = find_pyproject_toml(config_file_path)
3638
try:
3739
with config_file_path.open("rb") as f:
@@ -85,7 +87,7 @@ def parse_config_file(config_file_path: Path | None = None, override_formatter_c
8587
"In pyproject.toml, Codeflash only supports the 'test-framework' as pytest and unittest."
8688
)
8789
if len(config["formatter-cmds"]) > 0:
88-
#see if this is happening during Github actions setup
90+
#see if this is happening during GitHub actions setup
8991
if not override_formatter_check:
9092
assert config["formatter-cmds"][0] != "your-formatter $file", (
9193
"The formatter command is not set correctly in pyproject.toml. Please set the "

codeflash/code_utils/instrument_existing_tests.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
from codeflash.cli_cmds.console import logger
1010
from codeflash.code_utils.code_utils import get_run_tmp_file, module_name_from_file_path
1111
from codeflash.discovery.functions_to_optimize import FunctionToOptimize
12-
from codeflash.models.models import FunctionParent, TestingMode
13-
from codeflash.verification.test_results import VerificationType
12+
from codeflash.models.models import FunctionParent, TestingMode, VerificationType
1413

1514
if TYPE_CHECKING:
1615
from collections.abc import Iterable

0 commit comments

Comments
 (0)