Skip to content

Commit

Permalink
add more features
Browse files Browse the repository at this point in the history
  • Loading branch information
xmnlab committed Dec 14, 2023
1 parent 6291d12 commit 5b52aa0
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 47 deletions.
22 changes: 10 additions & 12 deletions .envers/data.lock
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
version: 0.1
releases:
'2.0':
'1.0':
spec:
status: draft
docs: ''
profiles:
- base
Expand All @@ -23,23 +22,17 @@ releases:
type: string
default: '1.0'
encrypted: false
USE_CONTAINER:
type: bool
default: true
encrypted: false
data:
base:
files:
.env:
type: dotenv
vars:
ENV: dev
PROJECT_NAME: envers
VERSION: '1.0'
USE_CONTAINER: true
'1.0':
ENV: staging
PROJECT_NAME: sugar
VERSION: '1.2'
'2.0':
spec:
status: draft
docs: ''
profiles:
- base
Expand All @@ -60,6 +53,10 @@ releases:
type: string
default: '1.0'
encrypted: false
USE_CONTAINER:
type: bool
default: true
encrypted: false
data:
base:
files:
Expand All @@ -69,3 +66,4 @@ releases:
ENV: dev
PROJECT_NAME: envers
VERSION: '1.0'
USE_CONTAINER: true
4 changes: 2 additions & 2 deletions .envers/specs.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: 0.1
releases:
'1.0':
status: draft
status: deployed
docs: ''
profiles:
- base
Expand All @@ -23,7 +23,7 @@ releases:
default: '1.0'
encrypted: false
'2.0':
status: draft
status: deployed
docs: ''
profiles:
- base
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@ Below are the initial subcommands for `envers`:
Create a new version draft in the spec file. Some variants of this command:
- `envers draft <spec version number> --from <previous spec version number>`
- `envers draft <spec version number> --from-env .env`
- `envers profile set --profile <profile_name> --spec <version_number>`:
- `envers profile-set --profile <profile_name> --spec <version_number>`:
Add new content.
- `envers profile update --profile <profile_name> --spec <version_number>`:
Update existing content.
- `envers profile load --profile prod --spec <spec version>`:
Load a specific environment profile to files
- `envers profile versions --profile <profile_name> --spec <spec version>`:
Expand Down
18 changes: 10 additions & 8 deletions src/envers/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,17 @@ def profile_set(


@app.command()
def profile_update(profile_name: str, spec_version: str) -> None:
"""Update existing content of a profile."""
print(profile_name, spec_version)


@app.command()
def profile_load(profile: str, spec: str) -> None:
def profile_load(
profile: Annotated[
str, typer.Option(help="The name of the profile to set values for.")
] = "",
spec: Annotated[
str, typer.Option(help="The version of the spec to use.")
] = "",
) -> None:
"""Load a specific environment profile to files."""
print(profile, spec)
envers = Envers()
envers.profile_load(profile, spec)


@app.command()
Expand Down
111 changes: 89 additions & 22 deletions src/envers/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def deploy(self, version: str) -> None:
None
"""
specs_file = Path(".envers") / ENVERS_SPEC_FILENAME
data_lock_file = Path(".envers") / "data.lock"
data_file = Path(".envers") / "data.lock"

if not specs_file.exists():
typer.echo("Spec file not found. Please initialize envers first.")
Expand All @@ -169,11 +169,21 @@ def deploy(self, version: str) -> None:
typer.echo(f"Version {version} not found in specs.yaml.")
raise typer.Exit()

spec = specs["releases"][version]
spec = copy.deepcopy(specs["releases"][version])

# all data in the data.lock file are deployed
del spec["status"]

if data_lock_file.exists():
with open(data_lock_file, "r") as file:
if data_file.exists():
with open(data_file, "r") as file:
data_lock = yaml.safe_load(file) or {}

if not data_lock:
typer.echo("data.lock is not valid. Creating a new file.")
data_lock = {
"version": specs["version"],
"releases": {},
}
data_lock["releases"][version] = {"spec": spec, "data": {}}
else:
data_lock = {
Expand All @@ -197,9 +207,13 @@ def deploy(self, version: str) -> None:
profile_data["files"][file_path] = file_data
data_lock["releases"][version]["data"][profile_name] = profile_data

with open(data_lock_file, "w") as file:
with open(data_file, "w") as file:
yaml.dump(data_lock, file, sort_keys=False)

with open(specs_file, "w") as file:
specs["releases"][version]["status"] = "deployed"
yaml.dump(specs, file, sort_keys=False)

def profile_set(self, profile: str, spec: str) -> None:
"""
Set the profile values for a given spec version.
Expand All @@ -215,44 +229,97 @@ def profile_set(self, profile: str, spec: str) -> None:
-------
None
"""
data_lock_file = Path(".envers") / "data.lock"
data_file = Path(".envers") / "data.lock"

if not data_lock_file.exists():
if not data_file.exists():
typer.echo(
"Data lock file not found. Please deploy a version first."
)
raise typer.Exit()

with open(data_lock_file, "r") as file:
with open(data_file, "r") as file:
data_lock = yaml.safe_load(file) or {}

if not data_lock.get("releases", {}).get(spec, ""):
typer.echo(f"Version {spec} not found in data.lock.")
raise typer.Exit()

release_data = data_lock["releases"][spec]
spec_data = release_data.get("spec", {})
profile_data = release_data.get("data", {}).get(profile, {"files": {}})
profile_data = release_data.get("data", {}).get(profile, {})

if not (profile_data and profile_data.get("files", {})):
typer.echo(
f"There is no data spec for version '{spec}' "
f"and profile '{profile}'"
)
raise typer.Exit()

# Iterate over files and variables
for file_path, file_info in spec_data.get("files", {}).items():
profile_title = f"Profile: {profile}"
typer.echo(f"{profile_title}\n{'=' * len(profile_title)}")
for file_path, file_info in profile_data.get("files", {}).items():
file_title = f"File: {file_path}"
typer.echo(f"{file_title}\n{'-' * len(file_title)}")
for var_name, var_info in file_info.get("vars", {}).items():
current_value = (
profile_data.get("files", {})
.get(file_path, {})
.get("vars", {})
.get(var_name, var_info.get("default", ""))
)
current_value = var_info
new_value = typer.prompt(
f"Enter value for {var_name} in {file_path} "
f"(Profile: {profile})",
f"Enter value for `{var_name}`",
default=current_value,
)
if not profile_data.get("files", {}).get(file_path, {}):
profile_data["files"][file_path] = {"vars": {}}
profile_data["files"][file_path]["vars"][var_name] = new_value

# Update data.lock file
data_lock["releases"][spec]["data"][profile] = profile_data
with open(data_lock_file, "w") as file:
with open(data_file, "w") as file:
yaml.dump(data_lock, file, sort_keys=False)

def profile_load(self, profile: str, spec: str) -> None:
"""
Load a specific environment profile to files.
Load a specific environment profile to files based on the given
spec version.
Parameters
----------
profile : str
The name of the profile to load.
spec : str
The version of the spec to use.
Returns
-------
None
"""
data_lock_file = Path(".envers") / "data.lock"

if not data_lock_file.exists():
typer.echo(
"Data lock file not found. Please deploy a version first."
)
raise typer.Exit()

with open(data_lock_file, "r") as file:
data_lock = yaml.safe_load(file) or {}

if not data_lock.get("releases", {}).get(spec, ""):
typer.echo(f"Version {spec} not found in data.lock.")
raise typer.Exit()

release_data = data_lock["releases"][spec]
profile_data = release_data.get("data", {}).get(profile, {"files": {}})

# Iterate over files and variables
for file_path, file_info in profile_data.get("files", {}).items():
file_content = ""
for var_name, var_value in file_info.get("vars", {}).items():
file_content += f"{var_name}={var_value}\n"

# Create or update the file
with open(file_path, "w") as file:
file.write(file_content)

typer.echo(
f"Environment files for profile '{profile}' and spec version "
f"'{spec}' have been created/updated."
)

0 comments on commit 5b52aa0

Please sign in to comment.