mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-11 14:14:36 +08:00
This checks in the InspectorBackendCommands in the source tree file and ensures that it is kept in sync whenever the third_party location has been updated. In the process, I discovered multiple misconfigurations in the formatting presubmit check. First of all, it was never running, because the .eslintignore had an empty line. Second of all, it was running twice, which is unnecessary since we now check for changed files at the end of the presubmit. Lastly, it was only formatting JS files, while it should check all files. I have also updated the _CheckGeneratedFiles check to only run if it is actually necessary. If there are no changes made to any affected of the files, it will skip the step. This should thus reduce the presubmit time and we will only pay the cost if we actually update any of the files. Lastly, it will now properly format and lint the generated files. This makes reading the code a lot easier and makes it easier to digest the diff when a protocol update goes through. I have verified that, in a full build, the files are still minified. Thus, this has no impact on the loading performance. DISABLE_THIRD_PARTY_CHECK=Updating protocol generation Fixed: 1056614 Change-Id: If49b0e749978ea1a7838992ec13507ee761ad76c Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2087765 Reviewed-by: Paul Lewis <aerotwist@chromium.org> Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org>
189 lines
6.5 KiB
JavaScript
189 lines
6.5 KiB
JavaScript
// Copyright (c) 2016 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
var fs = require('fs');
|
|
var http = require('http');
|
|
var path = require('path');
|
|
var parseURL = require('url').parse;
|
|
|
|
var utils = require('../utils');
|
|
|
|
const remoteDebuggingPort = parseInt(process.env.REMOTE_DEBUGGING_PORT, 10) || 9222;
|
|
const serverPort = parseInt(process.env.PORT, 10) || 8090;
|
|
const devtoolsFolder = path.resolve(path.join(__dirname, '../..'));
|
|
|
|
http.createServer(requestHandler).listen(serverPort);
|
|
console.log(`Started hosted mode server at http://localhost:${serverPort}\n`);
|
|
console.log('For info on using the hosted mode server, see our contributing docs:');
|
|
console.log('https://bit.ly/devtools-contribution-guide');
|
|
console.log('Tip: Look for the \'Development server options\' section\n');
|
|
|
|
function requestHandler(request, response) {
|
|
var filePath = parseURL(request.url).pathname;
|
|
if (filePath === '/') {
|
|
var landingURL = `http://localhost:${remoteDebuggingPort}#custom=true`;
|
|
sendResponse(200, `<html>Please go to <a href="${landingURL}">${landingURL}</a></html>`);
|
|
return;
|
|
}
|
|
|
|
var proxiedFile = proxy(filePath, sendResponse);
|
|
if (proxiedFile) {
|
|
proxiedFile.then(data => sendResponse(200, data)).catch(handleProxyError);
|
|
return;
|
|
}
|
|
|
|
function handleProxyError(err) {
|
|
console.log(`Error serving the file ${filePath}:`, err);
|
|
console.log(`Make sure you opened Chrome with the flag "--remote-debugging-port=${remoteDebuggingPort}"`);
|
|
sendResponse(500, '500 - Internal Server Error');
|
|
}
|
|
|
|
var absoluteFilePath = path.join(devtoolsFolder, filePath);
|
|
if (!path.resolve(absoluteFilePath).startsWith(devtoolsFolder)) {
|
|
console.log(`File requested (${absoluteFilePath}) is outside of devtools folder: ${devtoolsFolder}`);
|
|
sendResponse(403, `403 - Access denied. File requested is outside of devtools folder: ${devtoolsFolder}`);
|
|
return;
|
|
}
|
|
|
|
fs.exists(absoluteFilePath, fsExistsCallback);
|
|
|
|
function fsExistsCallback(fileExists) {
|
|
if (!fileExists) {
|
|
console.log(`Cannot find file ${absoluteFilePath}`);
|
|
sendResponse(404, '404 - File not found');
|
|
return;
|
|
}
|
|
|
|
let encoding = 'utf8';
|
|
if (absoluteFilePath.endsWith('.png') || absoluteFilePath.endsWith('.jpg')) {
|
|
encoding = 'binary';
|
|
}
|
|
|
|
fs.readFile(absoluteFilePath, encoding, readFileCallback);
|
|
}
|
|
|
|
function readFileCallback(err, file) {
|
|
if (err) {
|
|
console.log(`Unable to read local file ${absoluteFilePath}:`, err);
|
|
sendResponse(500, '500 - Internal Server Error');
|
|
return;
|
|
}
|
|
sendResponse(200, file);
|
|
}
|
|
|
|
function sendResponse(statusCode, data) {
|
|
const path = parseURL(request.url).pathname;
|
|
|
|
if (path.endsWith('.rawresponse')) {
|
|
sendRawResponse(data);
|
|
return;
|
|
}
|
|
|
|
let encoding = 'utf8';
|
|
if (path.endsWith('.js')) {
|
|
response.setHeader('Content-Type', 'text/javascript; charset=utf-8');
|
|
} else if (path.endsWith('.css')) {
|
|
response.setHeader('Content-Type', 'text/css; charset=utf-8');
|
|
} else if (path.endsWith('.wasm')) {
|
|
response.setHeader('Content-Type', 'application/wasm');
|
|
encoding = 'binary'
|
|
} else if (path.endsWith('.svg')) {
|
|
response.setHeader('Content-Type', 'image/svg+xml; charset=utf-8');
|
|
} else if (path.endsWith('.png')) {
|
|
response.setHeader('Content-Type', 'image/png');
|
|
encoding = 'binary';
|
|
} else if (path.endsWith('.jpg')) {
|
|
response.setHeader('Content-Type', 'image/jpg');
|
|
encoding = 'binary';
|
|
}
|
|
|
|
response.writeHead(statusCode);
|
|
response.write(data, encoding);
|
|
response.end();
|
|
}
|
|
|
|
function sendRawResponse(data) {
|
|
const lines = data.split('\n');
|
|
|
|
let isHeader = true;
|
|
let line = lines.shift();
|
|
const statusCode = parseInt(line);
|
|
|
|
while ((line = lines.shift()) !== undefined) {
|
|
if (line.trim() === '') {
|
|
isHeader = false;
|
|
if (request.headers['if-none-match'] && response.getHeader('ETag') === request.headers['if-none-match']) {
|
|
response.writeHead(304);
|
|
response.end();
|
|
return;
|
|
}
|
|
response.writeHead(statusCode);
|
|
continue;
|
|
}
|
|
|
|
if (isHeader) {
|
|
const firstColon = line.indexOf(':');
|
|
response.setHeader(line.substring(0, firstColon), line.substring(firstColon + 1).trim());
|
|
} else {
|
|
response.write(line);
|
|
}
|
|
}
|
|
|
|
response.end();
|
|
}
|
|
}
|
|
|
|
var proxyFilePathToURL = {
|
|
'/favicon.ico': () => 'https://chrome-devtools-frontend.appspot.com/favicon.ico',
|
|
};
|
|
|
|
var proxyFileCache = new Map();
|
|
|
|
function proxy(filePath) {
|
|
if (!(filePath in proxyFilePathToURL))
|
|
return null;
|
|
if (process.env.CHROMIUM_COMMIT)
|
|
return onProxyFileURL(proxyFilePathToURL[filePath](process.env.CHROMIUM_COMMIT));
|
|
return utils.fetch(`http://localhost:${remoteDebuggingPort}/json/version`)
|
|
.then(onBrowserMetadata)
|
|
.then(onProxyFileURL);
|
|
|
|
function onBrowserMetadata(metadata) {
|
|
var metadataObject = JSON.parse(metadata);
|
|
var match = metadataObject['WebKit-Version'].match(/\s\(@(\b[0-9a-f]{5,40}\b)/);
|
|
var commitHash = match[1];
|
|
var proxyFileURL = proxyFilePathToURL[filePath](commitHash);
|
|
return proxyFileURL;
|
|
}
|
|
|
|
function onProxyFileURL(proxyFileURL) {
|
|
if (proxyFileCache.has(proxyFileURL))
|
|
return Promise.resolve(proxyFileCache.get(proxyFileURL));
|
|
return utils.fetch(proxyFileURL).then(cacheProxyFile.bind(null, proxyFileURL)).catch(onMissingFile);
|
|
}
|
|
|
|
function onMissingFile() {
|
|
var isFullCheckout = utils.shellOutput('git config --get remote.origin.url') ===
|
|
'https://chromium.googlesource.com/chromium/src.git';
|
|
var earlierCommitHash;
|
|
var gitLogCommand = `git log --max-count=1 --grep="Commit-Position" --before="12 hours ago"`;
|
|
if (isFullCheckout) {
|
|
earlierCommitHash = utils.shellOutput(`${gitLogCommand} --pretty=format:"%H"`);
|
|
} else {
|
|
var commitMessage = utils.shellOutput(`${gitLogCommand}`);
|
|
earlierCommitHash = commitMessage.match(/Cr-Mirrored-Commit: (.*)/)[1];
|
|
}
|
|
var fallbackURL = proxyFilePathToURL[filePath](earlierCommitHash);
|
|
console.log('WARNING: Unable to fetch generated file based on browser\'s revision');
|
|
console.log('Fetching earlier revision of same file as fallback');
|
|
console.log('There may be a mismatch between the front-end and back-end');
|
|
console.log(fallbackURL, '\n');
|
|
return utils.fetch(fallbackURL).then(cacheProxyFile.bind(null, fallbackURL));
|
|
}
|
|
|
|
function cacheProxyFile(proxyFileURL, data) {
|
|
proxyFileCache.set(proxyFileURL, data);
|
|
return data;
|
|
}
|
|
}
|