Skip to content

Bug: Offline mode (-o/--offline) still fetches HTTP-referenced requirements/constraints #70

@jensens

Description

@jensens

Bug Description

When running mxdev with the -o/--offline flag, HTTP-referenced requirements and constraints files are still fetched from the network. The offline mode currently only skips VCS operations but does not prevent HTTP URL fetching during the read phase.

Current Behavior

# In mx.ini or requirements file:
-c https://example.com/constraints.txt
-r https://example.com/requirements.txt

# Running with offline flag:
mxdev -o
# ❌ Still fetches from https://example.com/

The offline setting is only checked in:

  1. main.py:88-90 - To skip the VCS fetch() phase
  2. vcs/common.py:82-84 - In should_update() to prevent VCS updates
  3. processing.py:221-270 - For error tolerance of missing source directories

But offline is NOT checked in resolve_dependencies() (processing.py:93-167), which handles HTTP URL resolution.

Expected Behavior

When running with -o/--offline:

  • ✅ Skip all VCS operations (current behavior)
  • ✅ Skip all HTTP fetches of requirements/constraints files (missing behavior)
  • ✅ Work entirely offline using only local files
  • ✅ Tolerate missing files gracefully (like other offline operations)

Code References

Bug location: src/mxdev/processing.py:134-146

def resolve_dependencies(
    file_or_url: str,
    # ...
) -> tuple[list[str], list[str]]:
    # ...
    else:
        # HTTP URL handling - NO OFFLINE CHECK!
        try:
            with request.urlopen(file_or_url) as fio:  # ← Runs even in offline mode
                process_io(fio, ...)
        except URLError as e:
            raise Exception(f"Failed to fetch '{file_or_url}': {e}")

Impact

  • Users cannot work in truly offline environments (airplanes, restricted networks, etc.)
  • The -o/--offline flag is misleading - it doesn't provide full offline operation
  • Inconsistent behavior: VCS operations are skipped but HTTP fetches are not

Proposed Fix

Add offline mode check in resolve_dependencies():

def resolve_dependencies(
    file_or_url: str,
    # ...
    offline: bool = False,  # Add parameter
) -> tuple[list[str], list[str]]:
    # ...
    else:
        # HTTP URL handling
        if offline:
            logger.warning(f"Skipping HTTP reference in offline mode: {file_or_url}")
            return (requirements, constraints)
        
        try:
            with request.urlopen(file_or_url) as fio:
                process_io(fio, ...)
        except URLError as e:
            raise Exception(f"Failed to fetch '{file_or_url}': {e}")

Related

This was discovered while improving the help text for -n/-f/-o options to better explain their differences.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions