From ab9eaac4aa0dd3ebe58bc075de88d0ead93f993d Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Wed, 18 Dec 2024 16:37:41 +0000 Subject: [PATCH 1/8] Init --- src/py/flwr/cli/utils.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index 8cb89255ed40..a35ef1896820 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -161,10 +161,43 @@ def get_sha256_hash(file_path: Path) -> str: def get_user_auth_config_path(root_dir: Path, federation: str) -> Path: - """Return the path to the user auth config file.""" + """Return the path to the user auth config file. + + Additionally, a `.gitignore` file will be created or updated in the + Flower directory to include `.credentials`.""" # Locate the credentials directory credentials_dir = root_dir.absolute() / FLWR_DIR / CREDENTIALS_DIR credentials_dir.mkdir(parents=True, exist_ok=True) + + # Determine the absolute path of the Flower directory for .gitignore + abs_flwr_dir = root_dir.absolute() / FLWR_DIR + gitignore_path = abs_flwr_dir / ".gitignore" + credential_entry = CREDENTIALS_DIR + + try: + if gitignore_path.exists(): + # Read existing .gitignore content + with open(gitignore_path, "r", encoding="utf-8") as gitignore_file: + lines = gitignore_file.read().splitlines() + + # Check if .credentials is already in .gitignore + if credential_entry not in lines: + # Append .credentials to .gitignore + with open(gitignore_path, "a", encoding="utf-8") as gitignore_file: + gitignore_file.write(f"\n{credential_entry}\n") + else: + # Create a new .gitignore with .credentials + with open(gitignore_path, "w", encoding="utf-8") as gitignore_file: + gitignore_file.write(f"{credential_entry}\n") + except Exception as err: + typer.secho( + "❌ An error occurred while handling .gitignore. " + f"Please check the permissions of {gitignore_path} and try again.", + fg=typer.colors.RED, + bold=True, + ) + raise typer.Exit(code=1) from err + return credentials_dir / f"{federation}.json" From 40d140a6a8fcad395141bab5b6b653d88bfa14b2 Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Wed, 18 Dec 2024 16:51:24 +0000 Subject: [PATCH 2/8] Fix docformatter --- src/py/flwr/cli/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index a35ef1896820..9485cdbca56b 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -164,7 +164,8 @@ def get_user_auth_config_path(root_dir: Path, federation: str) -> Path: """Return the path to the user auth config file. Additionally, a `.gitignore` file will be created or updated in the - Flower directory to include `.credentials`.""" + Flower directory to include `.credentials`. + """ # Locate the credentials directory credentials_dir = root_dir.absolute() / FLWR_DIR / CREDENTIALS_DIR credentials_dir.mkdir(parents=True, exist_ok=True) From 1657e1eb4910a54be3dc0ac94e2463c10ac525e5 Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Wed, 18 Dec 2024 16:53:26 +0000 Subject: [PATCH 3/8] Address comment --- src/py/flwr/cli/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index 9485cdbca56b..3e418d165b2e 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -167,11 +167,11 @@ def get_user_auth_config_path(root_dir: Path, federation: str) -> Path: Flower directory to include `.credentials`. """ # Locate the credentials directory - credentials_dir = root_dir.absolute() / FLWR_DIR / CREDENTIALS_DIR + abs_flwr_dir = root_dir.absolute() / FLWR_DIR + credentials_dir = abs_flwr_dir / CREDENTIALS_DIR credentials_dir.mkdir(parents=True, exist_ok=True) # Determine the absolute path of the Flower directory for .gitignore - abs_flwr_dir = root_dir.absolute() / FLWR_DIR gitignore_path = abs_flwr_dir / ".gitignore" credential_entry = CREDENTIALS_DIR From 47b45fd055d2e7aefb9ba4985db203cc1fb3d8ac Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Wed, 18 Dec 2024 16:57:29 +0000 Subject: [PATCH 4/8] Fix ruff --- src/py/flwr/cli/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index 3e418d165b2e..422a551d52d2 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -178,7 +178,7 @@ def get_user_auth_config_path(root_dir: Path, federation: str) -> Path: try: if gitignore_path.exists(): # Read existing .gitignore content - with open(gitignore_path, "r", encoding="utf-8") as gitignore_file: + with open(gitignore_path, encoding="utf-8") as gitignore_file: lines = gitignore_file.read().splitlines() # Check if .credentials is already in .gitignore From 6af121afe3592617e236fe50c54398f29b66416a Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Wed, 18 Dec 2024 17:20:02 +0000 Subject: [PATCH 5/8] Clarify docstring --- src/py/flwr/cli/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index 422a551d52d2..03b49e437659 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -163,8 +163,8 @@ def get_sha256_hash(file_path: Path) -> str: def get_user_auth_config_path(root_dir: Path, federation: str) -> Path: """Return the path to the user auth config file. - Additionally, a `.gitignore` file will be created or updated in the - Flower directory to include `.credentials`. + Additionally, a `.gitignore` file will be created or updated in the Flower + directory to include the `.credentials` folder to be excluded from git. """ # Locate the credentials directory abs_flwr_dir = root_dir.absolute() / FLWR_DIR From 0cbc2c89b586191476dd450497d5f34fd229f33b Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Thu, 19 Dec 2024 09:23:38 +0000 Subject: [PATCH 6/8] Add user notice and warning when checking .gitignore --- src/py/flwr/cli/utils.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index 03b49e437659..ee5907613c08 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -177,16 +177,23 @@ def get_user_auth_config_path(root_dir: Path, federation: str) -> Path: try: if gitignore_path.exists(): - # Read existing .gitignore content with open(gitignore_path, encoding="utf-8") as gitignore_file: lines = gitignore_file.read().splitlines() - # Check if .credentials is already in .gitignore + # Warn if .credentials is not already in .gitignore if credential_entry not in lines: - # Append .credentials to .gitignore - with open(gitignore_path, "a", encoding="utf-8") as gitignore_file: - gitignore_file.write(f"\n{credential_entry}\n") + typer.secho( + f"`.gitignore` exists, but `{credential_entry}` entry not found. " + "Consider adding it to your `.gitignore` to exclude Flower " + "credentials from git.", + fg=typer.colors.YELLOW, + bold=True, + ) else: + typer.secho( + f"Creating a new `.gitignore` with `{credential_entry}` entry...", + fg=typer.colors.BLUE, + ) # Create a new .gitignore with .credentials with open(gitignore_path, "w", encoding="utf-8") as gitignore_file: gitignore_file.write(f"{credential_entry}\n") From 918e98e5b8772083340ded56f601b9fc8546eea8 Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Thu, 19 Dec 2024 09:24:52 +0000 Subject: [PATCH 7/8] Update docstring --- src/py/flwr/cli/utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index ee5907613c08..2e70db76d9ac 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -163,8 +163,10 @@ def get_sha256_hash(file_path: Path) -> str: def get_user_auth_config_path(root_dir: Path, federation: str) -> Path: """Return the path to the user auth config file. - Additionally, a `.gitignore` file will be created or updated in the Flower - directory to include the `.credentials` folder to be excluded from git. + Additionally, a `.gitignore` file will be created in the Flower directory to + include the `.credentials` folder to be excluded from git. If the `.gitignore` + file already exists, a warning will be displayed if the `.credentials` entry is + not found. """ # Locate the credentials directory abs_flwr_dir = root_dir.absolute() / FLWR_DIR From ef4f30d28c11ad1fb77aac7b584d9906f342c793 Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Thu, 19 Dec 2024 09:26:33 +0000 Subject: [PATCH 8/8] Add backticks --- src/py/flwr/cli/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index 2e70db76d9ac..9968895ef73b 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -201,8 +201,8 @@ def get_user_auth_config_path(root_dir: Path, federation: str) -> Path: gitignore_file.write(f"{credential_entry}\n") except Exception as err: typer.secho( - "❌ An error occurred while handling .gitignore. " - f"Please check the permissions of {gitignore_path} and try again.", + "❌ An error occurred while handling `.gitignore.` " + f"Please check the permissions of `{gitignore_path}` and try again.", fg=typer.colors.RED, bold=True, )