it's working as an installable CLI on testPypi. added more docs, handled when there's no custom domains, added to gitignore
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
|||||||
env/
|
env/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*egg-info/
|
*egg-info/
|
||||||
|
dist/
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -1,4 +1,6 @@
|
|||||||
# Publish Sites to Netlify via CLI!
|
# What Can Publify Do?
|
||||||
|
|
||||||
|
## Publish Sites to Netlify via CLI!
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> ls mysite
|
> ls mysite
|
||||||
@@ -12,7 +14,7 @@
|
|||||||
the site is published: http://6426ed336771f2380224fb84--scintillating-mochi-760bd3.netlify.app
|
the site is published: http://6426ed336771f2380224fb84--scintillating-mochi-760bd3.netlify.app
|
||||||
```
|
```
|
||||||
|
|
||||||
# Publish Sites to Netlify With Custom Domains Too!
|
## Publish Sites to Netlify With Custom Domains Too!
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> pub --root-dir mysite --custom-domain dude.helpers.fun
|
> pub --root-dir mysite --custom-domain dude.helpers.fun
|
||||||
@@ -20,12 +22,10 @@ the site is published: http://6426ee6a10e4e43866b46a42--startling-gingersnap-425
|
|||||||
the custom domain was set to dude.helpers.fun.
|
the custom domain was set to dude.helpers.fun.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# But First, a Bit of Configuration
|
||||||
|
|
||||||
To do this magic, you have to first
|
To do this magic, you have to first
|
||||||
|
|
||||||
1) Add an entry for `DOMAINS` in the `.env` file, with comma-separated values (no spaces).
|
1) Create an environment variable `NETLIFY_TOKEN`, obtained [here](https://app.netlify.com/user/applications#personal-access-tokens).
|
||||||
|
1) Create an environment variable `NETLIFY_DOMAINS`, with comma-separated values (no spaces), if you're planning to use custom domains.
|
||||||
1) Delegate DNS management of all domains listed in `DOMAINS` to Netlify ([link](https://docs.netlify.com/domains-https/netlify-dns/delegate-to-netlify/))
|
1) Delegate DNS management of all domains listed in `DOMAINS` to Netlify ([link](https://docs.netlify.com/domains-https/netlify-dns/delegate-to-netlify/))
|
||||||
|
|
||||||
# Environment Variables
|
|
||||||
|
|
||||||
- `NETLIFY_TOKEN`
|
|
||||||
- `DOMAINS` <-- comma-delimited domains you've already set up in Netlify
|
|
||||||
|
|||||||
@@ -12,7 +12,13 @@ from dotenv import load_dotenv
|
|||||||
load_dotenv()
|
load_dotenv()
|
||||||
NETLIFY_TOKEN = os.environ["NETLIFY_TOKEN"]
|
NETLIFY_TOKEN = os.environ["NETLIFY_TOKEN"]
|
||||||
AUTH_HEADER = {"Authorization": f"Bearer {NETLIFY_TOKEN}"}
|
AUTH_HEADER = {"Authorization": f"Bearer {NETLIFY_TOKEN}"}
|
||||||
DOMAINS = os.environ["DOMAINS"].split(",")
|
NETLIFY_DOMAINS = os.getenv("NETLIFY_DOMAINS") or ""
|
||||||
|
if NETLIFY_DOMAINS:
|
||||||
|
NETLIFY_DOMAINS = NETLIFY_DOMAINS.split(",")
|
||||||
|
|
||||||
|
|
||||||
|
class NoCustomDomains(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NoNestedFolder(Exception):
|
class NoNestedFolder(Exception):
|
||||||
@@ -122,13 +128,16 @@ def cli_remove_custom_domain() -> None:
|
|||||||
"""
|
"""
|
||||||
Remove a custom domain from a Netlify site
|
Remove a custom domain from a Netlify site
|
||||||
"""
|
"""
|
||||||
|
if len(NETLIFY_DOMAINS) == 0:
|
||||||
|
print("Please set NETLIFY_DOMAINS in your .env file")
|
||||||
|
raise NoCustomDomains
|
||||||
try:
|
try:
|
||||||
custom_domain = sys.argv[sys.argv.index("--remove-custom-domain") + 1]
|
custom_domain = sys.argv[sys.argv.index("--remove-custom-domain") + 1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
print("Please provide a domain")
|
print("Please provide a domain")
|
||||||
return
|
return
|
||||||
if len(DOMAINS) == 1 and custom_domain.count(".") == 0:
|
if len(NETLIFY_DOMAINS) == 1 and custom_domain.count(".") == 0:
|
||||||
custom_domain = f"{custom_domain}.{DOMAINS[0]}"
|
custom_domain = f"{custom_domain}.{NETLIFY_DOMAINS[0]}"
|
||||||
site_id = get_site_id_from_custom_domain(custom_domain)
|
site_id = get_site_id_from_custom_domain(custom_domain)
|
||||||
remove_custom_domain(site_id)
|
remove_custom_domain(site_id)
|
||||||
print(f"{custom_domain} was removed")
|
print(f"{custom_domain} was removed")
|
||||||
@@ -143,9 +152,6 @@ def cli_set_custom_domain() -> None:
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
print("Please provide a --custom-domain")
|
print("Please provide a --custom-domain")
|
||||||
return
|
return
|
||||||
if "--domain" not in sys.argv:
|
|
||||||
print("Please provide a --domain")
|
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
domain = sys.argv[sys.argv.index("--domain") + 1]
|
domain = sys.argv[sys.argv.index("--domain") + 1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@@ -158,8 +164,8 @@ def cli_set_custom_domain() -> None:
|
|||||||
except NoResult:
|
except NoResult:
|
||||||
print(f"No site found with domain '{domain}'")
|
print(f"No site found with domain '{domain}'")
|
||||||
return
|
return
|
||||||
if len(DOMAINS) == 1 and custom_domain.count(".") == 0:
|
if len(NETLIFY_DOMAINS) == 1 and custom_domain.count(".") == 0:
|
||||||
custom_domain = f"{custom_domain}.{DOMAINS[0]}"
|
custom_domain = f"{custom_domain}.{NETLIFY_DOMAINS[0]}"
|
||||||
set_to_custom_domain(site_id, custom_domain)
|
set_to_custom_domain(site_id, custom_domain)
|
||||||
print(f"custom domain was set to {custom_domain}")
|
print(f"custom domain was set to {custom_domain}")
|
||||||
|
|
||||||
@@ -182,9 +188,13 @@ def cli_delete_site() -> None:
|
|||||||
try:
|
try:
|
||||||
site_id = get_site_id_from_netlify_domain(netlify_domain)
|
site_id = get_site_id_from_netlify_domain(netlify_domain)
|
||||||
except NoResult:
|
except NoResult:
|
||||||
|
if len(NETLIFY_DOMAINS) == 0:
|
||||||
|
raise NoCustomDomains(
|
||||||
|
"No custom domains configured in NETLIFY_DOMAINS, and couldn't find a site with that domain"
|
||||||
|
)
|
||||||
print(f"No site found with domain '{domain}', trying custom domains")
|
print(f"No site found with domain '{domain}', trying custom domains")
|
||||||
if domain.count(".") == 0 and len(DOMAINS) == 1:
|
if domain.count(".") == 0 and len(NETLIFY_DOMAINS) == 1:
|
||||||
domain = f"{domain}.{DOMAINS[0]}"
|
domain = f"{domain}.{NETLIFY_DOMAINS[0]}"
|
||||||
try:
|
try:
|
||||||
site_id = get_site_id_from_custom_domain(domain)
|
site_id = get_site_id_from_custom_domain(domain)
|
||||||
except NoResult:
|
except NoResult:
|
||||||
@@ -205,11 +215,11 @@ def display_help() -> None:
|
|||||||
print(
|
print(
|
||||||
"""
|
"""
|
||||||
netlify.py --help
|
netlify.py --help
|
||||||
netlify.py --root-dir <path> --custom-domain <domain (or subdomain prefix if there's only one domain in DOMAINS)>
|
netlify.py --root-dir <path> --custom-domain <domain (or subdomain prefix if there's only one domain in NETLIFY_DOMAINS)>
|
||||||
netlify.py --list-sites
|
netlify.py --list-sites
|
||||||
netlify.py --custom-domain <custom_domain (or subdomain prefix if there's only one domain in DOMAINS)> --domain <existing_domain>
|
netlify.py --custom-domain <custom_domain (or subdomain prefix if there's only one domain in NETLIFY_DOMAINS)> --domain <existing_domain>
|
||||||
netlify.py --remove-custom-domain <custom_domain (or subdomain prefix if there's only one domain in DOMAINS)>
|
netlify.py --remove-custom-domain <custom_domain (or subdomain prefix if there's only one domain in NETLIFY_DOMAINS)>
|
||||||
netlify.py --delete-site <domain (or subdomain prefix if there's only one domain in DOMAINS)>
|
netlify.py --delete-site <domain (or subdomain prefix if there's only one domain in NETLIFY_DOMAINS)>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -220,6 +230,10 @@ def deploy_site() -> None:
|
|||||||
"""
|
"""
|
||||||
custom_domain = None
|
custom_domain = None
|
||||||
if "--custom-domain" in sys.argv:
|
if "--custom-domain" in sys.argv:
|
||||||
|
if len(NETLIFY_DOMAINS) == 0:
|
||||||
|
raise NoCustomDomains(
|
||||||
|
"No custom domains configured in NETLIFY_DOMAINS, and --custom-domain was provided"
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
custom_domain = sys.argv[sys.argv.index("--custom-domain") + 1]
|
custom_domain = sys.argv[sys.argv.index("--custom-domain") + 1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@@ -236,10 +250,10 @@ def deploy_site() -> None:
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
custom_domain is not None
|
custom_domain is not None
|
||||||
and len(DOMAINS) == 1
|
and len(NETLIFY_DOMAINS) == 1
|
||||||
and custom_domain.count(".") == 0
|
and custom_domain.count(".") == 0
|
||||||
):
|
):
|
||||||
custom_domain = f"{custom_domain}.{DOMAINS[0]}"
|
custom_domain = f"{custom_domain}.{NETLIFY_DOMAINS[0]}"
|
||||||
deploy_page_to_netlify(root_dir, custom_domain)
|
deploy_page_to_netlify(root_dir, custom_domain)
|
||||||
|
|
||||||
|
|
||||||
@@ -278,15 +292,29 @@ def main() -> None:
|
|||||||
cli_remove_custom_domain()
|
cli_remove_custom_domain()
|
||||||
except NoResult:
|
except NoResult:
|
||||||
print("No site found with that custom domain")
|
print("No site found with that custom domain")
|
||||||
|
except NoCustomDomains:
|
||||||
|
print("No custom domains configured in NETLIFY_DOMAINS")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
elif "--delete-site" in sys.argv or "--remove-site" in sys.argv:
|
elif "--delete-site" in sys.argv or "--remove-site" in sys.argv:
|
||||||
cli_delete_site()
|
try:
|
||||||
|
cli_delete_site()
|
||||||
|
except NoCustomDomains as e:
|
||||||
|
print(str(e))
|
||||||
sys.exit()
|
sys.exit()
|
||||||
elif "--custom-domain" in sys.argv and "--root-dir" not in sys.argv:
|
elif "--custom-domain" in sys.argv and "--root-dir" not in sys.argv:
|
||||||
|
if len(NETLIFY_DOMAINS) == 0:
|
||||||
|
print("No custom domains configured in NETLIFY_DOMAINS")
|
||||||
|
sys.exit()
|
||||||
|
if "--domain" in sys.argv:
|
||||||
|
print("Please supply a --domain")
|
||||||
|
sys.exit()
|
||||||
cli_set_custom_domain()
|
cli_set_custom_domain()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
else:
|
else:
|
||||||
deploy_site()
|
try:
|
||||||
|
deploy_site()
|
||||||
|
except NoCustomDomains as e:
|
||||||
|
print(str(e))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
6
pyproject.toml
Normal file
6
pyproject.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = [
|
||||||
|
"setuptools>=42",
|
||||||
|
"wheel"
|
||||||
|
]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
18
setup.py
18
setup.py
@@ -1,14 +1,28 @@
|
|||||||
|
import pathlib as pl
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="publify",
|
name="publify",
|
||||||
version="0.1.0",
|
version="0.1.2",
|
||||||
description="A CLI for publishing sites to Netlify and assigning custom domains to them.",
|
description="A CLI for publishing sites to Netlify and assigning custom domains to them.",
|
||||||
author="Zev Averbach",
|
author="Zev Averbach",
|
||||||
author_email="zev@averba.ch",
|
author_email="zev@averba.ch",
|
||||||
|
description_file="README.md",
|
||||||
|
long_description=pl.Path("README.md").read_text(),
|
||||||
|
long_description_content_type="text/markdown",
|
||||||
license="MIT",
|
license="MIT",
|
||||||
|
classifiers=[
|
||||||
|
"Development Status :: 3 - Alpha",
|
||||||
|
"Intended Audience :: Developers",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
|
],
|
||||||
packages=["publify"],
|
packages=["publify"],
|
||||||
|
include_package_data=True,
|
||||||
install_requires=["python-dotenv", "requests"],
|
install_requires=["python-dotenv", "requests"],
|
||||||
|
python_requires=">=3.10", # only because we're using | instead of typing.Union; otherwise >= 3.9
|
||||||
url="https://github.com/zevaverbach/publify",
|
url="https://github.com/zevaverbach/publify",
|
||||||
entry_points={"console_scripts": ["pub = publify.publify:main"]},
|
entry_points={"console_scripts": ["pub=publify.publify:main"]},
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user