Skip to content
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
41 changes: 6 additions & 35 deletions pretext/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,27 +77,6 @@ def main(ctx: click.Context, targets: bool) -> None:
`pretext build --help`.
"""
if (pp := utils.project_path()) is not None:
try:
ProjectRefactor.parse(pp)
log.info(
"------------------------------------\n Good news: \n Your project.ptx file is ready for\n the 2.0.0 release of PreTeXt-CLI.\n------------------------------------\n"
)
except Exception as e:
log.warning(
"Your project.ptx or publication file may not be compatible with the "
+ "upcoming 2.0.0 release of PreTeXt-CLI."
)
log.warning(
"For more information or to help us fix a possible bug, please visit"
)
log.warning(" https://groups.google.com/g/pretext-support/c/bwf51qOoT9c")
log.warning(
"and share the result of running `pretext support` on your machine with us."
)
log.info("")
log.warning(f"Exception info: {e}")
log.info("")
log.warning("Continuing with current version...")
if targets:
for target in Project.parse(pp).target_names():
print(target)
Expand Down Expand Up @@ -514,12 +493,11 @@ def generate(
try:
target = project.get_target(name=target_name)
except AssertionError as e:

utils.show_target_hints(target_name, project, task="generating assets for")
log.critical("Exiting without completing build.")
log.debug(e, exc_info=True)
return

try:
f'Generating assets in for the target "{target.name}".'
target.generate_assets(
Expand Down Expand Up @@ -673,32 +651,25 @@ def view(
context_settings=CONTEXT_SETTINGS,
)
@click.argument("target_name", metavar="target", required=False)
@click.option(
"-s",
"--site",
required=False,
default="site",
help="Relative path to a directory containing html for a landing page.",
)
@click.option("-u", "--update_source", is_flag=True, required=False)
def deploy(target_name: str, site: str, update_source: bool) -> None:
def deploy(target_name: str, update_source: bool) -> None:
"""
Automatically deploys most recent build of [TARGET] to GitHub Pages,
making it available to the general public.
Requires that your project is under Git version control
properly configured with GitHub and GitHub Pages. Deployed
files will live in `docs` subdirectory of project.
files will live in the gh-pages branch of your repository.
"""
if utils.no_project(task="deploy"):
return
project = Project.parse()
target = project.get_target(name=target_name)
if target.format != Format.HTML:
if target.format not in [Format.HTML, Format.RUNESTONE]:
log.critical("Target could not be found in project.ptx manifest.")
# only list targets with html format.
log.critical(
f"Possible html targets to deploy are: {project.target_names('html')}"
f"Possible html/Runestone targets to deploy are: {project.target_names(Format.HTML)}"
)
log.critical("Exiting without completing task.")
return
project.deploy(target_name, site, update_source)
project.deploy(target_name, update_source)
79 changes: 79 additions & 0 deletions pretext/project/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import subprocess
import typing as t
from enum import Enum
import hashlib
Expand Down Expand Up @@ -998,6 +999,9 @@ def publication_abspath(self) -> Path:
def output_dir_abspath(self) -> Path:
return self.abspath() / self.output_dir

def site_abspath(self) -> Path:
return self.abspath() / self.site

def xsl_abspath(self) -> Path:
return self.abspath() / self.xsl

Expand All @@ -1024,3 +1028,78 @@ def get_executables(self) -> Executables:

def init_core(self) -> None:
core.set_executables(self._executables.dict())

def deploy_targets(self) -> t.List[Target]:
return [target for target in self.targets if target.site is not None]

def deploy(self, target_name: str, update_source: bool) -> None:
# Before doing any work, we check that git is installed.
try:
subprocess.run(["git", "--version"], capture_output=True)
log.debug("Git is installed.")
except Exception as e:
log.error(
"Git must be installed to use this feature, but couldn't be found."
)
log.debug(f"Error: {e}", exc_info=True)
return
# Determine what set of targets to deploy. If a target name is specified, deploy on that target. If there are `deploy-dir` specified in the project manifest, also deploy the contents of the `site` folder, if present.
if len(self.deploy_targets()) == 0:
target = self.get_target(target_name)
if target is None:
log.error(f"Target `{target_name}` not found.")
return
if target.format not in [
Format.HTML,
Format.RUNESTONE,
]: # redundant for CLI
log.error("Only HTML and Runestone format targets are supported.")
return
if not target.output_dir_abspath().exists():
log.error(
f"No build for `{target.name}` was found in the directory `{target.output_dir_abspath()}`."
)
log.error(
f"Try running `pretext view {target.name} -b` to build and preview your project first."
)
return
log.info(f"Using latest build located in `{target.output_dir_abspath()}`.")
log.info("")
utils.publish_to_ghpages(target.output_dir_abspath(), update_source)
return
else: # we now deploy multiple targets and the site directory
if not self.site_abspath().exists:
log.error(f"Site directory `{self.site}` not found.")
log.info(
f"You have `deploy-dir` or `site` (v2) elements in your project.ptx file, which requires you to maintain at least a simple landing page in the folder `{self.site}`. Either create this folder or remove the `deploy-dir` elements from your project.ptx file.\n"
)
return
with tempfile.TemporaryDirectory() as temp_dir:
shutil.copytree(
self.site.resolve(),
Path(temp_dir),
dirs_exist_ok=True,
)
for target in self.deploy_targets():
if not target.output_dir_abspath().exists():
log.warning(
f"No build for `{target.name}` was found in the directory `{target.output_dir_abspath()}`. Try running `pretext build {target.name}` to build this component first."
)
log.info("Skipping this target for now.")
else:
deploy_dir = str(target.site)
assert isinstance(deploy_dir, str)
shutil.copytree(
target.output_dir_abspath(),
(Path(temp_dir) / deploy_dir).resolve(),
dirs_exist_ok=True,
)
log.info(f"Deploying `{target.name}` to `{target.site}`.")
# Recopy the site's index.html (if it exists) to the root of the temp directory. This is a bit of a hack, but it's the simplest way to ensure that the site's landing page is deployed.
if (self.site_abspath() / "index.html").exists():
shutil.copy(
self.site_abspath() / "index.html",
Path(temp_dir),
)
utils.publish_to_ghpages(Path(temp_dir), update_source)
return