diff --git a/polyapi/deployables.py b/polyapi/deployables.py index 55dbbd7..b498da8 100644 --- a/polyapi/deployables.py +++ b/polyapi/deployables.py @@ -191,7 +191,9 @@ def write_cache_revision(git_revision: Optional[str] = None) -> None: with open(CACHE_VERSION_FILE, 'w', encoding='utf-8') as file: file.write(git_revision) + def is_cache_up_to_date() -> bool: + """Check if the cached revision matches the current Git revision.""" if not Path(CACHE_VERSION_FILE).exists(): return False with open(CACHE_VERSION_FILE, 'r', encoding='utf-8') as file: @@ -199,21 +201,17 @@ def is_cache_up_to_date() -> bool: git_revision = get_git_revision() return cached_revision == git_revision -def is_cache_up_to_date() -> bool: - """Check if the cached revision matches the current Git revision.""" - cached_revision = get_cache_deployments_revision() - git_revision = get_git_revision() # This function needs to be defined or imported - return cached_revision == git_revision -def write_deploy_comments(deployments: List[Dict]) -> str: - """Generate a string of deployment comments for each deployment.""" +def write_deploy_comments(deployments: list) -> str: + """ + Generate deployment comments for each deployment record. + """ canopy_path = 'polyui/collections' if 'localhost' in os.getenv('POLY_API_BASE_URL', '') else 'canopy/polyui/collections' comments = [] for d in deployments: instance_url = d['instance'].replace(':8000', ':3000') if d['instance'].endswith(':8000') else d['instance'] - comment = f"# Poly deployed @ {d['deployed']} - {d['context']}.{d['name']} - {instance_url}/{canopy_path}/{d['type']}s/{d['id']} - {d['fileRevision']}" - comments.append(comment) - return '\n'.join(comments) + comments.append(f"# Poly deployed @ {d['deployed']} - {d['context']}.{d['name']} - {instance_url}/{canopy_path}/{d['type']}s/{d['id']} - {d['fileRevision']}") + return "\n".join(comments) def print_docstring_function_comment(description: str, args: list, returns: dict) -> str: docstring = f'"""{description}\n\n' @@ -247,8 +245,13 @@ def update_deployment_comments(file_content: str, deployable: dict) -> str: file_content = file_content[:range[0]] + file_content[range[1]:] if deployable['deployments']: deployment_comments = write_deploy_comments(deployable['deployments']) - deployable['deploymentCommentRanges'] = [(0, len(deployment_comments) + 1)] - file_content = f"{deployment_comments}\n{file_content}" + # Add blank line after deployment comments only if file content doesn't start with blank line + if file_content.startswith('\n'): + deployable['deploymentCommentRanges'] = [(0, len(deployment_comments) + 1)] + file_content = f"{deployment_comments}\n{file_content}" + else: + deployable['deploymentCommentRanges'] = [(0, len(deployment_comments) + 2)] + file_content = f"{deployment_comments}\n\n{file_content}" return file_content def update_deployable_function_comments(file_content: str, deployable: dict, disable_docs: bool = False) -> str: @@ -288,13 +291,3 @@ def write_updated_deployable(deployable: dict, disable_docs: bool = False) -> di deployable['fileRevision'] = get_deployable_file_revision(file_contents) return deployable -def write_deploy_comments(deployments: list) -> str: - """ - Generate deployment comments for each deployment record. - """ - canopy_path = 'polyui/collections' if 'localhost' in os.getenv('POLY_API_BASE_URL', '') else 'canopy/polyui/collections' - comments = [] - for d in deployments: - instance_url = d['instance'].replace(':8000', ':3000') if d['instance'].endswith(':8000') else d['instance'] - comments.append(f"# Poly deployed @ {d['deployed']} - {d['context']}.{d['name']} - {instance_url}/{canopy_path}/{d['type']}s/{d['id']} - {d['fileRevision']}") - return "\n".join(comments) \ No newline at end of file diff --git a/polyapi/sync.py b/polyapi/sync.py index 921defa..3349009 100644 --- a/polyapi/sync.py +++ b/polyapi/sync.py @@ -15,8 +15,8 @@ ) DEPLOY_ORDER = [ - 'server-function', 'client-function', + 'server-function', ] def read_file(file_path: str) -> str: @@ -129,7 +129,8 @@ def sync_deployables(dry_run: bool, instance: str | None = None): **deployable, **previous_deployment, "description": deployable["types"]["description"], - "instance": instance + "instance": instance, + "type": deployable["type"] } else: sync_deployment = { **deployable, "instance": instance } diff --git a/tests/test_deployables.py b/tests/test_deployables.py index 80ec742..9788f0b 100644 --- a/tests/test_deployables.py +++ b/tests/test_deployables.py @@ -121,4 +121,68 @@ def test_parse_and_write_deployable_docstring(self): def test_parse_and_overwrite_docstring(self): parsed_deployable = parse_function_code(EXPECTED_SERVER_FN_DOCSTRINGS) updated_file_contents = update_deployable_function_comments(EXPECTED_SERVER_FN_DOCSTRINGS, parsed_deployable) - self.assertEqual(EXPECTED_SERVER_FN_DOCSTRINGS, updated_file_contents) \ No newline at end of file + self.assertEqual(EXPECTED_SERVER_FN_DOCSTRINGS, updated_file_contents) + + def test_deployment_comments_with_imports_at_top(self): + """Test that deployment comments are placed at the very top, before import statements.""" + # File content that starts with imports (no existing deployment comments) + file_with_imports = '''from typing import Dict +from polyapi.typedefs import PolyServerFunction + +polyConfig: PolyServerFunction = { + "name": "foobar", + "context": "testing", + "logsEnabled": True, +} + +def foobar(foo: str, bar: Dict[str, str]) -> int: + """A function that does something really important.""" + print("Okay then!") + return 7 +''' + + expected_with_deployment_comments = '''# Poly deployed @ 2024-11-12T14:43:22.631113 - testing.foobar - https://na1.polyapi.io/canopy/polyui/collections/server-functions/jh23h5g3h5b24jh5b2j3h45v2jhg43v52j3h - 086aedd + +from typing import Dict +from polyapi.typedefs import PolyServerFunction + +polyConfig: PolyServerFunction = { + "name": "foobar", + "context": "testing", + "logsEnabled": True, +} + +def foobar(foo: str, bar: Dict[str, str]) -> int: + """A function that does something really important.""" + print("Okay then!") + return 7 +''' + + test_deployable = parse_function_code(file_with_imports, "foobar") + + # Add a mock deployment to test comment placement + test_deployable["deployments"] = [{ + 'context': 'testing', + 'deployed': '2024-11-12T14:43:22.631113', + 'fileRevision': '086aedd', + 'id': 'jh23h5g3h5b24jh5b2j3h45v2jhg43v52j3h', + 'instance': 'https://na1.polyapi.io', + 'name': 'foobar', + 'type': 'server-function' + }] + + # Update deployment comments this should place comments at the very top + updated_file_contents = update_deployment_comments(file_with_imports, test_deployable) + + self.assertEqual(updated_file_contents, expected_with_deployment_comments) + + # ensure the first line is a deployment comment, not an import + first_line = updated_file_contents.split('\n')[0] + self.assertTrue(first_line.startswith('# Poly deployed @'), + f"Expected deployment comment at top, but first line was: {first_line}") + + # Ensure imports come after the deployment comment and blank line + lines = updated_file_contents.split('\n') + import_line_index = next(i for i, line in enumerate(lines) if line.startswith('from typing import')) + self.assertGreater(import_line_index, 1, + "Import statements should come after deployment comments and blank line") \ No newline at end of file