Add --mission CLI Flag And GET /mission HTTP Endpoint To Expose Repository Mission Statement
Overview
In this article, we will explore the implementation of a new "mission" feature that allows users to view the repository's mission statement via both the CLI and the HTTP server. This feature will be achieved by adding a --mission
flag to the CLI and a GET /mission
endpoint in the persistent HTTP server.
Changes to Apply
CLI Handler
To implement the --mission
flag in the CLI handler, we need to make the following changes:
- Create a new function
processMission(args)
similar toprocessVersion
:- Detect the
--mission
flag. - Read the
MISSION.md
file from the repository root usingfs.readFileSync
. - On success, output a JSON object:
{ mission: <file content as string> }
. - On failure, call
logError("Mission CLI failed", error)
and return HTTP-style exit.
- Detect the
- In
main(args)
, callawait processMission(args)
immediately after version and before default case, and return.
Here is the updated code for the CLI handler:
// sandbox/source/main.js
const fs = require('fs');
const logError = require('./lib/logError');
async function processMission(args) {
const missionFlag = args.includes('--mission');
if (!missionFlag) return;
try {
const missionContent = fs.readFileSync('MISSION.md', 'utf8');
console.log(JSON.stringify({ mission: missionContent }));
} catch (error) {
logError("Mission CLI failed", error);
process.exit(1);
}
}
async function main(args) {
// ... existing code ...
await processMission(args);
// ... existing code ...
}
HTTP Server Endpoint
To implement the GET /mission
endpoint in the HTTP server, we need to make the following changes:
- In the existing
processServe(args)
function, add aGET /mission
route:- On request, read
MISSION.md
from the project root. - Respond with status 200 and JSON payload
{ mission: <string> }
. - Increment
globalThis.callCount
and handle errors by returning HTTP 500 with{ error, message }
usinglogError
.
- On request, read
Here is the updated code for the HTTP server endpoint:
// src/lib/main.js
const fs = require('fs');
const logError = require('./lib/logError');
async function processServe(args) {
// ... existing code ...
app.get('/mission', async (req, res) => {
try {
const missionContent = fs.readFileSync('MISSION.md', 'utf8');
res.status(200).json({ mission: missionContent });
globalThis.callCount++;
} catch (error) {
logError("Mission HTTP failed", error);
res.status(500).json({ error, message: "Internal Server Error" });
}
});
// ... existing code ...
}
Tests
To ensure the correctness of the implementation, we need to write tests for both the CLI and HTTP server endpoints.
CLI Tests
Here are the updated tests for the CLI:
// sandbox/tests/main.test.js
const = require('../source/main');
describe('CLI', () => {
it('should log mission statement JSON', async () => {
const args = ['--mission'];
await main(args);
expect(console.log).toHaveBeenCalledTimes(1);
expect(console.log).toHaveBeenCalledWith(JSON.stringify({ mission: 'Mission statement' }));
});
it('should log error on mission statement read failure', async () => {
const fsReadFileSyncMock = jest.spyOn(fs, 'readFileSync').mockImplementationOnce(() => {
throw new Error('Mocked error');
});
const args = ['--mission'];
await main(args);
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledWith('Mission CLI failed: Mocked error');
fsReadFileSyncMock.mockRestore();
});
});
HTTP Tests
Here are the updated tests for the HTTP server:
// tests/unit/main.test.js
const fetch = require('node-fetch');
const fs = require('fs');
const logError = require('../lib/logError');
describe('HTTP', () => {
it('should return mission statement JSON', async () => {
const fsReadFileSyncMock = jest.spyOn(fs, 'readFileSync').mockImplementationOnce(() => 'Mission statement');
const port = await startServer();
const response = await fetch(`http://localhost:${port}/mission`);
expect(response.status).toBe(200);
expect(await response.json()).toEqual({ mission: 'Mission statement' });
fsReadFileSyncMock.mockRestore();
});
it('should return error on mission statement read failure', async () => {
const fsReadFileSyncMock = jest.spyOn(fs, 'readFileSync').mockImplementationOnce(() => {
throw new Error('Mocked error');
});
const port = await startServer();
const response = await fetch(`http://localhost:${port}/mission`);
expect(response.status).toBe(500);
expect(await response.json()).toEqual({ error: 'Mocked error', message: 'Internal Server Error' });
fsReadFileSyncMock.mockRestore();
});
});
Documentation
To ensure that the documentation is up-to-date, we need to update the CLI usage section and add HTTP documentation.
Here is the updated documentation:
# CLI Usage
* `--mission`: Print the mission statement JSON.
# HTTP Endpoints
* `GET /mission`: Return the mission statement JSON.
Dependencies
No new runtime dependencies are required for this feature.
Verification & Acceptance
To verify the correctness of the implementation, we need to run the tests and ensure that all existing and new tests pass.
Here are the steps to verify the implementation:
- Run
npm test
to ensure that all tests pass. - Run
node sandbox/source/main.js --mission
to ensure that the mission statement JSON is printed. - Run
node sandbox/source/main.js --serve
andcurl http://localhost:3000/mission
to ensure that the mission statement JSON is returned and the metrics are incremented. - Verify that the README updates correctly describe the flag and endpoint with examples.
Q: What is the purpose of adding a --mission
flag to the CLI?
A: The purpose of adding a --mission
flag to the CLI is to allow users to view the repository's mission statement via the command line. This feature provides users with easy access to the mission statement, making it easier to understand the purpose and goals of the repository.
Q: How does the --mission
flag work?
A: The --mission
flag works by detecting the presence of the flag in the command line arguments. If the flag is present, the CLI handler reads the MISSION.md
file from the repository root and outputs the mission statement as a JSON object.
Q: What is the purpose of the GET /mission
endpoint in the HTTP server?
A: The purpose of the GET /mission
endpoint in the HTTP server is to provide users with a way to view the repository's mission statement via a web interface. This endpoint allows users to access the mission statement by making a GET request to the /mission
endpoint.
Q: How does the GET /mission
endpoint work?
A: The GET /mission
endpoint works by reading the MISSION.md
file from the repository root and returning the mission statement as a JSON object with a status code of 200. If an error occurs while reading the file, the endpoint returns a status code of 500 with an error message.
Q: What are the benefits of implementing the --mission
flag and GET /mission
endpoint?
A: The benefits of implementing the --mission
flag and GET /mission
endpoint include:
- Improved user experience: By providing users with easy access to the mission statement, we can improve their overall experience with the repository.
- Increased transparency: By making the mission statement easily accessible, we can increase transparency and accountability within the repository.
- Simplified maintenance: By implementing a single endpoint for the mission statement, we can simplify maintenance and reduce the risk of errors.
Q: How do I implement the --mission
flag and GET /mission
endpoint in my own repository?
A: To implement the --mission
flag and GET /mission
endpoint in your own repository, follow these steps:
- Create a new file called
MISSION.md
in the root of your repository and add the mission statement to it. - Update the CLI handler to detect the
--mission
flag and read theMISSION.md
file. - Update the HTTP server to implement the
GET /mission
endpoint and return the mission statement as a JSON object. - Test the implementation to ensure that it works correctly.
Q: What are some common issues that may arise when implementing the --mission
flag and GET /mission
endpoint?
A: Some common issues that may arise when implementing the --mission
flag and GET /mission
endpoint include:
- File not found errors: If the
MISSION.md
file is not found, the implementation will fail. - File read errors If there is an error reading the
MISSION.md
file, the implementation will fail. - Endpoint not implemented correctly: If the
GET /mission
endpoint is not implemented correctly, the implementation will fail.
Q: How do I troubleshoot issues with the --mission
flag and GET /mission
endpoint?
A: To troubleshoot issues with the --mission
flag and GET /mission
endpoint, follow these steps:
- Check the file path: Ensure that the file path to the
MISSION.md
file is correct. - Check the file contents: Ensure that the
MISSION.md
file contains the correct mission statement. - Check the endpoint implementation: Ensure that the
GET /mission
endpoint is implemented correctly. - Test the implementation: Test the implementation to ensure that it works correctly.