Skip to content

Commit 5b0ccca

Browse files
committed
Add skip_if_exists property to YAML configuration and update validation
1 parent 1d46916 commit 5b0ccca

5 files changed

Lines changed: 25 additions & 1 deletion

File tree

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,27 @@ struct generate \
133133

134134
## 📝 YAML Configuration
135135

136-
Here is an example of a YAML configuration file:
136+
### Configuration Properties
137+
138+
When defining your project structure in the YAML configuration file, you can use various properties to control the behavior of the script. Here are the available properties:
139+
140+
- **skip**: If set to `true`, the file or folder will be skipped and not created.
141+
- **skip_if_exists**: If set to `true`, the file or folder will be skipped if it already exists.
142+
- **permissions**: Set custom file permissions using a string representation of the octal value (e.g., `'0777'`).
143+
- **content**: Define the content of the file directly in the YAML configuration.
144+
- **file**: Specify a local or remote file to include. Supported protocols include `file://`, `http://`, `https://`, `github://`, `githubhttps://`, `githubssh://`, `s3://`, and `gs://`.
145+
146+
Example:
137147

138148
```yaml
139149
structure:
140150
- README.md:
151+
skip: true
141152
content: |
142153
# {{@ project_name @}}
143154
This is a template repository.
144155
- script.sh:
156+
skip_if_exists: true
145157
permissions: '0777'
146158
content: |
147159
#!/bin/bash
@@ -185,6 +197,8 @@ variables:
185197
default: "John Doe"
186198
```
187199
200+
These properties allow you to customize the behavior and content of the files and folders generated by the script, providing flexibility and control over your project structure.
201+
188202
### Template variables
189203
190204
You can use template variables in your configuration file by enclosing them in `{{@` and `@}}`. For example, `{{@ project_name @}}` will be replaced with the value of the `project_name` variable at runtime. If this are not set when running the script, it will prompt you to enter the value interactively.

example/structure.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ structure:
66
This is a template repository.
77
- script.sh:
88
permissions: '0777'
9+
skip_if_exists: true
910
content: |
1011
#!/bin/bash
1112
echo "Hello, {{@ author_name @}}!"

struct-schema.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"type": "object",
1212
"properties": {
1313
"skip": { "type": "boolean" },
14+
"skip_if_exists": { "type": "boolean" },
1415
"content": { "type": "string" },
1516
"permissions": { "type": "string" },
1617
"file": { "type": "string", "format": "uri" }

struct_module/commands/validate.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ def _validate_structure_config(self, structure):
110110
raise ValueError(f"The 'prompt' value for '{name}' must be a string.")
111111
if 'skip' in content and not isinstance(content['skip'], bool):
112112
raise ValueError(f"The 'skip' value for '{name}' must be a string.")
113+
if 'skip_if_exists' in content and not isinstance(content['skip_if_exists'], bool):
114+
raise ValueError(f"The 'skip_if_exists' value for '{name}' must be a string.")
113115
elif not isinstance(content, str):
114116
raise ValueError(f"The content of '{name}' must be a string or dictionary.")
115117
self.logger.info("Configuration validation passed.")

struct_module/file_item.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def __init__(self, properties):
2525
self.permissions = properties.get("permissions")
2626
self.input_store = properties.get("input_store")
2727
self.skip = properties.get("skip", False)
28+
self.skip_if_exists = properties.get("skip_if_exists", False)
2829

2930
self.content_fetcher = ContentFetcher()
3031

@@ -121,6 +122,11 @@ def create(self, base_path, dry_run=False, backup_path=None, file_strategy='over
121122
self.logger.info(f"[DRY RUN] Would create file: {file_path} with content: \n\n{self.content}")
122123
return
123124

125+
if self.skip_if_exists and os.path.exists(file_path):
126+
self.logger.info(f"Skipping file creation as file exists")
127+
self.logger.info(f" File path: {file_path}")
128+
return
129+
124130
# Create the directory if it does not exist
125131
os.makedirs(os.path.dirname(file_path), exist_ok=True)
126132

0 commit comments

Comments
 (0)