xcad пре 3 месеци
родитељ
комит
de2b51c86f

+ 115 - 96
archetypes/__main__.py

@@ -17,13 +17,9 @@ from rich.table import Table
 from rich.panel import Panel
 
 # Import CLI components
-from cli.core.template import Template
 from cli.core.collection import VariableCollection
 from cli.core.display import DisplayManager
 from cli.core.exceptions import (
-    TemplateLoadError,
-    TemplateSyntaxError,
-    TemplateValidationError,
     TemplateRenderError,
 )
 
@@ -44,7 +40,7 @@ def setup_logging(log_level: str = "WARNING") -> None:
     numeric_level = getattr(logging, log_level.upper(), None)
     if not isinstance(numeric_level, int):
         raise ValueError(f"Invalid log level: {log_level}")
-    
+
     logging.basicConfig(
         level=numeric_level,
         format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
@@ -54,26 +50,30 @@ def setup_logging(log_level: str = "WARNING") -> None:
 
 class ArchetypeTemplate:
     """Simplified template for testing individual .j2 files."""
-    
+
     def __init__(self, file_path: Path, module_name: str):
         self.file_path = file_path
         self.module_name = module_name
         self.id = file_path.stem  # Filename without extension
         self.template_dir = file_path.parent
-        
+
         # Create a minimal template.yaml in memory
-        self.metadata = type('obj', (object,), {
-            'name': f"Archetype: {self.id}",
-            'description': f"Testing archetype from {file_path.name}",
-            'version': "0.1.0",
-            'author': "Testing",
-            'library': "archetype",
-            'tags': ["archetype", "test"],
-        })()
-        
+        self.metadata = type(
+            "obj",
+            (object,),
+            {
+                "name": f"Archetype: {self.id}",
+                "description": f"Testing archetype from {file_path.name}",
+                "version": "0.1.0",
+                "author": "Testing",
+                "library": "archetype",
+                "tags": ["archetype", "test"],
+            },
+        )()
+
         # Parse spec from module if available
         self.variables = self._load_module_spec()
-    
+
     def _load_module_spec(self) -> Optional[VariableCollection]:
         """Load variable spec from the module and merge with extension.yaml if present."""
         try:
@@ -82,7 +82,7 @@ class ArchetypeTemplate:
                 from cli.modules.compose import spec
                 from collections import OrderedDict
                 import yaml
-                
+
                 # Convert spec to dict if needed
                 if isinstance(spec, (dict, OrderedDict)):
                     spec_dict = OrderedDict(spec)
@@ -90,63 +90,72 @@ class ArchetypeTemplate:
                     # Extract dict from existing VariableCollection (shouldn't happen)
                     spec_dict = OrderedDict()
                 else:
-                    logging.warning(f"Spec for {self.module_name} has unexpected type: {type(spec)}")
+                    logging.warning(
+                        f"Spec for {self.module_name} has unexpected type: {type(spec)}"
+                    )
                     return None
-                
+
                 # Check for extension.yaml in the archetype directory
                 extension_file = self.template_dir / "extension.yaml"
                 if extension_file.exists():
                     try:
-                        with open(extension_file, 'r') as f:
+                        with open(extension_file, "r") as f:
                             extension_vars = yaml.safe_load(f)
-                        
+
                         if extension_vars:
                             # Apply extension defaults to existing variables in their sections
                             # Extension vars that don't exist will be added to a "testing" section
                             applied_count = 0
                             new_vars = {}
-                            
+
                             for var_name, var_spec in extension_vars.items():
                                 found = False
                                 # Search for the variable in existing sections
                                 for section_name, section_data in spec_dict.items():
-                                    if "vars" in section_data and var_name in section_data["vars"]:
+                                    if (
+                                        "vars" in section_data
+                                        and var_name in section_data["vars"]
+                                    ):
                                         # Update the default value for existing variable
                                         if "default" in var_spec:
-                                            section_data["vars"][var_name]["default"] = var_spec["default"]
+                                            section_data["vars"][var_name][
+                                                "default"
+                                            ] = var_spec["default"]
                                             applied_count += 1
                                             found = True
                                             break
-                                
+
                                 # If variable doesn't exist in spec, add it to testing section
                                 if not found:
                                     new_vars[var_name] = var_spec
-                            
+
                             # Add new test-only variables to testing section
                             if new_vars:
                                 if "testing" not in spec_dict:
                                     spec_dict["testing"] = {
                                         "title": "Testing Variables",
                                         "description": "Additional variables for archetype testing",
-                                        "vars": {}
+                                        "vars": {},
                                     }
                                 spec_dict["testing"]["vars"].update(new_vars)
-                            
-                            logging.debug(f"Applied {applied_count} extension defaults, added {len(new_vars)} new test variables from {extension_file}")
+
+                            logging.debug(
+                                f"Applied {applied_count} extension defaults, added {len(new_vars)} new test variables from {extension_file}"
+                            )
                     except Exception as e:
                         logging.warning(f"Failed to load extension.yaml: {e}")
-                
+
                 return VariableCollection(spec_dict)
         except Exception as e:
             logging.warning(f"Could not load spec for module {self.module_name}: {e}")
             return None
-    
+
     def render(self, variables: Optional[Dict[str, Any]] = None) -> Dict[str, str]:
         """Render the single .j2 file using CLI's Template class."""
         # Create a minimal template directory structure in memory
         # by using the Template class's rendering capabilities
         from jinja2 import Environment, FileSystemLoader, StrictUndefined
-        
+
         # Set up Jinja2 environment with the archetype directory
         env = Environment(
             loader=FileSystemLoader(str(self.template_dir)),
@@ -155,11 +164,11 @@ class ArchetypeTemplate:
             lstrip_blocks=True,
             keep_trailing_newline=True,
         )
-        
+
         # Get variable values
         if variables is None:
             variables = {}
-        
+
         # Get default values from spec if available
         if self.variables:
             # Get ALL variable values, not just satisfied ones
@@ -175,15 +184,15 @@ class ArchetypeTemplate:
             final_values = {**spec_values, **variables}
         else:
             final_values = variables
-        
+
         try:
             # Load and render the template
             template = env.get_template(self.file_path.name)
             rendered_content = template.render(**final_values)
-            
+
             # Remove .j2 extension for output filename
-            output_filename = self.file_path.name.replace('.j2', '')
-            
+            output_filename = self.file_path.name.replace(".j2", "")
+
             return {output_filename: rendered_content}
         except Exception as e:
             raise TemplateRenderError(f"Failed to render {self.file_path.name}: {e}")
@@ -192,11 +201,11 @@ class ArchetypeTemplate:
 def find_archetypes(module_name: str) -> List[Path]:
     """Find all .j2 files in the module's archetype directory."""
     module_dir = ARCHETYPES_DIR / module_name
-    
+
     if not module_dir.exists():
         console.print(f"[red]Module directory not found: {module_dir}[/red]")
         return []
-    
+
     # Find all .j2 files
     j2_files = list(module_dir.glob("*.j2"))
     return sorted(j2_files)
@@ -205,98 +214,107 @@ def find_archetypes(module_name: str) -> List[Path]:
 def create_module_commands(module_name: str) -> Typer:
     """Create a Typer app with commands for a specific module."""
     module_app = Typer(help=f"Manage {module_name} archetypes")
-    
+
     @module_app.command()
     def list() -> None:
         """List all archetype files for this module."""
         archetypes = find_archetypes(module_name)
-        
+
         if not archetypes:
             display.display_warning(
                 f"No archetypes found for module '{module_name}'",
-                context=f"directory: {ARCHETYPES_DIR / module_name}"
+                context=f"directory: {ARCHETYPES_DIR / module_name}",
             )
             return
-        
+
         # Create table
-        table = Table(title=f"Archetypes for '{module_name}'", show_header=True, header_style="bold cyan")
+        table = Table(
+            title=f"Archetypes for '{module_name}'",
+            show_header=True,
+            header_style="bold cyan",
+        )
         table.add_column("ID", style="cyan")
         table.add_column("Filename", style="white")
         table.add_column("Size", style="dim")
-        
+
         for archetype_path in archetypes:
             file_size = archetype_path.stat().st_size
             if file_size < 1024:
                 size_str = f"{file_size}B"
             else:
                 size_str = f"{file_size / 1024:.1f}KB"
-            
+
             table.add_row(
                 archetype_path.stem,
                 archetype_path.name,
                 size_str,
             )
-        
+
         console.print(table)
         console.print(f"\n[dim]Found {len(archetypes)} archetype(s)[/dim]")
-    
+
     @module_app.command()
     def show(
         id: str = Argument(..., help="Archetype ID (filename without .j2)"),
     ) -> None:
         """Show details of an archetype file."""
         archetypes = find_archetypes(module_name)
-        
+
         # Find the archetype
         archetype_path = None
         for path in archetypes:
             if path.stem == id:
                 archetype_path = path
                 break
-        
+
         if not archetype_path:
             display.display_error(
-                f"Archetype '{id}' not found",
-                context=f"module '{module_name}'"
+                f"Archetype '{id}' not found", context=f"module '{module_name}'"
             )
             return
-        
+
         # Load archetype
         archetype = ArchetypeTemplate(archetype_path, module_name)
-        
+
         # Display details
         console.print()
-        console.print(Panel(
-            f"[bold]{archetype.metadata.name}[/bold]\n"
-            f"{archetype.metadata.description}\n\n"
-            f"[dim]Module:[/dim] {module_name}\n"
-            f"[dim]File:[/dim] {archetype_path.name}\n"
-            f"[dim]Path:[/dim] {archetype_path}",
-            title="Archetype Details",
-            border_style="cyan",
-        ))
-        
+        console.print(
+            Panel(
+                f"[bold]{archetype.metadata.name}[/bold]\n"
+                f"{archetype.metadata.description}\n\n"
+                f"[dim]Module:[/dim] {module_name}\n"
+                f"[dim]File:[/dim] {archetype_path.name}\n"
+                f"[dim]Path:[/dim] {archetype_path}",
+                title="Archetype Details",
+                border_style="cyan",
+            )
+        )
+
         # Show variables if spec is loaded
         if archetype.variables:
             console.print("\n[bold]Available Variables:[/bold]")
-            
+
             # Access the private _sections attribute
             for section_name, section in archetype.variables._sections.items():
                 if section.variables:
-                    console.print(f"\n[cyan]{section.title or section_name.capitalize()}:[/cyan]")
+                    console.print(
+                        f"\n[cyan]{section.title or section_name.capitalize()}:[/cyan]"
+                    )
                     for var_name, var in section.variables.items():
-                        default = var.value if var.value is not None else "[dim]none[/dim]"
+                        default = (
+                            var.value if var.value is not None else "[dim]none[/dim]"
+                        )
                         console.print(f"  {var_name}: {default}")
         else:
             console.print("\n[yellow]No variable spec loaded for this module[/yellow]")
-        
+
         # Show file content
         console.print("\n[bold]Template Content:[/bold]")
         console.print("─" * 80)
-        with open(archetype_path, 'r') as f:
+        with open(archetype_path, "r") as f:
             console.print(f.read())
         console.print()
-    
+
     @module_app.command()
     def generate(
         id: str = Argument(..., help="Archetype ID (filename without .j2)"),
@@ -313,28 +331,25 @@ def create_module_commands(module_name: str) -> Typer:
         """Generate output from an archetype file (always in preview mode)."""
         # Archetypes ALWAYS run in dry-run mode with content display
         # This is a testing tool - it never writes actual files
-        dry_run = True
-        show_content = True
-        
+
         archetypes = find_archetypes(module_name)
-        
+
         # Find the archetype
         archetype_path = None
         for path in archetypes:
             if path.stem == id:
                 archetype_path = path
                 break
-        
+
         if not archetype_path:
             display.display_error(
-                f"Archetype '{id}' not found",
-                context=f"module '{module_name}'"
+                f"Archetype '{id}' not found", context=f"module '{module_name}'"
             )
             return
-        
+
         # Load archetype
         archetype = ArchetypeTemplate(archetype_path, module_name)
-        
+
         # Parse variable overrides
         variables = {}
         if var:
@@ -343,48 +358,51 @@ def create_module_commands(module_name: str) -> Typer:
                     key, value = var_option.split("=", 1)
                     variables[key] = value
                 else:
-                    console.print(f"[yellow]Warning: Invalid --var format '{var_option}' (use KEY=VALUE)[/yellow]")
-        
+                    console.print(
+                        f"[yellow]Warning: Invalid --var format '{var_option}' (use KEY=VALUE)[/yellow]"
+                    )
+
         # Render the archetype
         try:
             rendered_files = archetype.render(variables)
         except Exception as e:
             display.display_error(
-                f"Failed to render archetype: {e}",
-                context=f"archetype '{id}'"
+                f"Failed to render archetype: {e}", context=f"archetype '{id}'"
             )
             return
-        
+
         # Determine output directory (for display purposes only)
         if directory:
             output_dir = Path(directory)
         else:
             output_dir = Path.cwd()
-        
+
         # Always show preview (archetypes never write files)
         console.print()
         console.print("[bold cyan]Archetype Preview (Testing Mode)[/bold cyan]")
-        console.print("[dim]This tool never writes files - it's for testing template snippets only[/dim]")
+        console.print(
+            "[dim]This tool never writes files - it's for testing template snippets only[/dim]"
+        )
         console.print()
         console.print(f"[dim]Reference directory:[/dim] {output_dir}")
         console.print(f"[dim]Files to preview:[/dim] {len(rendered_files)}")
         console.print()
-        
+
         for filename, content in rendered_files.items():
             full_path = output_dir / filename
             status = "Would overwrite" if full_path.exists() else "Would create"
-            size = len(content.encode('utf-8'))
+            size = len(content.encode("utf-8"))
             console.print(f"  [{status}] {filename} ({size} bytes)")
-        
+
         console.print()
         console.print("[bold]Rendered Content:[/bold]")
         console.print("─" * 80)
         for filename, content in rendered_files.items():
             console.print(content)
-        
+
         console.print()
         display.display_success("Preview complete - no files were written")
-    
+
     return module_app
 
 
@@ -393,7 +411,7 @@ def init_app() -> None:
     # Find all module directories in archetypes/
     if ARCHETYPES_DIR.exists():
         for module_dir in ARCHETYPES_DIR.iterdir():
-            if module_dir.is_dir() and not module_dir.name.startswith(('_', '.')):
+            if module_dir.is_dir() and not module_dir.name.startswith(("_", ".")):
                 module_name = module_dir.name
                 # Register module commands
                 module_app = create_module_commands(module_name)
@@ -413,10 +431,11 @@ def main(
         setup_logging(log_level)
     else:
         logging.disable(logging.CRITICAL)
-    
+
     import click
+
     ctx = click.get_current_context()
-    
+
     if ctx.invoked_subcommand is None:
         console.print(ctx.get_help())
         sys.exit(0)

+ 26 - 20
cli/core/collection.py

@@ -71,7 +71,7 @@ class VariableCollection:
             "key": key,
             "title": data.get("title", key.replace("_", " ").title()),
         }
-        
+
         # Only add optional fields if explicitly provided in the source data
         if "description" in data:
             section_init_data["description"] = data["description"]
@@ -83,7 +83,7 @@ class VariableCollection:
             section_init_data["required"] = True
         if "needs" in data:
             section_init_data["needs"] = data["needs"]
-            
+
         return VariableSection(section_init_data)
 
     def _initialize_variables(
@@ -402,31 +402,31 @@ class VariableCollection:
 
     def reset_disabled_bool_variables(self) -> list[str]:
         """Reset bool variables with unsatisfied dependencies to False.
-        
+
         This ensures that disabled bool variables don't accidentally remain True
         and cause confusion in templates or configuration.
-        
+
         Note: CLI-provided variables are NOT reset here - they are validated
         later in validate_all() to provide better error messages.
-        
+
         Returns:
             List of variable names that were reset
         """
         reset_vars = []
-        
+
         for section_key, section in self._sections.items():
             # Check if section dependencies are satisfied
             section_satisfied = self.is_section_satisfied(section_key)
             is_enabled = section.is_enabled()
-            
+
             for var_name, variable in section.variables.items():
                 # Only process bool variables
                 if variable.type != "bool":
                     continue
-                    
+
                 # Check if variable's own dependencies are satisfied
                 var_satisfied = self.is_variable_satisfied(var_name)
-                
+
                 # If section is disabled OR variable dependencies aren't met, reset to False
                 if not section_satisfied or not is_enabled or not var_satisfied:
                     # Only reset if current value is not already False
@@ -434,11 +434,11 @@ class VariableCollection:
                         # Don't reset CLI-provided variables - they'll be validated later
                         if variable.origin == "cli":
                             continue
-                        
+
                         # Store original value if not already stored (for display purposes)
                         if not hasattr(variable, "_original_disabled"):
                             variable._original_disabled = variable.value
-                        
+
                         variable.value = False
                         reset_vars.append(var_name)
                         logger.debug(
@@ -446,7 +446,7 @@ class VariableCollection:
                             f"(section satisfied: {section_satisfied}, enabled: {is_enabled}, "
                             f"var satisfied: {var_satisfied})"
                         )
-        
+
         return reset_vars
 
     def sort_sections(self) -> None:
@@ -691,12 +691,16 @@ class VariableCollection:
         for section_key, section in self._sections.items():
             section_satisfied = self.is_section_satisfied(section_key)
             is_enabled = section.is_enabled()
-            
+
             for var_name, variable in section.variables.items():
                 # Check CLI-provided bool variables with unsatisfied dependencies
-                if variable.type == "bool" and variable.origin == "cli" and variable.value is not False:
+                if (
+                    variable.type == "bool"
+                    and variable.origin == "cli"
+                    and variable.value is not False
+                ):
                     var_satisfied = self.is_variable_satisfied(var_name)
-                    
+
                     if not section_satisfied or not is_enabled or not var_satisfied:
                         # Build error message with unmet needs (use set to avoid duplicates)
                         unmet_needs = set()
@@ -708,8 +712,12 @@ class VariableCollection:
                             for need in variable.needs:
                                 if not self._is_need_satisfied(need):
                                     unmet_needs.add(need)
-                        
-                        needs_str = ", ".join(sorted(unmet_needs)) if unmet_needs else "dependencies not satisfied"
+
+                        needs_str = (
+                            ", ".join(sorted(unmet_needs))
+                            if unmet_needs
+                            else "dependencies not satisfied"
+                        )
                         errors.append(
                             f"{section.key}.{var_name} (set via CLI to {variable.value} but requires: {needs_str})"
                         )
@@ -893,9 +901,7 @@ class VariableCollection:
 
                 # Special handling for needs (allow explicit null/empty to clear)
                 if "needs" in other_var._explicit_fields:
-                    update["needs"] = (
-                        other_var.needs.copy() if other_var.needs else []
-                    )
+                    update["needs"] = other_var.needs.copy() if other_var.needs else []
 
                 # Special handling for value/default (allow explicit null to clear)
                 if "value" in other_var._explicit_fields:

+ 14 - 9
cli/core/display.py

@@ -205,7 +205,11 @@ class DisplayManager:
             version = (
                 str(template.metadata.version) if template.metadata.version else ""
             )
-            schema = template.schema_version if hasattr(template, 'schema_version') else "1.0"
+            schema = (
+                template.schema_version
+                if hasattr(template, "schema_version")
+                else "1.0"
+            )
 
             # Show library with type indicator and color
             library_name = template.metadata.library or ""
@@ -229,9 +233,7 @@ class DisplayManager:
 
         console.print(table)
 
-    def display_template_details(
-        self, template: Template, template_id: str
-    ) -> None:
+    def display_template_details(self, template: Template, template_id: str) -> None:
         """Display template information panel and variables table.
 
         Args:
@@ -371,7 +373,9 @@ class DisplayManager:
             if template.metadata.version
             else "Not specified"
         )
-        schema = template.schema_version if hasattr(template, 'schema_version') else "1.0"
+        schema = (
+            template.schema_version if hasattr(template, "schema_version") else "1.0"
+        )
         description = template.metadata.description or "No description available"
 
         # Get library information
@@ -456,9 +460,7 @@ class DisplayManager:
         if file_tree.children:
             console.print(file_tree)
 
-    def _display_variables_table(
-        self, template: Template
-    ) -> None:
+    def _display_variables_table(self, template: Template) -> None:
         """Display a table of variables for a template.
 
         All variables and sections are always shown. Disabled sections/variables
@@ -531,7 +533,10 @@ class DisplayManager:
                 # Special case: disabled bool variables show as "original → False"
                 if (is_dimmed or not var_satisfied) and variable.type == "bool":
                     # Show that disabled bool variables are forced to False
-                    if hasattr(variable, "_original_disabled") and variable._original_disabled is not False:
+                    if (
+                        hasattr(variable, "_original_disabled")
+                        and variable._original_disabled is not False
+                    ):
                         orig_val = str(variable._original_disabled)
                         default_val = f"{orig_val} {IconManager.arrow_right()} False"
                     else:

+ 9 - 7
cli/core/module.py

@@ -249,11 +249,13 @@ class Module(ABC):
 
             # Re-sort sections after applying config (toggle values may have changed)
             template.variables.sort_sections()
-            
+
             # Reset disabled bool variables to False to prevent confusion
             reset_vars = template.variables.reset_disabled_bool_variables()
             if reset_vars:
-                logger.debug(f"Reset {len(reset_vars)} disabled bool variables to False")
+                logger.debug(
+                    f"Reset {len(reset_vars)} disabled bool variables to False"
+                )
 
         self._display_template_details(template, id)
 
@@ -651,11 +653,13 @@ class Module(ABC):
         # Re-sort sections after all overrides (toggle values may have changed)
         if template.variables:
             template.variables.sort_sections()
-            
+
             # Reset disabled bool variables to False to prevent confusion
             reset_vars = template.variables.reset_disabled_bool_variables()
             if reset_vars:
-                logger.debug(f"Reset {len(reset_vars)} disabled bool variables to False")
+                logger.debug(
+                    f"Reset {len(reset_vars)} disabled bool variables to False"
+                )
 
         if not quiet:
             self._display_template_details(template, id)
@@ -1284,9 +1288,7 @@ class Module(ABC):
                 f"Template '{id}' could not be loaded: {exc}"
             ) from exc
 
-    def _display_template_details(
-        self, template: Template, id: str
-    ) -> None:
+    def _display_template_details(self, template: Template, id: str) -> None:
         """Display template information panel and variables table.
 
         Args:

+ 3 - 1
cli/core/prompt.py

@@ -87,7 +87,9 @@ class PromptHandler:
                     # Prompt for toggle variable using standard variable prompting logic
                     # This ensures consistent handling of description, extra text, validation hints, etc.
                     current_value = toggle_var.convert(toggle_var.value)
-                    new_value = self._prompt_variable(toggle_var, required=section.required)
+                    new_value = self._prompt_variable(
+                        toggle_var, required=section.required
+                    )
 
                     if new_value != current_value:
                         collected[toggle_var.name] = new_value

+ 5 - 3
cli/core/template.py

@@ -438,10 +438,12 @@ class Template:
             import importlib
 
             module = importlib.import_module(f"cli.modules.{kind}")
-            
+
             # Check if module has schema-specific specs (multi-schema support)
             # Try SCHEMAS constant first (uppercase), then schemas attribute
-            schemas = getattr(module, "SCHEMAS", None) or getattr(module, "schemas", None)
+            schemas = getattr(module, "SCHEMAS", None) or getattr(
+                module, "schemas", None
+            )
             if schemas and schema_version in schemas:
                 spec = schemas[schema_version]
                 logger.debug(
@@ -453,7 +455,7 @@ class Template:
                 logger.debug(
                     f"Loaded and cached module spec for kind '{kind}' (default/no schema mapping)"
                 )
-            
+
             return spec
         except Exception as e:
             raise ValueError(

+ 5 - 2
cli/core/variable.py

@@ -1,10 +1,13 @@
 from __future__ import annotations
 
-from typing import Any, Dict, List, Optional, Set
+from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set
 from urllib.parse import urlparse
 import logging
 import re
 
+if TYPE_CHECKING:
+    from cli.core.section import VariableSection
+
 logger = logging.getLogger(__name__)
 
 TRUE_VALUES = {"true", "1", "yes", "on"}
@@ -408,7 +411,7 @@ class Variable:
 
     def get_parent(self) -> Optional["VariableSection"]:
         """Get the parent VariableSection that contains this variable.
-        
+
         Returns:
             The parent VariableSection if set, None otherwise
         """

+ 1 - 2
cli/modules/compose/spec_v1_1.py

@@ -105,8 +105,7 @@ spec = OrderedDict(
             "title": "Ports",
             "toggle": "ports_enabled",
             "needs": "network_mode=bridge",
-            "vars": {
-            },
+            "vars": {},
         },
         "traefik": {
             "title": "Traefik",

+ 0 - 9
network-v1

@@ -1,9 +0,0 @@
----
-services:
-  test_service:
-    networks:
-      bridge:
-
-networks:
-  bridge:
-    driver: bridge