Skip to content

Commit 202318c

Browse files
Taniya Mathurgudivt
authored andcommitted
Replace fallback logic with sys.exit(1) and add PyYAML auto-install
1 parent e4b787d commit 202318c

File tree

1 file changed

+69
-27
lines changed

1 file changed

+69
-27
lines changed

publish.py

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -934,35 +934,77 @@ def _check_requirements_has_idp_common_pkg(self, func_dir):
934934
def _extract_function_name(self, dir_name, template_path):
935935
"""Extract CloudFormation function name from template by matching CodeUri."""
936936
try:
937+
try:
938+
import yaml
939+
except ImportError:
940+
self.console.print("[yellow]PyYAML not found, installing...[/yellow]")
941+
subprocess.run(
942+
[sys.executable, "-m", "pip", "install", "PyYAML"], check=True
943+
)
944+
import yaml
945+
946+
# Create a custom loader that ignores CloudFormation intrinsic functions
947+
class CFLoader(yaml.SafeLoader):
948+
pass
949+
950+
def construct_unknown(loader, node):
951+
if isinstance(node, yaml.ScalarNode):
952+
return loader.construct_scalar(node)
953+
elif isinstance(node, yaml.SequenceNode):
954+
return loader.construct_sequence(node)
955+
elif isinstance(node, yaml.MappingNode):
956+
return loader.construct_mapping(node)
957+
return None
958+
959+
# Add constructors for CloudFormation intrinsic functions
960+
cf_functions = [
961+
"!Ref",
962+
"!GetAtt",
963+
"!Join",
964+
"!Sub",
965+
"!Select",
966+
"!Split",
967+
"!Base64",
968+
"!GetAZs",
969+
"!ImportValue",
970+
"!FindInMap",
971+
"!Equals",
972+
"!And",
973+
"!Or",
974+
"!Not",
975+
"!If",
976+
"!Condition",
977+
]
978+
979+
for func in cf_functions:
980+
CFLoader.add_constructor(func, construct_unknown)
981+
937982
with open(template_path, "r", encoding="utf-8") as f:
938-
lines = f.readlines()
983+
template = yaml.load(f, Loader=CFLoader)
939984

940-
for i, line in enumerate(lines):
941-
# Look for CodeUri that matches our directory
942-
if "CodeUri:" in line:
943-
code_uri = (
944-
line.split("CodeUri:")[-1].strip().strip("\"'").rstrip("/")
945-
)
946-
code_dir = code_uri.split("/")[-1] if "/" in code_uri else code_uri
947-
948-
if code_dir == dir_name:
949-
# Found matching CodeUri, now look backwards for the resource name
950-
# Look for AWS::Serverless::Function type first
951-
for j in range(i - 1, max(0, i - 50), -1):
952-
if "Type: AWS::Serverless::Function" in lines[j]:
953-
# Found the function type, now look backwards for resource name
954-
for k in range(j - 1, max(0, j - 10), -1):
955-
stripped = lines[k].strip()
956-
# Resource names are at the start of line and end with ':'
957-
if (
958-
stripped
959-
and not stripped.startswith(" ")
960-
and stripped.endswith(":")
961-
):
962-
return stripped.rstrip(":")
963-
break
964-
965-
return dir_name
985+
if not template or not isinstance(template, dict):
986+
raise Exception(f"Failed to parse YAML template: {template_path}")
987+
988+
resources = template.get("Resources", {})
989+
for resource_name, resource_config in resources.items():
990+
if (
991+
resource_config
992+
and isinstance(resource_config, dict)
993+
and resource_config.get("Type") == "AWS::Serverless::Function"
994+
):
995+
properties = resource_config.get("Properties", {})
996+
if properties and isinstance(properties, dict):
997+
code_uri = properties.get("CodeUri", "")
998+
if isinstance(code_uri, str):
999+
code_uri = code_uri.rstrip("/")
1000+
code_dir = (
1001+
code_uri.split("/")[-1] if "/" in code_uri else code_uri
1002+
)
1003+
if code_dir == dir_name:
1004+
return resource_name
1005+
raise Exception(
1006+
f"No CloudFormation function found for directory {dir_name} in template {template_path}"
1007+
)
9661008

9671009
except Exception as e:
9681010
self.console.print(

0 commit comments

Comments
 (0)