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

fix(builtin): properly parse status file value containing spaces #2615

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
46 changes: 29 additions & 17 deletions internal/pkg_npm/packager.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,32 @@ function unquoteArgs(s) {
}

/**
* The status files are expected to look like
* BUILD_SCM_HASH 83c699db39cfd74526cdf9bebb75aa6f122908bb
* BUILD_SCM_LOCAL_CHANGES true
* STABLE_BUILD_SCM_VERSION 6.0.0-beta.6+12.sha-83c699d.with-local-changes
* BUILD_TIMESTAMP 1520021990506
*
* @param {string} p the path to the status file
* @returns a two-dimensional array of key/value pairs
*/
* The status files are expected to look like
* BUILD_SCM_HASH 83c699db39cfd74526cdf9bebb75aa6f122908bb
* BUILD_SCM_LOCAL_CHANGES true
* STABLE_BUILD_SCM_VERSION 6.0.0-beta.6+12.sha-83c699d.with-local-changes
* BUILD_TIMESTAMP 1520021990506
*
* Parsing regex is created based on Bazel's documentation describing the status file schema:
* The key names can be anything but they may only use upper case letters and underscores. The
* first space after the key name separates it from the value. The value is the rest of the line
* (including additional whitespaces).
*
* @param {string} p the path to the status file
* @returns a two-dimensional array of key/value pairs
*/
function parseStatusFile(p) {
if (!p) return [];
return fs.readFileSync(p, {encoding: 'utf-8'})
.split('\n')
.filter(t => !!t)
.map(t => t.split(' '));
const results = {};
const statusFile = fs.readFileSync(p, {encoding: 'utf-8'});
for (const match of `\n${statusFile}`.matchAll(/^([A-Z_]+) (.*)/gm)) {
// Lines which go unmatched define an index value of `0` and should be skipped.
if (match.index === 0) {
continue;
}
results[match[1]] = match[2];
}
return results;
}

function main(args) {
Expand All @@ -95,15 +106,16 @@ function main(args) {
// Replace statuses last so that earlier substitutions can add
// status-related placeholders
if (volatileFile || infoFile) {
const statusEntries = parseStatusFile(volatileFile)
statusEntries.push(...parseStatusFile(infoFile))
const statuses = {
...parseStatusFile(volatileFile),
...parseStatusFile(infoFile),
};
// Looks like {'BUILD_SCM_VERSION': 'v1.2.3'}
const statuses = new Map(statusEntries)
for (let idx = 0; idx < substitutions.length; idx++) {
const match = substitutions[idx][1].match(/\{(.*)\}/);
if (!match) continue;
const statusKey = match[1];
let statusValue = statuses.get(statusKey);
let statusValue = statuses[statusKey];
if (statusValue) {
// npm versions must be numeric, so if the VCS tag starts with leading 'v', strip it
// See https://github.com/bazelbuild/rules_nodejs/pull/1591
Expand Down
38 changes: 28 additions & 10 deletions internal/pkg_web/assembler.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,33 @@ function unquoteArgs(s) {
return s.replace(/^'(.*)'$/, '$1');
}

function getBazelStatusMappings(statusFilePath) {
if (!statusFilePath) return {};
const stampFileLines = fs.readFileSync(statusFilePath, {encoding: 'utf-8'}).trim().split('\n');
const stampMap = {};
for (const line of stampFileLines) {
const [key, value] = line.split(' ');
stampMap[key] = value;
/**
* The status files are expected to look like
* BUILD_SCM_HASH 83c699db39cfd74526cdf9bebb75aa6f122908bb
* BUILD_SCM_LOCAL_CHANGES true
* STABLE_BUILD_SCM_VERSION 6.0.0-beta.6+12.sha-83c699d.with-local-changes
* BUILD_TIMESTAMP 1520021990506
*
* Parsing regex is created based on Bazel's documentation describing the status file schema:
* The key names can be anything but they may only use upper case letters and underscores. The
* first space after the key name separates it from the value. The value is the rest of the line
* (including additional whitespaces).
*
* @param {string} p the path to the status file
* @returns a two-dimensional array of key/value pairs
*/
function parseStatusFile(p) {
if (!p) return [];
const results = {};
const statusFile = fs.readFileSync(p, {encoding: 'utf-8'});
for (const match of `\n${statusFile}`.matchAll(/^([A-Z_]+) (.*)/gm)) {
// Lines which go unmatched define an index value of `0` and should be skipped.
if (match.index === 0) {
continue;
}
results[match[1]] = match[2];
}
return stampMap;
return results;
}

function normalizeSubstitutions(substitutionsArg, stampMap) {
Expand Down Expand Up @@ -74,8 +92,8 @@ function main(params) {
const rawSubstitutions = params.shift().replace(/^'(.*)'$/, '$1');

const stampMap = {
...getBazelStatusMappings(volatileFilePath),
...getBazelStatusMappings(stableFilePath),
...parseStatusFile(volatileFilePath),
...parseStatusFile(stableFilePath),
};

const normalizedSubstitutions = normalizeSubstitutions(rawSubstitutions, stampMap)
Expand Down
42 changes: 35 additions & 7 deletions packages/rollup/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,43 @@ To use these files, you write JS code in your `rollup.config.js` to read from th
Each line is a space-separated key/value pair.

```javascript
/**
* The status files are expected to look like
* BUILD_SCM_HASH 83c699db39cfd74526cdf9bebb75aa6f122908bb
* BUILD_SCM_LOCAL_CHANGES true
* STABLE_BUILD_SCM_VERSION 6.0.0-beta.6+12.sha-83c699d.with-local-changes
* BUILD_TIMESTAMP 1520021990506
*
* Parsing regex is created based on Bazel's documentation describing the status file schema:
* The key names can be anything but they may only use upper case letters and underscores. The
* first space after the key name separates it from the value. The value is the rest of the line
* (including additional whitespaces).
*
* @param {string} p the path to the status file
* @returns a two-dimensional array of key/value pairs
*/
function parseStatusFile(p) {
if (!p) return [];
const results = {};
const statusFile = require('fs').readFileSync(p, {encoding: 'utf-8'});
for (const match of `\n${statusFile}`.matchAll(/^([A-Z_]+) (.*)/gm)) {
// Lines which go unmatched define an index value of `0` and should be skipped.
if (match.index === 0) {
continue;
}
results[match[1]] = match[2];
}
return results;
}

const statuses = parseStatusFile(bazel_version_file);
// Parse the stamp file produced by Bazel from the version control system
let version = '<unknown>';
if (bazel_info_file) {
const versionTag = require('fs')
.readFileSync(bazel_info_file, {encoding: 'utf-8'})
.split('\n')
.find(s => s.startsWith('STABLE_GIT_COMMIT'));
if (versionTag) {
version = 'v' + versionTag.split(' ')[1].trim();
// Don't assume BUILD_SCM_VERSION exists
if (statuses['BUILD_SCM_VERSION']) {
version = 'v' + statuses['BUILD_SCM_VERSION'];
if (DEBUG) {
version += '_debug';
}
}
```
Expand Down
44 changes: 36 additions & 8 deletions packages/rollup/test/integration/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,44 @@ import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import nodeResolve from '@rollup/plugin-node-resolve';

/**
* The status files are expected to look like
* BUILD_SCM_HASH 83c699db39cfd74526cdf9bebb75aa6f122908bb
* BUILD_SCM_LOCAL_CHANGES true
* STABLE_BUILD_SCM_VERSION 6.0.0-beta.6+12.sha-83c699d.with-local-changes
* BUILD_TIMESTAMP 1520021990506
*
* Parsing regex is created based on Bazel's documentation describing the status file schema:
* The key names can be anything but they may only use upper case letters and underscores. The
* first space after the key name separates it from the value. The value is the rest of the line
* (including additional whitespaces).
*
* @param {string} p the path to the status file
* @returns a two-dimensional array of key/value pairs
*/
function parseStatusFile(p) {
if (!p) return [];
const results = {};
const statusFile = require('fs').readFileSync(p, {encoding: 'utf-8'});
for (const match of `\n${statusFile}`.matchAll(/^([A-Z_]+) (.*)/gm)) {
// Lines which go unmatched define an index value of `0` and should be skipped.
if (match.index === 0) {
continue;
}
results[match[1]] = match[2];
}
return results;
}

// Parse the stamp file produced by Bazel from the version control system
let version = '<unknown>';
if (bazel_version_file) {
const versionTag = require('fs')
.readFileSync(bazel_version_file, {encoding: 'utf-8'})
.split('\n')
.find(s => s.startsWith('BUILD_SCM_VERSION'));
// Don't assume BUILD_SCM_VERSION exists
if (versionTag) {
version = 'v' + versionTag.split(' ')[1].trim();

const statuses = parseStatusFile(bazel_version_file);
// Don't assume BUILD_SCM_VERSION exists
if (statuses['BUILD_SCM_VERSION']) {
version = 'v' + statuses['BUILD_SCM_VERSION'];
if (DEBUG) {
version += '_debug';
}
}

Expand Down
47 changes: 36 additions & 11 deletions packages/rollup/test/version_stamp/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
/**
* The status files are expected to look like
* BUILD_SCM_HASH 83c699db39cfd74526cdf9bebb75aa6f122908bb
* BUILD_SCM_LOCAL_CHANGES true
* STABLE_BUILD_SCM_VERSION 6.0.0-beta.6+12.sha-83c699d.with-local-changes
* BUILD_TIMESTAMP 1520021990506
*
* Parsing regex is created based on Bazel's documentation describing the status file schema:
* The key names can be anything but they may only use upper case letters and underscores. The
* first space after the key name separates it from the value. The value is the rest of the line
* (including additional whitespaces).
*
* @param {string} p the path to the status file
* @returns a two-dimensional array of key/value pairs
*/
function parseStatusFile(p) {
if (!p) return [];
const results = {};
const statusFile = require('fs').readFileSync(p, {encoding: 'utf-8'});
for (const match of `\n${statusFile}`.matchAll(/^([A-Z_]+) (.*)/gm)) {
// Lines which go unmatched define an index value of `0` and should be skipped.
if (match.index === 0) {
continue;
}
results[match[1]] = match[2];
}
return results;
}

const DEBUG = process.env['COMPILATION_MODE'] === 'dbg';

// Parse the stamp file produced by Bazel from the version control system
let version = '<unknown>';
if (bazel_version_file) {
const versionTag = require('fs')
.readFileSync(bazel_version_file, {encoding: 'utf-8'})
.split('\n')
.find(s => s.startsWith('BUILD_SCM_VERSION'));
// Don't assume BUILD_SCM_VERSION exists
if (versionTag) {
version = 'v' + versionTag.split(' ')[1].trim();
if (DEBUG) {
version += '_debug';
}

const statuses = parseStatusFile(bazel_version_file);
// Don't assume BUILD_SCM_VERSION exists
if (statuses['BUILD_SCM_VERSION']) {
version = 'v' + statuses['BUILD_SCM_VERSION'];
if (DEBUG) {
version += '_debug';
}
}

Expand Down