Skip to content

Commit

Permalink
build: include dist folder in published packages
Browse files Browse the repository at this point in the history
  • Loading branch information
Planeshifter committed Aug 12, 2023
1 parent 93c16b7 commit 8bbf2c5
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 70 deletions.
59 changes: 20 additions & 39 deletions lib/node_modules/@stdlib/_tools/scripts/publish_packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -1098,24 +1098,6 @@ function publish( pkg, clbk ) {
'cwd': dist
};

// Transform error messages:
jscodeshift = join( rootDir(), 'node_modules', '.bin', 'jscodeshift' );
command = 'STDLIB_PKG=\'@stdlib/'+distPkg+'\' '+jscodeshift+' ./lib/**/*.js ./lib/*.js -t '+join( __dirname, 'transform_error_messages.js' );
debug( 'Executing command: %s', command );
shell( command, opts );

// Format rewritten error messages:
command = 'find . -name "*.js" -exec sed -E -i "s/Error\\( format\\( \\"([a-zA-Z0-9]+)\\"/Error\\( format\\( \'\\1\'/g" {} \\;';
shell( command, opts );

// Format string literal error messages:
command = 'find . -name "*.js" -exec sed -E -i "s/Error\\( format\\(\\"([a-zA-Z0-9]+)\\"/Error\\( format\\( \'\\1\'/g" {} \\;';
shell( command, opts );

// Format code by replacing double quotes with single quotes in inserted `require` calls:
command = 'find . -name "*.js" -exec sed -E -i "s/require\\( ?\\"@stdlib\\/error-tools-fmtprodmsg\\" ?\\);/require\\( \'@stdlib\\/error-tools-fmtprodmsg\' \\);/g" {} \\;';
shell( command, opts );

command = 'rm -f docs/repl.txt && rm -f docs/types/test.ts';
shell( command, opts );
if ( hasCLI ) {
Expand Down Expand Up @@ -1180,36 +1162,35 @@ function publish( pkg, clbk ) {
}
}
}
// Transform error messages and save files to `dist` subdirectory:
command = 'cp -r lib dist';
shell( command, opts );
jscodeshift = join( rootDir(), 'node_modules', '.bin', 'jscodeshift' );
command = 'STDLIB_PKG=\'@stdlib/'+distPkg+'\' '+jscodeshift+' ./dist/**/*.js ./dist/*.js -t '+join( __dirname, 'transform.js' );
debug( 'Executing command: %s', command );
shell( command, opts );
command = 'find ./dist -name "*.js" -exec sed -E -i "1i\\/\\*\\* \\@license '+pkgJSON.license+' \\*\\/\n" {} \\;';
shell( command, opts );

// Change `@stdlib/string-format` to `@stdlib/error-tools-fmtprodmsg` in package.json:
// Add `@stdlib/error-tools-fmtprodmsg` in package.json if the package depends on `@stdlib/string-format`:
if ( pkgJSON.dependencies[ '@stdlib/string-format' ] ) {
delete pkgJSON.dependencies[ '@stdlib/string-format' ];
fmtProdMsgVersion = npmVersion( '@stdlib/error-tools-fmtprodmsg' );
pkgJSON.dependencies[ '@stdlib/error-tools-fmtprodmsg' ] = fmtProdMsgVersion;
}
fmtProdMsgVersion = npmVersion( '@stdlib/error-tools-fmtprodmsg' );
pkgJSON.dependencies[ '@stdlib/error-tools-fmtprodmsg' ] = fmtProdMsgVersion;

// Replace LICENSE comments with abbreviated ones:
if ( hasCLI ) {
command = 'find '+dist+' -name "*.js" -type f';
} else {
command = 'find '+dist+' -name "bin/cli" -type f';
}
command += ' -exec perl -i -p0e \'s|/\\*\\*\\n\\*\\s\\@license\\sApache-2.0\\n\\*\\n\\*\\sCopyright\\s\\(c\\)\\s\\d{4}\\sThe\\sStdlib\\sAuthors\\.\\n(.*?)\\n\\*\\slimitations\\sunder\\sthe\\sLicense\\.\\n\\*/|// Copyright (c) '+CURRENT_YEAR+' The Stdlib Authors. License is Apache-2.0: http://www.apache.org/licenses/LICENSE-2.0|s\' {} \\;';
shell( command );

// Replace GitHub MathJax equations with SVGs:
command = 'find '+dist+' -type f -name \'*.md\' -print0 | xargs -0 perl -0777 -i -pe \'s/```math\\n([\\s\\S]+?)\\n```\\n\\n//g\'';
shell( command );
command = 'find '+dist+' -type f -name \'*.md\' -print0 | xargs -0 perl -0777 -i -pe \'s/<!-- <div class="equation"(.*)(<\\/div>\\s*-->)/<div class="equation"$1<\\/div>/sg\'';
shell( command );
command = 'find . -type f -name \'*.md\' -print0 | xargs -0 perl -0777 -i -pe \'s/```math\\n([\\s\\S]+?)\\n```\\n\\n//g\'';
shell( command, opts );
command = 'find . -type f -name \'*.md\' -print0 | xargs -0 perl -0777 -i -pe \'s/<!-- <div class="equation"(.*)(<\\/div>\\s*-->)/<div class="equation"$1<\\/div>/sg\'';
shell( command, opts );

// Replace GitHub links to individual packages with npm links:
command = 'find '+dist+' -type f -name \'*.md\' -print0 | xargs -0 sed -Ei \'/tree\\/main/b; s/@stdlib\\/([^:]*)\\]: https:\\/\\/github.com\\/stdlib-js/@stdlib\\/\\1\\]: https:\\/\\/www.npmjs.com\\/package\\/@stdlib/g\'';
shell( command );
command = 'find . -type f -name \'*.md\' -print0 | xargs -0 sed -Ei \'/tree\\/main/b; s/@stdlib\\/([^:]*)\\]: https:\\/\\/github.com\\/stdlib-js/@stdlib\\/\\1\\]: https:\\/\\/www.npmjs.com\\/package\\/@stdlib/g\'';
shell( command, opts );

// Replace list with links to other branches from installation section:
command = 'find '+dist+' -type f -name \'*.md\' -print0 | xargs -0 perl -0777 -i -pe "s/\\`\\`\\`\n\nAlternatively,[^<]+<\\/section>/\\`\\`\\`\n\n<\\/section>/"';
shell( command );
command = 'find . -type f -name \'*.md\' -print0 | xargs -0 perl -0777 -i -pe "s/\\`\\`\\`\n\nAlternatively,[^<]+<\\/section>/\\`\\`\\`\n\n<\\/section>/"';
shell( command, opts );

writeFileSync( pkgJsonPath, JSON.stringify( pkgJSON, null, ' ' ).concat( '\n' ) );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@
// MODULES //

var logger = require( 'debug' );
var startsWith = require('@stdlib/string/starts-with');
var replace = require( '@stdlib/string/replace' );
var pkg2id = require( '@stdlib/error/tools/pkg2id' );
var msg2id = require( '@stdlib/error/tools/msg2id');
var ENV = require( '@stdlib/process/env' );


// VARIABLES //

var debug = logger( 'scripts:transform-error-messages' );
var debug = logger( 'scripts:transform' );
var pkg = ENV[ 'STDLIB_PKG' ];
var prefix = pkg2id( pkg );
var RE_EMPTY_LINE = /(\r?\n){2,}/g;
var ERROR_NAMES = [
'Error',
'AssertionError',
Expand All @@ -45,7 +48,7 @@ var ERROR_NAMES = [
// MAIN //

/**
* Transforms a file.
* Transforms a file for a production build.
*
* ## Notes
*
Expand All @@ -64,68 +67,122 @@ function transformer( fileInfo, api ) {
var requires;
var code;
var root;
var out;
var id;
var j;

j = api.jscodeshift;
root = j( fileInfo.source );

root.find(j.Program).forEach( onProgram );

requires = root.find( j.CallExpression, {
'callee': {
'name': 'require',
'type': 'Identifier'
}
});

debug( 'Transforming file: %s', fileInfo.path );
return root

root
.find( j.Literal )
.forEach( onStringLiteral )
.toSource();
.forEach( onStringLiteral );

requires.forEach( rewriteRequire );

root
.find(j.Node)
.forEach( deleteComment );

out = root.toSource({
'quote': 'single',
'lineTerminator': '\n',
'reuseWhitespace': false,
'useTabs': true
});

return replace( out, RE_EMPTY_LINE, '\n' );

/**
* Removes comments from the program.
*
* @private
* @param {Object} path - AST node path
* @returns {void}
*/
function onProgram( path ) {
path.node.comments = [];
}

/**
* Deletes the comments associated with a given node.
*
* @private
* @param {Object} path - AST node path
* @returns {void}
*/
function deleteComment( path ) {
delete path.node.comments;
}

/**
* Rewrites a `require` statement to include the `/dist` directory if the module being required starts with `@stdlib`.
*
* @private
* @param {Object} path - AST node path
* @returns {void}
*/
function rewriteRequire( path ) {
if ( startsWith( path.value.arguments[0].value, '@stdlib' ) ) {
path.value.arguments[0].value += '/dist';
}
}

/**
* Callback invoked upon finding a string literal.
*
* @private
* @param {Object} node - AST node
* @param {Object} path - AST node path
* @returns {void}
*/
function onStringLiteral( node ) {
if ( node.value.value === '@stdlib/string-format' ) {
function onStringLiteral( path ) {
if ( path.value.value === '@stdlib/string-format' ) {
debug( 'Replacing `@stdlib/string-format` with `@stdlib/error-tools-fmtprodmsg`...' );
j( node )
j( path )
.replaceWith( j.stringLiteral( '@stdlib/error-tools-fmtprodmsg' ) );
}
// If the string literal is inside a NewExpression for an error, replace the string literal with the error message...
else if (
// Case: new Error( format( '...', ... ) )
( node.parent.parent.value.type === 'NewExpression' &&
ERROR_NAMES.includes( node.parent.parent.value.callee.name ) )
( path.parent.parent.value.type === 'NewExpression' &&
ERROR_NAMES.includes( path.parent.parent.value.callee.name ) )
) {
id = msg2id( node.value.value );
id = msg2id( path.value.value );
if ( id ) {
code = prefix + id;
debug( 'Replacing format string "'+node.value.value+'" with error code "'+code+'"...' );
j( node )
debug( 'Replacing format string "'+path.value.value+'" with error code "'+code+'"...' );
j( path )
.replaceWith( j.stringLiteral( code ) );
}
}
else if (
// Case: new Error( '...' )
( node.parent.value.type === 'NewExpression' &&
ERROR_NAMES.includes( node.parent.value.callee.name ) )
( path.parent.value.type === 'NewExpression' &&
ERROR_NAMES.includes( path.parent.value.callee.name ) )
) {
id = msg2id( node.value.value );
id = msg2id( path.value.value );
if ( id ) {
code = prefix + id;
debug( 'Replacing string literal "'+node.value.value+'" with error code "'+code+'"...' );
debug( 'Replacing string literal "'+path.value.value+'" with error code "'+code+'"...' );

// Replace with call to `format` with the error code...
replacement = j.callExpression(j.identifier( 'format' ), [
j.stringLiteral( code )
]);
j( node ).replaceWith( replacement );
j( path ).replaceWith( replacement );

// Add `require` call to `@stdlib/error-tools-fmtprodmsg` if not already present...
requires = root.find( j.CallExpression, {
'callee': {
'name': 'require',
'type': 'Identifier'
}
});
nRequires = requires.size();
debug( 'Found ' + nRequires + ' `require` calls...' );
if ( !requires.some( hasRequire ) ) {
Expand All @@ -142,15 +199,15 @@ function transformer( fileInfo, api ) {
}

/**
* Tests whether a node is a require call for `@stdlib/error-tools-fmtprodmsg`.
* Tests whether a path is a require call for `@stdlib/error-tools-fmtprodmsg`.
*
* @private
* @param {Object} node - node to test
* @returns {boolean} boolean indicating whether a node is a require call for `@stdlib/error-tools-fmtprodmsg`
* @param {Object} path - AST node path
* @returns {boolean} boolean indicating whether a path is a require call for `@stdlib/error-tools-fmtprodmsg`
*/
function hasRequire( node ) {
return node.value.callee.name === 'require' &&
node.value.arguments[ 0 ].value === '@stdlib/error-tools-fmtprodmsg';
function hasRequire( path ) {
return path.value.callee.name === 'require' &&
path.value.arguments[ 0 ].value === '@stdlib/error-tools-fmtprodmsg';
}
}

Expand Down

0 comments on commit 8bbf2c5

Please sign in to comment.