ghps 0.6__tar.gz → 0.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ghps-0.6 → ghps-0.7}/CHANGELOG.md +9 -1
- {ghps-0.6 → ghps-0.7}/PKG-INFO +27 -8
- {ghps-0.6 → ghps-0.7}/README.md +16 -5
- {ghps-0.6 → ghps-0.7}/SECURITY.md +2 -2
- {ghps-0.6 → ghps-0.7}/ghps/cli.py +8 -0
- {ghps-0.6 → ghps-0.7}/ghps/params.py +2 -1
- {ghps-0.6 → ghps-0.7}/ghps/server.py +12 -2
- {ghps-0.6 → ghps-0.7}/ghps.egg-info/PKG-INFO +27 -8
- {ghps-0.6 → ghps-0.7}/setup.py +2 -2
- {ghps-0.6 → ghps-0.7}/tests/test_cli.py +21 -0
- {ghps-0.6 → ghps-0.7}/tests/test_error.py +14 -0
- {ghps-0.6 → ghps-0.7}/tests/test_server.py +39 -0
- {ghps-0.6 → ghps-0.7}/AUTHORS.md +0 -0
- {ghps-0.6 → ghps-0.7}/LICENSE +0 -0
- {ghps-0.6 → ghps-0.7}/MANIFEST.in +0 -0
- {ghps-0.6 → ghps-0.7}/ghps/__init__.py +0 -0
- {ghps-0.6 → ghps-0.7}/ghps/__main__.py +0 -0
- {ghps-0.6 → ghps-0.7}/ghps/errors.py +0 -0
- {ghps-0.6 → ghps-0.7}/ghps.egg-info/SOURCES.txt +0 -0
- {ghps-0.6 → ghps-0.7}/ghps.egg-info/dependency_links.txt +0 -0
- {ghps-0.6 → ghps-0.7}/ghps.egg-info/entry_points.txt +0 -0
- {ghps-0.6 → ghps-0.7}/ghps.egg-info/requires.txt +0 -0
- {ghps-0.6 → ghps-0.7}/ghps.egg-info/top_level.txt +0 -0
- {ghps-0.6 → ghps-0.7}/requirements-dev.txt +0 -0
- {ghps-0.6 → ghps-0.7}/requirements-latest.txt +0 -0
- {ghps-0.6 → ghps-0.7}/setup.cfg +0 -0
|
@@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
|
+
## [0.7] - 2026-09-22
|
|
9
|
+
### Added
|
|
10
|
+
- `host` parameter
|
|
11
|
+
- `--host` CLI argument
|
|
12
|
+
### Changed
|
|
13
|
+
- Test system modified
|
|
14
|
+
- `README.md` updated
|
|
8
15
|
## [0.6] - 2026-08-31
|
|
9
16
|
### Added
|
|
10
17
|
- Custom default error page
|
|
@@ -52,7 +59,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
52
59
|
- Command line interface
|
|
53
60
|
- Test system
|
|
54
61
|
|
|
55
|
-
[Unreleased]: https://github.com/sepandhaghighi/ghps/compare/v0.
|
|
62
|
+
[Unreleased]: https://github.com/sepandhaghighi/ghps/compare/v0.7...dev
|
|
63
|
+
[0.7]: https://github.com/sepandhaghighi/ghps/compare/v0.6...v0.7
|
|
56
64
|
[0.6]: https://github.com/sepandhaghighi/ghps/compare/v0.5...v0.6
|
|
57
65
|
[0.5]: https://github.com/sepandhaghighi/ghps/compare/v0.4...v0.5
|
|
58
66
|
[0.4]: https://github.com/sepandhaghighi/ghps/compare/v0.3...v0.4
|
{ghps-0.6 → ghps-0.7}/PKG-INFO
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ghps
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7
|
|
4
4
|
Summary: Ghps: A Minimal GitHub Pages Simulator for Local Development
|
|
5
5
|
Home-page: https://github.com/sepandhaghighi/ghps
|
|
6
|
-
Download-URL: https://github.com/sepandhaghighi/ghps/tarball/v0.
|
|
6
|
+
Download-URL: https://github.com/sepandhaghighi/ghps/tarball/v0.7
|
|
7
7
|
Author: Sepand Haghighi
|
|
8
8
|
Author-email: me@sepand.tech
|
|
9
9
|
License: MIT
|
|
@@ -101,13 +101,13 @@ Dynamic: summary
|
|
|
101
101
|
## Installation
|
|
102
102
|
|
|
103
103
|
### Source Code
|
|
104
|
-
- Download [Version 0.
|
|
104
|
+
- Download [Version 0.7](https://github.com/sepandhaghighi/ghps/archive/v0.7.zip) or [Latest Source](https://github.com/sepandhaghighi/ghps/archive/dev.zip)
|
|
105
105
|
- `pip install .`
|
|
106
106
|
|
|
107
107
|
### PyPI
|
|
108
108
|
|
|
109
109
|
- Check [Python Packaging User Guide](https://packaging.python.org/installing/)
|
|
110
|
-
- `pip install ghps==0.
|
|
110
|
+
- `pip install ghps==0.7`
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
## Usage
|
|
@@ -117,13 +117,14 @@ Ghps can be used both as a CLI tool and as a Python library.
|
|
|
117
117
|
### CLI
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
ghps --port=8080 --no-cache --no-threaded
|
|
120
|
+
ghps --host=127.0.0.1 --port=8080 --no-cache --no-threaded
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
#### Options
|
|
124
124
|
|
|
125
125
|
| Option | Description | Default |
|
|
126
126
|
|--------|-------------|----------|
|
|
127
|
+
| `--host` | Host address to bind to | `localhost` |
|
|
127
128
|
| `-p, --port` | Port to serve on | `8000` |
|
|
128
129
|
| `-d, --directory` | Directory to serve | Current directory (`.`) |
|
|
129
130
|
| `-b, --base-path` | Base path for project pages (e.g. `/repo-name`) | `""` |
|
|
@@ -133,7 +134,11 @@ ghps --port=8080 --no-cache --no-threaded
|
|
|
133
134
|
| `--auto-open` | Automatically open the server URL | Disable |
|
|
134
135
|
| `--directory-listing` | Enable directory listing | Disable |
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
> [!NOTE]
|
|
138
|
+
> You can set `--port=0` to let the OS automatically select an available port.
|
|
139
|
+
|
|
140
|
+
> [!NOTE]
|
|
141
|
+
> You can use `--host=0.0.0.0` to bind Ghps to all available network interfaces, or specify a particular address such as `127.0.0.1`.
|
|
137
142
|
|
|
138
143
|
|
|
139
144
|
### Library
|
|
@@ -143,6 +148,7 @@ from ghps import GHPageServer
|
|
|
143
148
|
|
|
144
149
|
server = GHPageServer(
|
|
145
150
|
directory="dist",
|
|
151
|
+
host="localhost",
|
|
146
152
|
port=5000,
|
|
147
153
|
base_path="/repo-name",
|
|
148
154
|
strict=True,
|
|
@@ -159,6 +165,7 @@ server.start()
|
|
|
159
165
|
| Parameter | Type | Description | Default |
|
|
160
166
|
|------------|------|-------------|----------|
|
|
161
167
|
| `directory` | `str` | Directory to serve | `"."` |
|
|
168
|
+
| `host` | `str` | Host address to bind the server to | `"localhost"` |
|
|
162
169
|
| `port` | `int` | Port number | `8000` |
|
|
163
170
|
| `base_path` | `str` | Base path for project page simulation | `""` |
|
|
164
171
|
| `strict` | `bool` | Enforce GitHub-like routing behavior | `True` |
|
|
@@ -167,7 +174,11 @@ server.start()
|
|
|
167
174
|
| `auto_open` | `bool` | Automatically open the server URL | `False` |
|
|
168
175
|
| `directory_listing` | `bool` | Enable directory listing | `False` |
|
|
169
176
|
|
|
170
|
-
|
|
177
|
+
> [!NOTE]
|
|
178
|
+
> You can set `port=0` to let the OS automatically select an available port.
|
|
179
|
+
|
|
180
|
+
> [!NOTE]
|
|
181
|
+
> The `host` parameter controls the network interface used for server binding. The default is `"localhost"`.
|
|
171
182
|
|
|
172
183
|
## Issues & Bug Reports
|
|
173
184
|
|
|
@@ -218,6 +229,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
|
218
229
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
219
230
|
|
|
220
231
|
## [Unreleased]
|
|
232
|
+
## [0.7] - 2026-09-22
|
|
233
|
+
### Added
|
|
234
|
+
- `host` parameter
|
|
235
|
+
- `--host` CLI argument
|
|
236
|
+
### Changed
|
|
237
|
+
- Test system modified
|
|
238
|
+
- `README.md` updated
|
|
221
239
|
## [0.6] - 2026-08-31
|
|
222
240
|
### Added
|
|
223
241
|
- Custom default error page
|
|
@@ -265,7 +283,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
265
283
|
- Command line interface
|
|
266
284
|
- Test system
|
|
267
285
|
|
|
268
|
-
[Unreleased]: https://github.com/sepandhaghighi/ghps/compare/v0.
|
|
286
|
+
[Unreleased]: https://github.com/sepandhaghighi/ghps/compare/v0.7...dev
|
|
287
|
+
[0.7]: https://github.com/sepandhaghighi/ghps/compare/v0.6...v0.7
|
|
269
288
|
[0.6]: https://github.com/sepandhaghighi/ghps/compare/v0.5...v0.6
|
|
270
289
|
[0.5]: https://github.com/sepandhaghighi/ghps/compare/v0.4...v0.5
|
|
271
290
|
[0.4]: https://github.com/sepandhaghighi/ghps/compare/v0.3...v0.4
|
{ghps-0.6 → ghps-0.7}/README.md
RENAMED
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
## Installation
|
|
51
51
|
|
|
52
52
|
### Source Code
|
|
53
|
-
- Download [Version 0.
|
|
53
|
+
- Download [Version 0.7](https://github.com/sepandhaghighi/ghps/archive/v0.7.zip) or [Latest Source](https://github.com/sepandhaghighi/ghps/archive/dev.zip)
|
|
54
54
|
- `pip install .`
|
|
55
55
|
|
|
56
56
|
### PyPI
|
|
57
57
|
|
|
58
58
|
- Check [Python Packaging User Guide](https://packaging.python.org/installing/)
|
|
59
|
-
- `pip install ghps==0.
|
|
59
|
+
- `pip install ghps==0.7`
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
## Usage
|
|
@@ -66,13 +66,14 @@ Ghps can be used both as a CLI tool and as a Python library.
|
|
|
66
66
|
### CLI
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
|
-
ghps --port=8080 --no-cache --no-threaded
|
|
69
|
+
ghps --host=127.0.0.1 --port=8080 --no-cache --no-threaded
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
#### Options
|
|
73
73
|
|
|
74
74
|
| Option | Description | Default |
|
|
75
75
|
|--------|-------------|----------|
|
|
76
|
+
| `--host` | Host address to bind to | `localhost` |
|
|
76
77
|
| `-p, --port` | Port to serve on | `8000` |
|
|
77
78
|
| `-d, --directory` | Directory to serve | Current directory (`.`) |
|
|
78
79
|
| `-b, --base-path` | Base path for project pages (e.g. `/repo-name`) | `""` |
|
|
@@ -82,7 +83,11 @@ ghps --port=8080 --no-cache --no-threaded
|
|
|
82
83
|
| `--auto-open` | Automatically open the server URL | Disable |
|
|
83
84
|
| `--directory-listing` | Enable directory listing | Disable |
|
|
84
85
|
|
|
85
|
-
|
|
86
|
+
> [!NOTE]
|
|
87
|
+
> You can set `--port=0` to let the OS automatically select an available port.
|
|
88
|
+
|
|
89
|
+
> [!NOTE]
|
|
90
|
+
> You can use `--host=0.0.0.0` to bind Ghps to all available network interfaces, or specify a particular address such as `127.0.0.1`.
|
|
86
91
|
|
|
87
92
|
|
|
88
93
|
### Library
|
|
@@ -92,6 +97,7 @@ from ghps import GHPageServer
|
|
|
92
97
|
|
|
93
98
|
server = GHPageServer(
|
|
94
99
|
directory="dist",
|
|
100
|
+
host="localhost",
|
|
95
101
|
port=5000,
|
|
96
102
|
base_path="/repo-name",
|
|
97
103
|
strict=True,
|
|
@@ -108,6 +114,7 @@ server.start()
|
|
|
108
114
|
| Parameter | Type | Description | Default |
|
|
109
115
|
|------------|------|-------------|----------|
|
|
110
116
|
| `directory` | `str` | Directory to serve | `"."` |
|
|
117
|
+
| `host` | `str` | Host address to bind the server to | `"localhost"` |
|
|
111
118
|
| `port` | `int` | Port number | `8000` |
|
|
112
119
|
| `base_path` | `str` | Base path for project page simulation | `""` |
|
|
113
120
|
| `strict` | `bool` | Enforce GitHub-like routing behavior | `True` |
|
|
@@ -116,7 +123,11 @@ server.start()
|
|
|
116
123
|
| `auto_open` | `bool` | Automatically open the server URL | `False` |
|
|
117
124
|
| `directory_listing` | `bool` | Enable directory listing | `False` |
|
|
118
125
|
|
|
119
|
-
|
|
126
|
+
> [!NOTE]
|
|
127
|
+
> You can set `port=0` to let the OS automatically select an available port.
|
|
128
|
+
|
|
129
|
+
> [!NOTE]
|
|
130
|
+
> The `host` parameter controls the network interface used for server binding. The default is `"localhost"`.
|
|
120
131
|
|
|
121
132
|
## Issues & Bug Reports
|
|
122
133
|
|
|
@@ -32,6 +32,13 @@ def _parse_args() -> argparse.Namespace:
|
|
|
32
32
|
help="Version"
|
|
33
33
|
)
|
|
34
34
|
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
"--host",
|
|
37
|
+
type=str,
|
|
38
|
+
default="localhost",
|
|
39
|
+
help="Host address to bind to (default: localhost)"
|
|
40
|
+
)
|
|
41
|
+
|
|
35
42
|
parser.add_argument(
|
|
36
43
|
"-p", "--port",
|
|
37
44
|
type=int,
|
|
@@ -94,6 +101,7 @@ def main() -> None:
|
|
|
94
101
|
else:
|
|
95
102
|
server = GHPageServer(
|
|
96
103
|
directory=args.directory,
|
|
104
|
+
host=args.host,
|
|
97
105
|
port=args.port,
|
|
98
106
|
base_path=args.base_path,
|
|
99
107
|
strict=not args.no_strict,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""ghps params."""
|
|
3
3
|
|
|
4
|
-
GHPS_VERSION = "0.
|
|
4
|
+
GHPS_VERSION = "0.7"
|
|
5
5
|
GHPS_REPO = "https://github.com/sepandhaghighi/ghps"
|
|
6
6
|
|
|
7
7
|
INVALID_DIRECTORY_TYPE_ERROR = "`directory` must be str or pathlib.Path."
|
|
8
8
|
DIRECTORY_NOT_FOUND_ERROR = "`directory` does not exist."
|
|
9
9
|
DIRECTORY_NOT_DIR_ERROR = "`directory` must be a valid directory."
|
|
10
10
|
|
|
11
|
+
INVALID_HOST_TYPE_ERROR = "`host` must be str."
|
|
11
12
|
INVALID_PORT_TYPE_ERROR = "`port` must be int."
|
|
12
13
|
INVALID_PORT_RANGE_ERROR = "`port` must be between 0 and 65535."
|
|
13
14
|
|
|
@@ -17,6 +17,7 @@ from .params import (
|
|
|
17
17
|
INVALID_DIRECTORY_TYPE_ERROR,
|
|
18
18
|
DIRECTORY_NOT_FOUND_ERROR,
|
|
19
19
|
DIRECTORY_NOT_DIR_ERROR,
|
|
20
|
+
INVALID_HOST_TYPE_ERROR,
|
|
20
21
|
INVALID_PORT_TYPE_ERROR,
|
|
21
22
|
INVALID_PORT_RANGE_ERROR,
|
|
22
23
|
INVALID_BASE_PATH_TYPE_ERROR,
|
|
@@ -38,6 +39,7 @@ from .errors import GHPSValidationError, GHPSRuntimeError
|
|
|
38
39
|
|
|
39
40
|
def _validate_inputs(
|
|
40
41
|
directory: Any,
|
|
42
|
+
host: Any,
|
|
41
43
|
port: Any,
|
|
42
44
|
base_path: Any,
|
|
43
45
|
strict: Any,
|
|
@@ -50,6 +52,7 @@ def _validate_inputs(
|
|
|
50
52
|
Validate GHPageServer inputs.
|
|
51
53
|
|
|
52
54
|
:param directory: Root directory to serve files from.
|
|
55
|
+
:param host: Host address to bind the server to.
|
|
53
56
|
:param port: Port number to bind the server to.
|
|
54
57
|
:param base_path: URL base path prefix for serving content.
|
|
55
58
|
:param strict: If False, enables automatic ".html" resolution.
|
|
@@ -68,6 +71,9 @@ def _validate_inputs(
|
|
|
68
71
|
if not directory.is_dir():
|
|
69
72
|
raise GHPSValidationError(DIRECTORY_NOT_DIR_ERROR)
|
|
70
73
|
|
|
74
|
+
if not isinstance(host, str):
|
|
75
|
+
raise GHPSValidationError(INVALID_HOST_TYPE_ERROR)
|
|
76
|
+
|
|
71
77
|
if not isinstance(port, int) or isinstance(port, bool):
|
|
72
78
|
raise GHPSValidationError(INVALID_PORT_TYPE_ERROR)
|
|
73
79
|
|
|
@@ -249,6 +255,7 @@ class GHPageServer:
|
|
|
249
255
|
def __init__(
|
|
250
256
|
self,
|
|
251
257
|
directory: str = ".",
|
|
258
|
+
host: str = "localhost",
|
|
252
259
|
port: int = 8000,
|
|
253
260
|
base_path: str = "",
|
|
254
261
|
strict: bool = True,
|
|
@@ -261,6 +268,7 @@ class GHPageServer:
|
|
|
261
268
|
Initialize the server.
|
|
262
269
|
|
|
263
270
|
:param directory: Root directory to serve files from.
|
|
271
|
+
:param host: Host address to bind the server to.
|
|
264
272
|
:param port: Port number to bind the server to.
|
|
265
273
|
:param base_path: URL base path prefix for serving content.
|
|
266
274
|
:param strict: If False, enables automatic ".html" resolution.
|
|
@@ -271,6 +279,7 @@ class GHPageServer:
|
|
|
271
279
|
"""
|
|
272
280
|
_validate_inputs(
|
|
273
281
|
directory=directory,
|
|
282
|
+
host=host,
|
|
274
283
|
port=port,
|
|
275
284
|
base_path=base_path,
|
|
276
285
|
strict=strict,
|
|
@@ -280,6 +289,7 @@ class GHPageServer:
|
|
|
280
289
|
directory_listing=directory_listing
|
|
281
290
|
)
|
|
282
291
|
self._directory = str(Path(directory).resolve())
|
|
292
|
+
self._host = host
|
|
283
293
|
self._port = port
|
|
284
294
|
self._url = None
|
|
285
295
|
self._base_path = base_path
|
|
@@ -315,11 +325,11 @@ class GHPageServer:
|
|
|
315
325
|
server_cls = _ThreadedTCPServer if self._threaded else socketserver.TCPServer
|
|
316
326
|
|
|
317
327
|
try:
|
|
318
|
-
self._httpd = server_cls((
|
|
328
|
+
self._httpd = server_cls((self._host, self._port), handler)
|
|
319
329
|
except OSError as e:
|
|
320
330
|
_handle_bind_error(self._port, e)
|
|
321
331
|
self._port = self._httpd.server_address[1]
|
|
322
|
-
self._url = f"http://
|
|
332
|
+
self._url = f"http://{self._host}:{self._port}{self._base_path}"
|
|
323
333
|
self._print_server_info()
|
|
324
334
|
|
|
325
335
|
if self._auto_open:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ghps
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7
|
|
4
4
|
Summary: Ghps: A Minimal GitHub Pages Simulator for Local Development
|
|
5
5
|
Home-page: https://github.com/sepandhaghighi/ghps
|
|
6
|
-
Download-URL: https://github.com/sepandhaghighi/ghps/tarball/v0.
|
|
6
|
+
Download-URL: https://github.com/sepandhaghighi/ghps/tarball/v0.7
|
|
7
7
|
Author: Sepand Haghighi
|
|
8
8
|
Author-email: me@sepand.tech
|
|
9
9
|
License: MIT
|
|
@@ -101,13 +101,13 @@ Dynamic: summary
|
|
|
101
101
|
## Installation
|
|
102
102
|
|
|
103
103
|
### Source Code
|
|
104
|
-
- Download [Version 0.
|
|
104
|
+
- Download [Version 0.7](https://github.com/sepandhaghighi/ghps/archive/v0.7.zip) or [Latest Source](https://github.com/sepandhaghighi/ghps/archive/dev.zip)
|
|
105
105
|
- `pip install .`
|
|
106
106
|
|
|
107
107
|
### PyPI
|
|
108
108
|
|
|
109
109
|
- Check [Python Packaging User Guide](https://packaging.python.org/installing/)
|
|
110
|
-
- `pip install ghps==0.
|
|
110
|
+
- `pip install ghps==0.7`
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
## Usage
|
|
@@ -117,13 +117,14 @@ Ghps can be used both as a CLI tool and as a Python library.
|
|
|
117
117
|
### CLI
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
ghps --port=8080 --no-cache --no-threaded
|
|
120
|
+
ghps --host=127.0.0.1 --port=8080 --no-cache --no-threaded
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
#### Options
|
|
124
124
|
|
|
125
125
|
| Option | Description | Default |
|
|
126
126
|
|--------|-------------|----------|
|
|
127
|
+
| `--host` | Host address to bind to | `localhost` |
|
|
127
128
|
| `-p, --port` | Port to serve on | `8000` |
|
|
128
129
|
| `-d, --directory` | Directory to serve | Current directory (`.`) |
|
|
129
130
|
| `-b, --base-path` | Base path for project pages (e.g. `/repo-name`) | `""` |
|
|
@@ -133,7 +134,11 @@ ghps --port=8080 --no-cache --no-threaded
|
|
|
133
134
|
| `--auto-open` | Automatically open the server URL | Disable |
|
|
134
135
|
| `--directory-listing` | Enable directory listing | Disable |
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
> [!NOTE]
|
|
138
|
+
> You can set `--port=0` to let the OS automatically select an available port.
|
|
139
|
+
|
|
140
|
+
> [!NOTE]
|
|
141
|
+
> You can use `--host=0.0.0.0` to bind Ghps to all available network interfaces, or specify a particular address such as `127.0.0.1`.
|
|
137
142
|
|
|
138
143
|
|
|
139
144
|
### Library
|
|
@@ -143,6 +148,7 @@ from ghps import GHPageServer
|
|
|
143
148
|
|
|
144
149
|
server = GHPageServer(
|
|
145
150
|
directory="dist",
|
|
151
|
+
host="localhost",
|
|
146
152
|
port=5000,
|
|
147
153
|
base_path="/repo-name",
|
|
148
154
|
strict=True,
|
|
@@ -159,6 +165,7 @@ server.start()
|
|
|
159
165
|
| Parameter | Type | Description | Default |
|
|
160
166
|
|------------|------|-------------|----------|
|
|
161
167
|
| `directory` | `str` | Directory to serve | `"."` |
|
|
168
|
+
| `host` | `str` | Host address to bind the server to | `"localhost"` |
|
|
162
169
|
| `port` | `int` | Port number | `8000` |
|
|
163
170
|
| `base_path` | `str` | Base path for project page simulation | `""` |
|
|
164
171
|
| `strict` | `bool` | Enforce GitHub-like routing behavior | `True` |
|
|
@@ -167,7 +174,11 @@ server.start()
|
|
|
167
174
|
| `auto_open` | `bool` | Automatically open the server URL | `False` |
|
|
168
175
|
| `directory_listing` | `bool` | Enable directory listing | `False` |
|
|
169
176
|
|
|
170
|
-
|
|
177
|
+
> [!NOTE]
|
|
178
|
+
> You can set `port=0` to let the OS automatically select an available port.
|
|
179
|
+
|
|
180
|
+
> [!NOTE]
|
|
181
|
+
> The `host` parameter controls the network interface used for server binding. The default is `"localhost"`.
|
|
171
182
|
|
|
172
183
|
## Issues & Bug Reports
|
|
173
184
|
|
|
@@ -218,6 +229,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
|
218
229
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
219
230
|
|
|
220
231
|
## [Unreleased]
|
|
232
|
+
## [0.7] - 2026-09-22
|
|
233
|
+
### Added
|
|
234
|
+
- `host` parameter
|
|
235
|
+
- `--host` CLI argument
|
|
236
|
+
### Changed
|
|
237
|
+
- Test system modified
|
|
238
|
+
- `README.md` updated
|
|
221
239
|
## [0.6] - 2026-08-31
|
|
222
240
|
### Added
|
|
223
241
|
- Custom default error page
|
|
@@ -265,7 +283,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
265
283
|
- Command line interface
|
|
266
284
|
- Test system
|
|
267
285
|
|
|
268
|
-
[Unreleased]: https://github.com/sepandhaghighi/ghps/compare/v0.
|
|
286
|
+
[Unreleased]: https://github.com/sepandhaghighi/ghps/compare/v0.7...dev
|
|
287
|
+
[0.7]: https://github.com/sepandhaghighi/ghps/compare/v0.6...v0.7
|
|
269
288
|
[0.6]: https://github.com/sepandhaghighi/ghps/compare/v0.5...v0.6
|
|
270
289
|
[0.5]: https://github.com/sepandhaghighi/ghps/compare/v0.4...v0.5
|
|
271
290
|
[0.4]: https://github.com/sepandhaghighi/ghps/compare/v0.3...v0.4
|
{ghps-0.6 → ghps-0.7}/setup.py
RENAMED
|
@@ -22,7 +22,7 @@ def read_description() -> str:
|
|
|
22
22
|
setup(
|
|
23
23
|
name='ghps',
|
|
24
24
|
packages=['ghps'],
|
|
25
|
-
version='0.
|
|
25
|
+
version='0.7',
|
|
26
26
|
description='Ghps: A Minimal GitHub Pages Simulator for Local Development',
|
|
27
27
|
long_description=read_description(),
|
|
28
28
|
long_description_content_type='text/markdown',
|
|
@@ -30,7 +30,7 @@ setup(
|
|
|
30
30
|
author='Sepand Haghighi',
|
|
31
31
|
author_email='me@sepand.tech',
|
|
32
32
|
url='https://github.com/sepandhaghighi/ghps',
|
|
33
|
-
download_url='https://github.com/sepandhaghighi/ghps/tarball/v0.
|
|
33
|
+
download_url='https://github.com/sepandhaghighi/ghps/tarball/v0.7',
|
|
34
34
|
keywords='github gh-pages static-server static-hosting development server local http simulator testing cli python',
|
|
35
35
|
project_urls={
|
|
36
36
|
'Source': 'https://github.com/sepandhaghighi/ghps'
|
|
@@ -36,6 +36,7 @@ def test_cli_default_arguments(monkeypatch):
|
|
|
36
36
|
|
|
37
37
|
run_cli(monkeypatch, [])
|
|
38
38
|
|
|
39
|
+
assert captured["host"] == "localhost"
|
|
39
40
|
assert captured["port"] == 8000
|
|
40
41
|
assert captured["strict"] is True
|
|
41
42
|
assert captured["no_cache"] is False
|
|
@@ -64,6 +65,26 @@ def test_cli_custom_port_and_directory(monkeypatch, tmp_path):
|
|
|
64
65
|
assert captured["directory"] == str(tmp_path.resolve())
|
|
65
66
|
|
|
66
67
|
|
|
68
|
+
def test_cli_host(monkeypatch):
|
|
69
|
+
captured = {}
|
|
70
|
+
|
|
71
|
+
def fake_init(self, **kwargs):
|
|
72
|
+
captured.update(kwargs)
|
|
73
|
+
|
|
74
|
+
monkeypatch.setattr(ghps.cli, "GHPageServer", type(
|
|
75
|
+
"MockServer",
|
|
76
|
+
(),
|
|
77
|
+
{
|
|
78
|
+
"__init__": fake_init,
|
|
79
|
+
"start": lambda self: None,
|
|
80
|
+
},
|
|
81
|
+
))
|
|
82
|
+
|
|
83
|
+
run_cli(monkeypatch, ["--host", "127.0.0.1"])
|
|
84
|
+
|
|
85
|
+
assert captured["host"] == "127.0.0.1"
|
|
86
|
+
|
|
87
|
+
|
|
67
88
|
def test_cli_base_path(monkeypatch):
|
|
68
89
|
captured = {}
|
|
69
90
|
|
|
@@ -47,6 +47,20 @@ def test_directory_not_directory(tmp_path):
|
|
|
47
47
|
)
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
def test_invalid_host_type(tmp_path):
|
|
51
|
+
with pytest.raises(GHPSValidationError, match="`host` must be str."):
|
|
52
|
+
GHPageServer(
|
|
53
|
+
directory=tmp_path,
|
|
54
|
+
port=8000,
|
|
55
|
+
host=123,
|
|
56
|
+
base_path="",
|
|
57
|
+
strict=True,
|
|
58
|
+
no_cache=False,
|
|
59
|
+
threaded=True,
|
|
60
|
+
directory_listing=False,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
50
64
|
def test_invalid_port_type1(tmp_path):
|
|
51
65
|
with pytest.raises(GHPSValidationError, match="`port` must be int."):
|
|
52
66
|
GHPageServer(
|
|
@@ -259,6 +259,25 @@ def test_auto_open_disabled(mock_server_cls, mock_web_open, tmp_path):
|
|
|
259
259
|
mock_web_open.assert_not_called()
|
|
260
260
|
|
|
261
261
|
|
|
262
|
+
@patch("ghps.server.webbrowser.open")
|
|
263
|
+
@patch("ghps.server._ThreadedTCPServer")
|
|
264
|
+
def test_auto_open_custom_host(mock_server_cls, mock_web_open, tmp_path):
|
|
265
|
+
mock_server = mock_server_cls.return_value
|
|
266
|
+
mock_server.server_address = ("127.0.0.1", 8000)
|
|
267
|
+
mock_server.serve_forever.side_effect = KeyboardInterrupt
|
|
268
|
+
|
|
269
|
+
server = GHPageServer(
|
|
270
|
+
directory=tmp_path,
|
|
271
|
+
port=8000,
|
|
272
|
+
host="127.0.0.1",
|
|
273
|
+
auto_open=True,
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
server.start()
|
|
277
|
+
|
|
278
|
+
mock_web_open.assert_called_once_with("http://127.0.0.1:8000")
|
|
279
|
+
|
|
280
|
+
|
|
262
281
|
@patch("ghps.server._ThreadedTCPServer")
|
|
263
282
|
def test_random_port_resolution(mock_server_cls, tmp_path):
|
|
264
283
|
mock_server = mock_server_cls.return_value
|
|
@@ -272,6 +291,26 @@ def test_random_port_resolution(mock_server_cls, tmp_path):
|
|
|
272
291
|
assert server._port == 54321
|
|
273
292
|
|
|
274
293
|
|
|
294
|
+
@patch("ghps.server._ThreadedTCPServer")
|
|
295
|
+
def test_custom_host_binding(mock_server_cls, tmp_path):
|
|
296
|
+
mock_server = mock_server_cls.return_value
|
|
297
|
+
mock_server.server_address = ("127.0.0.1", 8000)
|
|
298
|
+
mock_server.serve_forever.side_effect = KeyboardInterrupt
|
|
299
|
+
|
|
300
|
+
server = GHPageServer(
|
|
301
|
+
directory=tmp_path,
|
|
302
|
+
port=8000,
|
|
303
|
+
host="127.0.0.1",
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
server.start()
|
|
307
|
+
|
|
308
|
+
mock_server_cls.assert_called_once()
|
|
309
|
+
address = mock_server_cls.call_args[0][0]
|
|
310
|
+
|
|
311
|
+
assert address == ("127.0.0.1", 8000)
|
|
312
|
+
|
|
313
|
+
|
|
275
314
|
def test_directory_listing_enabled():
|
|
276
315
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
277
316
|
Path(tmpdir, "file.txt").write_text("Hello")
|
{ghps-0.6 → ghps-0.7}/AUTHORS.md
RENAMED
|
File without changes
|
{ghps-0.6 → ghps-0.7}/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ghps-0.6 → ghps-0.7}/setup.cfg
RENAMED
|
File without changes
|