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

Conversation

falbrechtskirchinger
Copy link
Contributor

@falbrechtskirchinger falbrechtskirchinger commented Apr 26, 2022

This PR adds a script for serving the amalgamated header on a local HTTPS server. When the header file is requested, the header is automatically amalgamated if any of the source files have been modified.

The header can then be included on Compiler Explorer like this:

#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;
}

Note that the #include <url> is resolved client-side, making it possible to host the header locally. HTTPS is nevertheless required, as it is hard-coded in the Compiler Explorer regex.


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

Prerequisites

  1. Make sure these Python packages are installed.

    PyYAML
    watchdog
    

    (see scripts/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.

    • 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 directory it is homed in.
The built-in configuration expects the certificate localhost.pem and the private key localhost-key.pemto 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 and try it out:

#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 scripts/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:

    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.

@gregmarr
Copy link
Contributor

Wow. I haven't tried this, but it sounds awesome.

@coveralls
Copy link

coveralls commented Apr 26, 2022

Coverage Status

Coverage remained the same at 100.0% when pulling ce8040d on falbrechtskirchinger:serve_header into b21c345 on nlohmann:develop.

@falbrechtskirchinger
Copy link
Contributor Author

Here's a demo of the script in action, integrated into VSCode. Note how the script injects a build count the user can check to be sure the correct version of the code is being run.
serve_header_demo01_annotated

scripts/serve_header/README.md Outdated Show resolved Hide resolved
scripts/serve_header/README.md Outdated Show resolved Hide resolved
scripts/serve_header/README.md Outdated Show resolved Hide resolved
@nlohmann
Copy link
Owner

Wow, I really like this idea! Haven't tried it myself, but there goes my "I'm not using MSVC so I cannot try it"-excuse ;-)

@nlohmann
Copy link
Owner

(And I think your screenshot should go into the README)

## Usage

`serve_header.py` has a builtin default configuration that will serve the header from the project folder it is homed in.
It expects to find the certificate `localhost.pem` and the private key `localhost-key.pem` in the projects root directory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

project's root or project root

from the project folder it is homed in.

I'm having trouble understanding this. By project folder and project root, do you mean the directory containing the scripts/serve_header directory, the directory that is checked out from GitHub? I assumed that's what you meant, but the multiple work tree example confused me about that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Project" refers to the JSON library or the git checkout, yes.

I'll fix the typo and see if I can come up with clearer wording.

Copy link
Contributor Author

@falbrechtskirchinger falbrechtskirchinger Apr 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the phrase "top level or project root directory" (used consistently) clearer to you?

Edit: I'm also using "web server root directory" when speaking about the root configuration option.

scripts/serve_header/README.md Outdated Show resolved Hide resolved
Copy link
Contributor

@gregmarr gregmarr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for the clarifications.

scripts/serve_header/README.md Outdated Show resolved Hide resolved
Copy link
Owner

@nlohmann nlohmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move the scripts folder to the test folder to keep the root a bit cleaner?

scripts/serve_header/README.md Outdated Show resolved Hide resolved
scripts/serve_header/README.md Outdated Show resolved Hide resolved
@nlohmann
Copy link
Owner

nlohmann commented May 1, 2022

Please update to the latest develop branch (we renamed some folders in #3462).

@nlohmann nlohmann added the please rebase Please rebase your branch to origin/develop label May 1, 2022
@nlohmann nlohmann removed the please rebase Please rebase your branch to origin/develop label May 1, 2022
Copy link
Owner

@nlohmann nlohmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@nlohmann nlohmann added this to the Release 3.11.0 milestone May 1, 2022
@nlohmann nlohmann self-assigned this May 1, 2022
@nlohmann nlohmann merged commit 0c698b7 into nlohmann:develop May 1, 2022
@nlohmann
Copy link
Owner

nlohmann commented May 1, 2022

Thanks!!!

@falbrechtskirchinger falbrechtskirchinger deleted the serve_header branch May 1, 2022 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants