8000 feat: add support for updating existing files by jackton1 · Pull Request #32 · tj-python/github-deploy · GitHub
[go: up one dir, main page]

Skip to content

feat: add support for updating existing files #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion github_deploy/commands/_constants.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
REPOS_URL = "https://api.github.com/search/repositories?q=org:{org}"
BASE_URL = "https://api.github.com/repos/{repo}/contents/{path}"
FILE_CONTENTS_URL = "https://api.github.com/repos/{repo}/contents/{path}"
26 changes: 22 additions & 4 deletions github_deploy/commands/_repo_utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import base64
import os

import aiofiles
import asyncclick as click
from aiofiles import os as aiofiles_os

from github_deploy.commands._constants import REPOS_URL, BASE_URL
from github_deploy.commands._constants import REPOS_URL, FILE_CONTENTS_URL
from github_deploy.commands._http_utils import get, delete, put
from github_deploy.commands._utils import get_headers

Expand All @@ -29,7 +31,7 @@ async def delete_content(
if exists:
data["sha"] = current_sha

url = BASE_URL.format(repo=repo, path=dest)
url = FILE_CONTENTS_URL.format(repo=repo, path=dest)

async with semaphore:
response = await delete(
Expand All @@ -40,7 +42,7 @@ async def delete_content(


async def check_exists(*, session, repo, dest, token, semaphore, skip_missing):
url = BASE_URL.format(repo=repo, path=dest)
url = FILE_CONTENTS_URL.format(repo=repo, path=dest)

async with semaphore:
response = await get(
Expand All @@ -62,6 +64,7 @@ async def upload_content(
token,
semaphore,
exists,
only_update,
current_sha,
current_content
):
Expand All @@ -73,6 +76,19 @@ async def upload_content(
if current_content == base64_content:
click.echo("Skipping: Contents are the same.")
return
else:
if exists:
click.echo("Storing backup of existing file...")

dirname, filename = os.path.split(f"{repo}/{dest}")

await aiofiles_os.makedirs(dirname, exist_ok=True)

async with aiofiles.open(f"{dirname}/{filename}", mode="wb") as f:
await f.write(base64.b64decode(current_content))
elif only_update:
click.echo(f"Skipping: only updating existing files.")

Check warning

Code scanning / Prospector (reported by Codacy)

f-string is missing placeholders (F541)

f-string is missing placeholders (F541)
return

data = {
"message": f"Updated {dest}"
Expand All @@ -83,7 +99,9 @@ async def upload_content(
if exists:
data["sha"] = current_sha

url = BASE_URL.format(repo=repo, path=dest)
url = FILE_CONTENTS_URL.format(repo=repo, path=dest)

click.echo(f"Uploading {source} to {repo}/{dest}...")

async with semaphore:
response = await put(
Expand Down
97 changes: 56 additions & 41 deletions github_deploy/commands/upload.py
A54C
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


async def handle_file_upload(
*, repo, source, dest, overwrite, token, semaphore, session
*, repo, source, dest, overwrite, only_update, token, semaphore, session
):
check_exists_response = await check_exists(
session=session,
Expand All @@ -23,19 +23,18 @@ async def handle_file_upload(
current_content = check_exists_response.get("content")
exists = current_sha is not None

if exists and not overwrite:
return click.style(
"Skipped uploading {source} to {repo}/{path}: Found an existing copy.".format(
source=source,
repo=repo,
path=dest,
),
fg="blue",
bold=True,
)

else:
if exists:
if exists:
if not overwrite:
return click.style(
"Skipped uploading {source} to {repo}/{path}: Found an existing copy.".format(
source=source,
repo=repo,
path=dest,
),
fg="blue",
bold=True,
)
else:
click.echo(
click.style(
"Found an existing copy at {repo}/{path} overwriting it's contents...".format(
Expand All @@ -45,43 +44,44 @@ async def handle_file_upload(
),
)

upload_response = await upload_content(
session=session,
repo=repo,
source=source,
dest=dest,
token=token,
semaphore=semaphore,
exists=exists,
current_sha=current_sha,
current_content=current_content,
)
upload_response = await upload_content(
session=session,
repo=repo,
source=source,
dest=dest,
token=token,
semaphore=semaphore,
exists=exists,
only_update=only_update,
current_sha=current_sha,
current_content=current_content,
)

if upload_response:
return click.style(
"Successfully uploaded '{source}' to {repo}/{dest}".format(
source=upload_response["content"]["name"],
repo=repo,
dest=upload_response["content"]["path"],
),
fg="green",
bold=True,
)
if upload_response:
return click.style(
"Successfully uploaded '{source}' to {repo}/{dest}".format(
source=upload_response["content"]["name"],
repo=repo,
dest=upload_response["content"]["path"],
),
fg="green",
bold=True,
)


@click.command()
@click.option(
"--org",
prompt=click.style("Enter your github user/organization", bold=True),
help="The github organization.",
)
@click.option(
"--token",
prompt=click.style("Enter your personal access token", bold=True),
help="Personal Access token with read and write access to org.",
hide_input=True,
envvar="TOKEN",
)
@click.option(
"--org",
prompt=click.style("Enter your github user/organization", bold=True),
help="The github organization.",
)
@click.option(
"--source",
prompt=click.style("Enter path to source file", fg="blue"),
Expand All @@ -98,16 +98,30 @@ async def handle_file_upload(
prompt=click.style(
"Should we overwrite existing contents at this path", fg="blue"
),
is_flag=True,
show_default=True,
help="Overwrite existing files.",
default=False,
)
@click.option(
"--only-update/--no-only-update",
prompt=click.style(
"Should we only update existing files at this path", fg="blue"
),
is_flag=True,
show_default=True,
help="Only update existing files.",
default=False,
)
@click.option(
"--private/--no-private",
prompt=click.style("Should we Include private repositories", bold=True),
is_flag=True,
show_default=True,
help="Upload files to private repositories.",
default=True,
)
async def main(org, token, source, dest, overwrite, private):
async def main(org, token, source, dest, overwrite, only_update, private):
"""Upload a file to all repositories owned by an organization/user."""
# create instance of Semaphore: max concurrent requests.
semaphore = asyncio.Semaphore(1000)
Expand Down Expand Up @@ -171,6 +185,7 @@ async def main(org, token, source, dest, overwrite, private):
dest=dest,
token=token,
overwrite=overwrite,
only_update=only_update,
session=session,
semaphore=semaphore,
)
Expand Down
0