mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 07:04:04 -05:00
Replace nopt with commander.js for argument parsing (#7673)
- Replace nopt with commander.js for better command-line argument parsing - Add automatic help generation with detailed descriptions - Maintain backward compatibility with existing arguments - Remove unused nopt dependency from package.json 🤖 Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
2
.github/workflows/test-frontend.yml
vendored
2
.github/workflows/test-frontend.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v6
|
||||
with:
|
||||
start: npm run dev -- --language c++ --noLocal
|
||||
start: npm run dev -- --language c++ --no-local
|
||||
wait-on: 'http://localhost:10240'
|
||||
wait-on-timeout: 120
|
||||
config: screenshotOnRunFailure=true,video=false
|
||||
|
||||
2
Makefile
2
Makefile
@@ -84,7 +84,7 @@ prebuild: prereqs scripts
|
||||
|
||||
.PHONY: run-only
|
||||
run-only: node-installed ## Runs the site like it runs in production without building it
|
||||
env NODE_ENV=production $(NODE) $(NODE_ARGS) ./out/dist/app.js --webpackContent ./out/webpack/static $(EXTRA_ARGS)
|
||||
env NODE_ENV=production $(NODE) $(NODE_ARGS) ./out/dist/app.js --webpack-content ./out/webpack/static $(EXTRA_ARGS)
|
||||
|
||||
.PHONY: run
|
||||
run: ## Runs the site like it runs in production
|
||||
|
||||
225
app.ts
225
app.ts
@@ -35,12 +35,12 @@ import url from 'node:url';
|
||||
import * as fsSync from 'node:fs';
|
||||
import fs from 'node:fs/promises';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import {Command, OptionValues} from 'commander';
|
||||
import compression from 'compression';
|
||||
import express from 'express';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import morgan from 'morgan';
|
||||
import nopt from 'nopt';
|
||||
import PromClient from 'prom-client';
|
||||
import responseTime from 'response-time';
|
||||
import sanitize from 'sanitize-filename';
|
||||
@@ -92,73 +92,73 @@ import type {Language, LanguageKey} from './types/languages.interfaces.js';
|
||||
|
||||
setBaseDirectory(new URL('.', import.meta.url));
|
||||
|
||||
(nopt as any).invalidHandler = (key: string, val: unknown, types: unknown[]) => {
|
||||
logger.error(
|
||||
`Command line argument type error for "--${key}=${val}",
|
||||
expected ${types.map((t: unknown) => typeof t).join(' | ')}`,
|
||||
);
|
||||
};
|
||||
function parseNumberForOptions(value: string): number {
|
||||
const parsedValue = Number.parseInt(value, 10);
|
||||
if (Number.isNaN(parsedValue)) {
|
||||
throw new Error(`Invalid number: "${value}"`);
|
||||
}
|
||||
return parsedValue;
|
||||
}
|
||||
|
||||
type CompilerExplorerOptions = Partial<{
|
||||
interface CompilerExplorerOptions extends OptionValues {
|
||||
env: string[];
|
||||
rootDir: string;
|
||||
host: string;
|
||||
host?: string;
|
||||
port: number;
|
||||
propDebug: boolean;
|
||||
debug: boolean;
|
||||
dist: boolean;
|
||||
archivedVersions: string;
|
||||
noRemoteFetch: boolean;
|
||||
tmpDir: string;
|
||||
wsl: boolean;
|
||||
language: string[];
|
||||
noCache: boolean;
|
||||
ensureNoIdClash: boolean;
|
||||
logHost: string;
|
||||
logPort: number;
|
||||
hostnameForLogging: string;
|
||||
propDebug?: boolean;
|
||||
debug?: boolean;
|
||||
dist?: boolean;
|
||||
remoteFetch: boolean;
|
||||
tmpDir?: string;
|
||||
wsl?: boolean;
|
||||
language?: string[];
|
||||
cache: boolean;
|
||||
ensureNoIdClash?: boolean;
|
||||
logHost?: string;
|
||||
logPort?: number;
|
||||
hostnameForLogging?: string;
|
||||
suppressConsoleLog: boolean;
|
||||
metricsPort: number;
|
||||
loki: string;
|
||||
discoveryonly: string;
|
||||
prediscovered: string;
|
||||
metricsPort?: number;
|
||||
loki?: string;
|
||||
discoveryOnly?: string;
|
||||
prediscovered?: string;
|
||||
webpackContent?: string;
|
||||
local: boolean;
|
||||
version: boolean;
|
||||
webpackContent: string;
|
||||
noLocal: boolean;
|
||||
}>;
|
||||
}
|
||||
|
||||
// Parse arguments from command line 'node ./app.js args...'
|
||||
const opts = nopt({
|
||||
env: [String, Array],
|
||||
rootDir: [String],
|
||||
host: [String],
|
||||
port: [Number],
|
||||
propDebug: [Boolean],
|
||||
debug: [Boolean],
|
||||
dist: [Boolean],
|
||||
archivedVersions: [String],
|
||||
// Ignore fetch marks and assume every compiler is found locally
|
||||
noRemoteFetch: [Boolean],
|
||||
tmpDir: [String],
|
||||
wsl: [Boolean],
|
||||
// If specified, only loads the specified languages, resulting in faster loadup/iteration times
|
||||
language: [String, Array],
|
||||
// Do not use caching for compilation results (Requests might still be cached by the client's browser)
|
||||
noCache: [Boolean],
|
||||
// Don't cleanly run if two or more compilers have clashing ids
|
||||
ensureNoIdClash: [Boolean],
|
||||
logHost: [String],
|
||||
logPort: [Number],
|
||||
hostnameForLogging: [String],
|
||||
suppressConsoleLog: [Boolean],
|
||||
metricsPort: [Number],
|
||||
loki: [String],
|
||||
discoveryonly: [String],
|
||||
prediscovered: [String],
|
||||
version: [Boolean],
|
||||
webpackContent: [String],
|
||||
noLocal: [Boolean],
|
||||
}) as CompilerExplorerOptions;
|
||||
const program = new Command();
|
||||
program
|
||||
.name('compiler-explorer')
|
||||
.description('Interactively investigate compiler output')
|
||||
.option('--env <environments...>', 'Environment(s) to use', ['dev'])
|
||||
.option('--root-dir <dir>', 'Root directory for config files', './etc')
|
||||
.option('--host <hostname>', 'Hostname to listen on')
|
||||
.option('--port <port>', 'Port to listen on', parseNumberForOptions, 10240)
|
||||
.option('--prop-debug', 'Debug properties')
|
||||
.option('--debug', 'Enable debug output')
|
||||
.option('--dist', 'Running in dist mode')
|
||||
.option('--no-remote-fetch', 'Ignore fetch marks and assume every compiler is found locally')
|
||||
.option('--tmpDir, --tmp-dir <dir>', 'Directory to use for temporary files')
|
||||
.option('--wsl', 'Running under Windows Subsystem for Linux')
|
||||
.option('--language <languages...>', 'Only load specified languages for faster startup')
|
||||
.option('--no-cache', 'Do not use caching for compilation results')
|
||||
.option('--ensure-no-id-clash', "Don't run if compilers have clashing ids")
|
||||
.option('--logHost, --log-host <hostname>', 'Hostname for remote logging')
|
||||
.option('--logPort, --log-port <port>', 'Port for remote logging', parseNumberForOptions)
|
||||
.option('--hostname-for-logging <hostname>', 'Hostname to use in logs')
|
||||
.option('--suppressConsoleLog, --suppress-console-log', 'Disable console logging')
|
||||
.option('--metricsPort, --metrics-port <port>', 'Port to serve metrics on', parseNumberForOptions)
|
||||
.option('--loki <url>', 'URL for Loki logging')
|
||||
.option('--discoveryonly, --discovery-only <file>', 'Output discovery info to file and exit')
|
||||
.option('--prediscovered <file>', 'Input discovery info from file')
|
||||
.option('--webpack-content <dir>', 'Path to webpack content')
|
||||
.option('--no-local', 'Disable local config')
|
||||
.option('--version', 'Show version information');
|
||||
|
||||
program.parse();
|
||||
|
||||
const opts = program.opts<CompilerExplorerOptions>();
|
||||
|
||||
if (opts.debug) logger.level = 'debug';
|
||||
|
||||
@@ -222,39 +222,29 @@ const releaseBuildNumber = (() => {
|
||||
return '';
|
||||
})();
|
||||
|
||||
function patchUpLanguageArg(languages: string[] | undefined): string[] | null {
|
||||
if (!languages) return null;
|
||||
if (languages.length === 1) {
|
||||
// Support old style comma-separated language args.
|
||||
return languages[0].split(',');
|
||||
}
|
||||
return languages;
|
||||
}
|
||||
|
||||
// Set default values for omitted arguments
|
||||
const defArgs: AppArguments = {
|
||||
rootDir: opts.rootDir || './etc',
|
||||
env: opts.env || ['dev'],
|
||||
const appArgs: AppArguments = {
|
||||
rootDir: opts.rootDir,
|
||||
env: opts.env,
|
||||
hostname: opts.host,
|
||||
port: opts.port || 10240,
|
||||
port: opts.port,
|
||||
gitReleaseName: gitReleaseName,
|
||||
releaseBuildNumber: releaseBuildNumber,
|
||||
wantedLanguages: patchUpLanguageArg(opts.language),
|
||||
doCache: !opts.noCache,
|
||||
fetchCompilersFromRemote: !opts.noRemoteFetch,
|
||||
wantedLanguages: opts.language,
|
||||
doCache: opts.cache,
|
||||
fetchCompilersFromRemote: opts.remoteFetch,
|
||||
ensureNoCompilerClash: opts.ensureNoIdClash,
|
||||
suppressConsoleLog: opts.suppressConsoleLog || false,
|
||||
suppressConsoleLog: opts.suppressConsoleLog,
|
||||
};
|
||||
|
||||
if (opts.logHost && opts.logPort) {
|
||||
logToPapertrail(opts.logHost, opts.logPort, defArgs.env.join('.'), opts.hostnameForLogging);
|
||||
logToPapertrail(opts.logHost, opts.logPort, appArgs.env.join('.'), opts.hostnameForLogging);
|
||||
}
|
||||
|
||||
if (opts.loki) {
|
||||
logToLoki(opts.loki);
|
||||
}
|
||||
|
||||
if (defArgs.suppressConsoleLog) {
|
||||
if (appArgs.suppressConsoleLog) {
|
||||
logger.info('Disabling further console logging');
|
||||
suppressConsoleLog();
|
||||
}
|
||||
@@ -276,12 +266,12 @@ function getFaviconFilename() {
|
||||
|
||||
const propHierarchy = [
|
||||
'defaults',
|
||||
defArgs.env,
|
||||
defArgs.env.map(e => `${e}.${process.platform}`),
|
||||
appArgs.env,
|
||||
appArgs.env.map(e => `${e}.${process.platform}`),
|
||||
process.platform,
|
||||
os.hostname(),
|
||||
].flat();
|
||||
if (!opts.noLocal) {
|
||||
if (opts.local) {
|
||||
propHierarchy.push('local');
|
||||
}
|
||||
logger.info(`properties hierarchy: ${propHierarchy.join(', ')}`);
|
||||
@@ -290,20 +280,20 @@ logger.info(`properties hierarchy: ${propHierarchy.join(', ')}`);
|
||||
if (opts.propDebug) props.setDebug(true);
|
||||
|
||||
// *All* files in config dir are parsed
|
||||
const configDir = path.join(defArgs.rootDir, 'config');
|
||||
const configDir = path.join(appArgs.rootDir, 'config');
|
||||
props.initialize(configDir, propHierarchy);
|
||||
// Instantiate a function to access records concerning "compiler-explorer"
|
||||
// in hidden object props.properties
|
||||
const ceProps = props.propsFor('compiler-explorer');
|
||||
const restrictToLanguages = ceProps<string>('restrictToLanguages');
|
||||
if (restrictToLanguages) {
|
||||
defArgs.wantedLanguages = restrictToLanguages.split(',');
|
||||
appArgs.wantedLanguages = restrictToLanguages.split(',');
|
||||
}
|
||||
|
||||
const languages = (() => {
|
||||
if (defArgs.wantedLanguages) {
|
||||
if (appArgs.wantedLanguages) {
|
||||
const filteredLangs: Partial<Record<LanguageKey, Language>> = {};
|
||||
for (const wantedLang of defArgs.wantedLanguages) {
|
||||
for (const wantedLang of appArgs.wantedLanguages) {
|
||||
for (const lang of Object.values(allLanguages)) {
|
||||
if (lang.id === wantedLang || lang.name === wantedLang || lang.alias.includes(wantedLang)) {
|
||||
filteredLangs[lang.id] = lang;
|
||||
@@ -459,8 +449,7 @@ function oldGoogleUrlHandler(req: express.Request, res: express.Response, next:
|
||||
}
|
||||
|
||||
function startListening(server: express.Express) {
|
||||
const ss = systemdSocket();
|
||||
let _port;
|
||||
const ss: {fd: number} | null = systemdSocket(); // TODO: I'm not sure this works any more
|
||||
if (ss) {
|
||||
// ms (5 min default)
|
||||
const idleTimeout = process.env.IDLE_TIMEOUT;
|
||||
@@ -478,9 +467,15 @@ function startListening(server: express.Express) {
|
||||
server.all('*', reset);
|
||||
logger.info(` IDLE_TIMEOUT: ${idleTimeout}`);
|
||||
}
|
||||
_port = ss;
|
||||
logger.info(` Listening on systemd socket: ${JSON.stringify(ss)}`);
|
||||
server.listen(ss);
|
||||
} else {
|
||||
_port = defArgs.port;
|
||||
logger.info(` Listening on http://${appArgs.hostname || 'localhost'}:${appArgs.port}/`);
|
||||
if (appArgs.hostname) {
|
||||
server.listen(appArgs.port, appArgs.hostname);
|
||||
} else {
|
||||
server.listen(appArgs.port);
|
||||
}
|
||||
}
|
||||
|
||||
const startupGauge = new PromClient.Gauge({
|
||||
@@ -489,24 +484,8 @@ function startListening(server: express.Express) {
|
||||
});
|
||||
startupGauge.set(process.uptime());
|
||||
const startupDurationMs = Math.floor(process.uptime() * 1000);
|
||||
if (Number.isNaN(Number.parseInt(_port))) {
|
||||
// unix socket, not a port number...
|
||||
logger.info(` Listening on socket: //${_port}/`);
|
||||
logger.info(` Startup duration: ${startupDurationMs}ms`);
|
||||
logger.info('=======================================');
|
||||
server.listen(_port);
|
||||
} else {
|
||||
// normal port number
|
||||
logger.info(` Listening on http://${defArgs.hostname || 'localhost'}:${_port}/`);
|
||||
logger.info(` Startup duration: ${startupDurationMs}ms`);
|
||||
logger.info('=======================================');
|
||||
// silly express typing, passing undefined is fine but
|
||||
if (defArgs.hostname) {
|
||||
server.listen(_port, defArgs.hostname);
|
||||
} else {
|
||||
server.listen(_port);
|
||||
}
|
||||
}
|
||||
logger.info(` Startup duration: ${startupDurationMs}ms`);
|
||||
logger.info('=======================================');
|
||||
}
|
||||
|
||||
const awsProps = props.propsFor('aws');
|
||||
@@ -514,31 +493,31 @@ const awsProps = props.propsFor('aws');
|
||||
// eslint-disable-next-line max-statements
|
||||
async function main() {
|
||||
await aws.initConfig(awsProps);
|
||||
SetupSentry(aws.getConfig('sentryDsn'), ceProps, releaseBuildNumber, gitReleaseName, defArgs);
|
||||
SetupSentry(aws.getConfig('sentryDsn'), ceProps, releaseBuildNumber, gitReleaseName, appArgs);
|
||||
const webServer = express();
|
||||
const router = express.Router();
|
||||
|
||||
startWineInit();
|
||||
|
||||
RemoteExecutionQuery.initRemoteExecutionArchs(ceProps, defArgs.env);
|
||||
RemoteExecutionQuery.initRemoteExecutionArchs(ceProps, appArgs.env);
|
||||
|
||||
const formattingService = new FormattingService();
|
||||
await formattingService.initialize(ceProps);
|
||||
|
||||
const clientOptionsHandler = new ClientOptionsHandler(sources, compilerProps, defArgs);
|
||||
const clientOptionsHandler = new ClientOptionsHandler(sources, compilerProps, appArgs);
|
||||
const compilationQueue = CompilationQueue.fromProps(compilerProps.ceProps);
|
||||
const compilationEnvironment = new CompilationEnvironment(
|
||||
compilerProps,
|
||||
awsProps,
|
||||
compilationQueue,
|
||||
formattingService,
|
||||
defArgs.doCache,
|
||||
appArgs.doCache,
|
||||
);
|
||||
const compileHandler = new CompileHandler(compilationEnvironment, awsProps);
|
||||
compilationEnvironment.setCompilerFinder(compileHandler.findCompiler.bind(compileHandler));
|
||||
const storageType = getStorageTypeByKey(storageSolution);
|
||||
const storageHandler = new storageType(httpRoot, compilerProps, awsProps);
|
||||
const compilerFinder = new CompilerFinder(compileHandler, compilerProps, defArgs, clientOptionsHandler);
|
||||
const compilerFinder = new CompilerFinder(compileHandler, compilerProps, appArgs, clientOptionsHandler);
|
||||
|
||||
const isExecutionWorker = ceProps<boolean>('execqueue.is_worker', false);
|
||||
const healthCheckFilePath = ceProps('healthCheckFilePath', null) as string | null;
|
||||
@@ -576,7 +555,7 @@ async function main() {
|
||||
if (!isExecutionWorker && initialCompilers.length === 0) {
|
||||
throw new Error('Unexpected failure, no compilers found!');
|
||||
}
|
||||
if (defArgs.ensureNoCompilerClash) {
|
||||
if (appArgs.ensureNoCompilerClash) {
|
||||
logger.warn('Ensuring no compiler ids clash');
|
||||
if (initialFindResults.foundClash) {
|
||||
// If we are forced to have no clashes, throw an error with some explanation
|
||||
@@ -586,7 +565,7 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.discoveryonly) {
|
||||
if (opts.discoveryOnly) {
|
||||
for (const compiler of initialCompilers) {
|
||||
if (compiler.buildenvsetup && compiler.buildenvsetup.id === '') delete compiler.buildenvsetup;
|
||||
|
||||
@@ -597,8 +576,8 @@ async function main() {
|
||||
compiler.cachedPossibleArguments = compilerInstance.possibleArguments.possibleArguments;
|
||||
}
|
||||
}
|
||||
await fs.writeFile(opts.discoveryonly, JSON.stringify(initialCompilers));
|
||||
logger.info(`Discovered compilers saved to ${opts.discoveryonly}`);
|
||||
await fs.writeFile(opts.discoveryOnly, JSON.stringify(initialCompilers));
|
||||
logger.info(`Discovered compilers saved to ${opts.discoveryOnly}`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
@@ -607,7 +586,7 @@ async function main() {
|
||||
clientOptionsHandler,
|
||||
renderConfig,
|
||||
storageHandler,
|
||||
defArgs.wantedLanguages?.[0],
|
||||
appArgs.wantedLanguages?.[0],
|
||||
);
|
||||
const routeApi = new RouteAPI(router, {
|
||||
compileHandler,
|
||||
@@ -615,7 +594,7 @@ async function main() {
|
||||
storageHandler,
|
||||
compilationEnvironment,
|
||||
ceProps,
|
||||
defArgs,
|
||||
defArgs: appArgs,
|
||||
renderConfig,
|
||||
renderGoldenLayout,
|
||||
});
|
||||
@@ -649,7 +628,7 @@ async function main() {
|
||||
|
||||
if (opts.metricsPort) {
|
||||
logger.info(`Running metrics server on port ${opts.metricsPort}`);
|
||||
setupMetricsServer(opts.metricsPort, defArgs.hostname);
|
||||
setupMetricsServer(opts.metricsPort, appArgs.hostname);
|
||||
}
|
||||
|
||||
webServer
|
||||
@@ -851,7 +830,7 @@ async function main() {
|
||||
noscriptHandler.initializeRoutes();
|
||||
routeApi.initializeRoutes();
|
||||
|
||||
if (!defArgs.doCache) {
|
||||
if (!appArgs.doCache) {
|
||||
logger.info(' with disabled caching');
|
||||
}
|
||||
setupEventLoopLagLogging();
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import nopt from 'nopt';
|
||||
import {Command} from 'commander';
|
||||
import _ from 'underscore';
|
||||
|
||||
import {CompilerArguments} from './lib/compiler-arguments.js';
|
||||
@@ -30,12 +30,20 @@ import * as Parsers from './lib/compilers/argument-parsers.js';
|
||||
import {executeDirect} from './lib/exec.js';
|
||||
import {logger} from './lib/logger.js';
|
||||
|
||||
const opts = nopt({
|
||||
parser: [String],
|
||||
exe: [String],
|
||||
padding: [Number],
|
||||
debug: [Boolean],
|
||||
});
|
||||
const program = new Command();
|
||||
program
|
||||
.name('compiler-args-app.ts')
|
||||
.usage('--parser=<compilertype> --exe=<path> [--padding=<number>]')
|
||||
.description(
|
||||
'Extracts compiler arguments\nFor example: node --no-warnings=ExperimentalWarning --import=tsx compiler-args-app.ts --parser=clang --exe=/opt/compiler-explorer/clang-15.0.0/bin/clang++ --padding=50',
|
||||
)
|
||||
.requiredOption('--parser <type>', 'Compiler parser type')
|
||||
.requiredOption('--exe <path>', 'Path to compiler executable')
|
||||
.option('--padding <number>', 'Padding for output formatting', '40')
|
||||
.option('--debug', 'Enable debug output');
|
||||
|
||||
program.parse();
|
||||
const opts = program.opts();
|
||||
|
||||
if (opts.debug) logger.level = 'debug';
|
||||
|
||||
@@ -73,7 +81,7 @@ class CompilerArgsApp {
|
||||
constructor() {
|
||||
this.parserName = opts.parser;
|
||||
this.executable = opts.exe;
|
||||
this.pad = opts.padding || 40;
|
||||
this.pad = Number.parseInt(opts.padding, 10);
|
||||
this.compiler = {
|
||||
compiler: {
|
||||
exe: this.executable,
|
||||
@@ -145,17 +153,7 @@ class CompilerArgsApp {
|
||||
}
|
||||
}
|
||||
|
||||
if (!opts.parser || !opts.exe) {
|
||||
console.error(
|
||||
'Usage: ' +
|
||||
'node --no-warnings=ExperimentalWarning --import=tsx compiler-args-app.ts ' +
|
||||
'--parser=<compilertype> --exe=<path> [--padding=<number>]\n' +
|
||||
'for example: --parser=clang --exe=/opt/compiler-explorer/clang-15.0.0/bin/clang++ --padding=50',
|
||||
);
|
||||
process.exit(1);
|
||||
} else {
|
||||
const app = new CompilerArgsApp();
|
||||
app.doTheParsing()
|
||||
.then(() => app.print())
|
||||
.catch(e => console.error(e));
|
||||
}
|
||||
const app = new CompilerArgsApp();
|
||||
app.doTheParsing()
|
||||
.then(() => app.print())
|
||||
.catch(e => console.error(e));
|
||||
|
||||
@@ -223,7 +223,7 @@ Note that path-style properties often support variable substitution as shown abo
|
||||
|
||||
### Property Debugging
|
||||
|
||||
You can enable detailed debugging of property resolution by using the `--propDebug` flag when starting Compiler
|
||||
You can enable detailed debugging of property resolution by using the `--prop-debug` flag when starting Compiler
|
||||
Explorer. This shows every property lookup, including where properties are being overridden and which configuration
|
||||
source they come from.
|
||||
|
||||
@@ -257,7 +257,7 @@ The configuration system is implemented primarily in the following files:
|
||||
If you need to troubleshoot configuration issues, you can run Compiler Explorer with debug output:
|
||||
|
||||
```
|
||||
make EXTRA_ARGS='--propDebug' dev
|
||||
make EXTRA_ARGS='--prop-debug' dev
|
||||
```
|
||||
|
||||
This will show detailed logs about property resolution, including which properties are being overridden and from which
|
||||
|
||||
@@ -4,7 +4,7 @@ Our frontend testing is done with cypress.
|
||||
|
||||
To run the tests locally:
|
||||
|
||||
- start a server with `npm run dev -- --language c++ --noLocal` - this configuration ensures your setup is clean of any
|
||||
- start a server with `npm run dev -- --language c++ --no-local` - this configuration ensures your setup is clean of any
|
||||
local properties.
|
||||
- in another terminal run `npx cypress open`, then choose "end to end" and then you should be able to run tests
|
||||
interactively.
|
||||
|
||||
@@ -29,7 +29,7 @@ export type AppArguments = {
|
||||
port: number;
|
||||
gitReleaseName: string;
|
||||
releaseBuildNumber: string;
|
||||
wantedLanguages: string[] | null;
|
||||
wantedLanguages: string[] | undefined;
|
||||
doCache: boolean;
|
||||
fetchCompilersFromRemote: boolean;
|
||||
ensureNoCompilerClash: boolean | undefined;
|
||||
|
||||
63
package-lock.json
generated
63
package-lock.json
generated
@@ -27,6 +27,7 @@
|
||||
"buffer": "^6.0.3",
|
||||
"chart.js": "^4.4.9",
|
||||
"clipboard": "^2.0.11",
|
||||
"commander": "^13.1.0",
|
||||
"compression": "^1.8.0",
|
||||
"copy-webpack-plugin": "^13.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
@@ -46,7 +47,6 @@
|
||||
"monaco-vim": "^0.4.2",
|
||||
"morgan": "^1.10.0",
|
||||
"node-targz": "^0.2.0",
|
||||
"nopt": "^8.1.0",
|
||||
"p-queue": "^8.1.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"profanities": "^3.0.1",
|
||||
@@ -87,7 +87,6 @@
|
||||
"@types/jquery": "^3.5.32",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/node-targz": "^0.2.4",
|
||||
"@types/nopt": "^3.0.32",
|
||||
"@types/request": "^2.48.12",
|
||||
"@types/response-time": "^2.3.8",
|
||||
"@types/serve-favicon": "^2.5.7",
|
||||
@@ -5233,13 +5232,6 @@
|
||||
"@types/tar-fs": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/nopt": {
|
||||
"version": "3.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/nopt/-/nopt-3.0.32.tgz",
|
||||
"integrity": "sha512-UP8QR0GaR8AE3l4wDmyCx4lEkX5o/1YVeDBqb1UqmfHefZqFNedQLTsobfzw56CvlXVVbt6kAwJJbN1yDTp16Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/pg": {
|
||||
"version": "8.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz",
|
||||
@@ -5843,15 +5835,6 @@
|
||||
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/abbrev": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz",
|
||||
"integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^18.17.0 || >=20.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
||||
@@ -6943,13 +6926,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
|
||||
"integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
|
||||
"dev": true,
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
|
||||
"integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/common-tags": {
|
||||
@@ -7534,6 +7516,16 @@
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/cypress/node_modules/commander": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
|
||||
"integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
@@ -9864,16 +9856,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/commander": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
|
||||
"integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/emoji-regex": {
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
|
||||
@@ -10899,21 +10881,6 @@
|
||||
"node": ">= 0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nopt": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz",
|
||||
"integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"abbrev": "^3.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"nopt": "bin/nopt.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || >=20.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"buffer": "^6.0.3",
|
||||
"chart.js": "^4.4.9",
|
||||
"clipboard": "^2.0.11",
|
||||
"commander": "^13.1.0",
|
||||
"compression": "^1.8.0",
|
||||
"copy-webpack-plugin": "^13.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
@@ -55,7 +56,6 @@
|
||||
"monaco-vim": "^0.4.2",
|
||||
"morgan": "^1.10.0",
|
||||
"node-targz": "^0.2.0",
|
||||
"nopt": "^8.1.0",
|
||||
"p-queue": "^8.1.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"profanities": "^3.0.1",
|
||||
@@ -96,7 +96,6 @@
|
||||
"@types/jquery": "^3.5.32",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/node-targz": "^0.2.4",
|
||||
"@types/nopt": "^3.0.32",
|
||||
"@types/request": "^2.48.12",
|
||||
"@types/response-time": "^2.3.8",
|
||||
"@types/serve-favicon": "^2.5.7",
|
||||
|
||||
Reference in New Issue
Block a user