Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable rapid testing and development on Compiler Explorer #3456

Merged
merged 1 commit into from
May 1, 2022
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
14 changes: 13 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@
/.idea
/cmake-build-*

/.vs
/.vs/
/.vscode/

# clangd cache
/.cache/

# build directories (vscode-cmake-tools, user-defined, ...)
/build*/

/docs/mkdocs/docs/examples/
/docs/mkdocs/docs/__pycache__/
Expand All @@ -19,3 +26,8 @@
/docs/docset/JSON_for_Modern_C++.docset/
/docs/docset/JSON_for_Modern_C++.tgz
/docs/mkdocs/docs/images/json.gif

# serve_header
/serve_header.yml
/localhost.pem
/localhost-key.pem
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,10 @@ update_hedley:
$(SED) -i '1s/^/#pragma once\n\n/' include/nlohmann/thirdparty/hedley/hedley.hpp
$(SED) -i '1s/^/#pragma once\n\n/' include/nlohmann/thirdparty/hedley/hedley_undef.hpp
$(MAKE) amalgamate

##########################################################################
# serve_header.py
##########################################################################

serve_header:
./tools/serve_header/serve_header.py --make $(MAKE)
91 changes: 91 additions & 0 deletions tools/serve_header/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
serve_header.py
===============

Serves the `single_include/nlohmann/json.hpp` header file over HTTP(S).

The header file is automatically amalgamated on demand.

![serve_header.py demo](demo.png)

## Prerequisites

1. Make sure these Python packages are installed.
```
PyYAML
watchdog
```
(see `tools/serve_header/requirements.txt`)

2. To serve the header over HTTPS (which is required by Compiler Explorer at this time), a certificate is needed.
The recommended method for creating a locally-trusted certificate is to use [`mkcert`](https://github.com/FiloSottile/mkcert).
- Install the `mkcert` certificate authority into your trust store(s):
```
$ mkcert -install
```
- Create a certificate for `localhost`:
```
$ mkcert localhost
```
The command will create two files, `localhost.pem` and `localhost-key.pem`, in the current working directory. It is recommended to create them in the top level or project root directory.

## Usage

`serve_header.py` has a built-in default configuration that will serve the `single_include/nlohmann/json.hpp` header file relative to the top level or project root directory it is homed in.
The built-in configuration expects the certificate `localhost.pem` and the private key `localhost-key.pem`to be located in the top level or project root directory.

To start serving the `json.hpp` header file at `https://localhost:8443/json.hpp`, run this command from the top level or project root directory:
```
$ make serve_header
```

Open [Compiler Explorer](https://godbolt.org/) and try it out:
```cpp
#include <https://localhost:8443/json.hpp>
using namespace nlohmann;

#include <iostream>

int main() {
// these macros are dynamically injected into the header file
std::cout << JSON_BUILD_TIME << " (" << JSON_BUILD_COUNT << ")\n";

return 0;
}
```

> `serve_header.py` dynamically injects the macros `JSON_BUILD_COUNT` and `JSON_BUILD_TIME` into the served header file. By comparing build count or time output from the compiled program with the output from `serve_header.py`, one can be reasonably sure the compiled code uses the expected revision of the header file.

## Configuration

`serve_header.py` will try to read a configuration file `serve_header.yml` in the top level or project root directory, and will fall back on built-in defaults if the file cannot be read.
An annotated example configuration can be found in `tools/serve_header/serve_header.yml.example`.

## Serving `json.hpp` from multiple project directory instances or working trees

`serve_header.py` was designed with the goal of supporting multiple project roots or working trees at the same time.
The recommended directory structure is shown below but `serve_header.py` can work with other structures as well, including a nested hierarchy.
```
json/ ⮜ the parent or web server root directoy
├── develop/ ⮜ the main git checkout
│ └── ...
├── feature1/
│ └── ... any number of additional
├── feature2/ ⮜ working trees (e.g., created
│ └── ... with git worktree)
└── feature3/
└── ...
```

To serve the header of each working tree at `https://localhost:8443/<worktree>/json.hpp`, a configuration file is needed.
1. Create the file `serve_header.yml` in the top level or project root directory of any working tree:
```yaml
root: ..
```
By shifting the web server root directory up one level, the `single_include/nlohmann/json.hpp` header files relative to each sibling directory or working tree will be served.

2. Start `serve_header.py` by running this command from the same top level or project root directory the configuration file is located in:
```
$ make serve_header
```

`serve_header.py` will automatically detect the addition or removal of working trees anywhere within the configured web server root directory.
Binary file added tools/serve_header/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions tools/serve_header/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
PyYAML==6.0
watchdog==2.1.7
Loading