Skip to content

Commit

Permalink
Merge pull request #888 from PreTeXtBook/codespace-view
Browse files Browse the repository at this point in the history
improve view command for codespaces
  • Loading branch information
oscarlevin authored Dec 28, 2024
2 parents d4865d3 + 85eb0db commit 013c76a
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 28 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,19 @@ Instructions: Add a subsection under `[Unreleased]` for additions, fixes, change

## [Unreleased]

### Fixed

- Improved codespace view command (now respects already running servers).
- CSS fixes for logo and references from core.

## [2.11.1] - 2024-12-25

Includes updates to core through commit: [e4edfd0](https://github.com/PreTeXtBook/pretext/commit/e4edfd0fe052d9dd91404667a42ff1c0932d114b)

### Fixed

- `pretext view` bug where a process is terminated abnormally

## [2.11.0] - 2024-12-24

Includes updates to core through commit: [e4edfd0](https://github.com/PreTeXtBook/pretext/commit/e4edfd0fe052d9dd91404667a42ff1c0932d114b)
Expand Down
2 changes: 1 addition & 1 deletion pretext/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

VERSION = get_version("pretext", Path(__file__).parent.parent)

CORE_COMMIT = "e4edfd0fe052d9dd91404667a42ff1c0932d114b"
CORE_COMMIT = "3c662c9fc70c6fa49c031c44ffaebcfbf61ce2f1"


def activate() -> None:
Expand Down
35 changes: 8 additions & 27 deletions pretext/cli.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import logging
import logging.handlers
import random
import sys
import time
import click
import click_log
import shutil
Expand Down Expand Up @@ -805,11 +803,10 @@ def view(
if utils.cannot_find_project(task="view the output for"):
return
project = Project.parse()

project_hash = utils.hash_path(project.abspath())
current_server = server.active_server_for_path_hash(project_hash)
if stop_server:
try:
project_hash = utils.hash_path(project.abspath())
current_server = server.active_server_for_path_hash(project_hash)
log.info("\nStopping server.")
if current_server:
current_server.terminate()
Expand Down Expand Up @@ -852,28 +849,8 @@ def view(

in_codespace = os.environ.get("CODESPACES")

if in_codespace and not default_server:
log.info(
"Running in a codespace, so using the codespace server instead of the standard python server."
)
if port == 8128:
port = random.randint(8129, 8999)
# set the url
url_base = utils.url_for_access(access=access, port=port)
url = url_base + url_path
log.info(f"Server will soon be available at {url_base}")
utils.start_codespace_server(port=port, access=access)
if no_launch:
log.info(f"The {target_name} will be available at {url}")
else:
seconds = 2
log.info(f"Opening browser for {target_name} at {url} in {seconds} seconds")
time.sleep(seconds)
webbrowser.open(url)
return
# Start server if there isn't one running already:
project_hash = utils.hash_path(project.abspath())
current_server = server.active_server_for_path_hash(project_hash)

if restart_server and current_server is not None:
log.info(
f"Terminating existing server {current_server.pid} on port {current_server.port}"
Expand Down Expand Up @@ -915,7 +892,11 @@ def callback(actual_port: int) -> None:
webbrowser.open(url)

log.info("starting server ...")
server.start_server(project.abspath(), access, port, callback)
if in_codespace and not default_server:
log.info("Running in a codespace, so using a subprocess server.")
server.start_codespace_server(project.abspath(), access, port, callback)
else:
server.start_server(project.abspath(), access, port, callback)


# pretext deploy
Expand Down
35 changes: 35 additions & 0 deletions pretext/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import os
from pathlib import Path
import socketserver
import subprocess
import sys
import typing as t
import psutil

Expand Down Expand Up @@ -73,6 +75,13 @@ def url(self) -> str:
return f"{self.binding}:{self.port}"


def is_port_in_use(port: int) -> bool:
import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(("localhost", port)) == 0


def get_running_servers() -> t.List[RunningServerInfo]:
"""
Processes the ~/.ptx/running_servers file to retrieve a list
Expand Down Expand Up @@ -208,3 +217,29 @@ class TCPServer(socketserver.TCPServer):
log.info("Stopping server.")
remove_server_entry(path_hash)
return


def start_codespace_server(
base_dir: Path,
access: t.Literal["public", "private"] = "private",
port: int = 8128,
callback: t.Callable[[int], None] | None = None,
) -> None:
while is_port_in_use(port):
log.debug(f"Port {port} is in use.")
port = port + 1
log.debug(f"Trying port {port} instead.")
path_hash = hash_path(base_dir)
binding = binding_for_access(access)
log.debug(f"values set: {path_hash}, {binding}, {port}")

log.info("Starting the server")
server_process = subprocess.Popen(
[sys.executable, "-m", "http.server", str(port)], cwd=base_dir
)
log.debug(f"Server process pid: {server_process.pid}")
log.debug("adding server entry")
add_server_entry(path_hash, server_process.pid, port, binding)
if callback is not None:
callback(port)
return

0 comments on commit 013c76a

Please sign in to comment.