Skip to content

Commit 5314d26

Browse files
author
betzrhodes
authored
Merge pull request #64 from nobitlost/master
v2.8.0
2 parents dd5f5e1 + bc0fff5 commit 5314d26

File tree

5 files changed

+128
-40
lines changed

5 files changed

+128
-40
lines changed

Diff for: README.md

+40-25
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
_Builder_ combines a preprocessor with an expression language and advanced imports.
44

5-
**Current version: 2.7.0**
5+
**Current version: 2.8.0**
66

77
![Build Status](https://cse-ci.electricimp.com/app/rest/builds/buildType:(id:Builder_BuildAndTest)/statusIcon)
88

@@ -54,6 +54,7 @@ _Builder_ combines a preprocessor with an expression language and advanced impor
5454
- [Remote Includes](#remote-includes)
5555
- [Caching Remote Includes](#caching-remote-includes)
5656
- [Proxy Access To Remote Includes](#proxy-access-to-remote-includes)
57+
- [Local Includes From Remote Files](#local-includes-from-remote-files)
5758
- [Testing](#testing)
5859
- [License](#license)
5960

@@ -458,15 +459,15 @@ The following types are supported in expressions:
458459
Variables can be used in `Builder` expression evaluation.
459460

460461
- Variables can be defined by:
461-
- The `-D <variable name> <variable value>` command line parameter.
462+
- The `-D<variable name> <variable value>` command line parameter.
462463
- A <code><b>@set</b></code> statement.
463464
- An [environment variable](#environment-variables).
464465
- Undefined variables are evaluated as `null`.
465466
- Variable names can contain `$`, `_`, latin letters and digits. They must not start with a digit.
466467

467468
#### Variable Definition Order ####
468469

469-
1. When resolving a variable’s value, *Builder* first looks for its definition in the command line `-D` parameters (`-D <variable name> <variable value>`) passed to the *pleasebuild* command.
470+
1. When resolving a variable’s value, *Builder* first looks for its definition in the command line `-D` parameters (`-D<variable name> <variable value>`) passed to the *pleasebuild* command.
470471
1. If no such variable definition is found, Squirrel code is scanned for `@set` statements preceding the variable usage.
471472
1. If no variable definitions are found in the previous steps, *Builder* looks in the host environment variables.
472473

@@ -592,9 +593,10 @@ npm install -g Builder
592593
then use the `pleasebuild` command which is provided by Builder:
593594

594595
```
595-
pleasebuild [-l] [-D <variable> <value>]
596+
pleasebuild [-l] [-D<variable> <value>]
596597
[--github-user <username> --github-token <token>]
597-
[--lib <path_to_file>] [--suppress-duplicate-includes-warning]
598+
[--lib <path_to_file>]
599+
[--use-remote-relative-includes] [--suppress-duplicate-includes-warning]
598600
[--cache] [--clear-cache] [--cache-exclude-list <path_to_file>]
599601
[--save-dependencies [<path_to_file>]] [--use-dependencies [<path_to_file>]]
600602
[--save-directives [<path_to_file>]] [--use-directives [<path_to_file>]]
@@ -610,10 +612,11 @@ and the options are:
610612
| Option | Synonym | Mandatory? | Value&nbsp;Required? | Description |
611613
| --- | --- | --- | --- | --- |
612614
| -l | | No | No | Generates line control statements. For a more detailed explanation, please read [this GCC page](https://gcc.gnu.org/onlinedocs/gcc-4.5.4/cpp/Line-Control.html) |
613-
| -D &lt;variable&gt; | | No | Yes | Defines a [variable](#variables). May be specified several times to define multiple variables |
615+
| -D&lt;variable&gt; | | No | Yes | Defines a [variable](#variables). May be specified several times to define multiple variables |
614616
| --github-user | | No | Yes | A GitHub username. See [‘Files From GitHub’](#files-from-github) |
615617
| --github-token | | No | Yes | A GitHub [personal access token](https://github.com/settings/tokens) or password (not recommended). Should be specified if the `--github-user` option is specified. See [‘Files From GitHub’](#files-from-github) |
616618
| --lib | --libs | No | Yes | Include the specified [JavaScript file(s) as a library](#including-javascript-libraries). May be specified several times to include multiple libraries. The provided value may specify a concrete file or a directory (all files from the directory will be included). The value may contain [wildcards](https://www.npmjs.com/package/glob) (all matched files will be included) |
619+
| --use-remote-relative-includes | | No | No | Interpret every [local include](#local-files) as relative to the location of the source file where it is mentioned. See ['Local Includes From Remote Files'](#local-includes-from-remote-files) |
617620
| --suppress-duplicate-includes-warning | --suppress-duplicate | No | No | Do not show a warning if a source file with the same content was included multiple times from different locations and this results in code duplication |
618621
| --cache | -c | No | No | Turn on caching for all files included from remote resources. This option is ignored if the `--save-dependencies` or `--use-dependencies` options are specified. See [‘Caching Remote Includes’](#caching-remote-includes) |
619622
| --clear-cache | | No | No | Clear the cache before Builder starts running. See [‘Caching Remote Includes’](#caching-remote-includes) |
@@ -637,32 +640,36 @@ then instantiate, setup and execute Builder from the source code, for example:
637640
const Builder = require('Builder');
638641
const builder = new Builder();
639642

640-
// Specify whether you need line control statements. See the "-l" CLI option
643+
// Specify whether you need line control statements. See the "-l" CLI option.
641644
builder.machine.generateLineControlStatements = <true|false>;
642645

643-
// Cache all files included from remote sources. See the "--cache" CLI option
646+
// Cache all files included from remote sources. See the "--cache" CLI option.
644647
builder.machine.useCache = <true|false>;
645648

646-
// Set GitHub credentials. See the "--github-user" and "--github-token" CLI options
649+
// Set GitHub credentials. See the "--github-user" and "--github-token" CLI options.
647650
builder.machine.readers.github.username = "<USERNAME>";
648651
builder.machine.readers.github.token = "<PASSWORD_OR_ACCESS_TOKEN>";
649652

650653
// Path to the file that lists the resources which should be excluded from caching.
651-
// See the "--cache-exclude-list" CLI option
654+
// See the "--cache-exclude-list" CLI option.
652655
builder.machine.excludeList = "<PATH_TO_FILE>";
653656

657+
// Replace local include paths to github URLs if requested.
658+
// See the "--use-remote-relative-includes" CLI option.
659+
builder.machine.remoteRelativeIncludes = <true|false>;
660+
654661
// Suppress warning about duplicate includes.
655-
// See the "--suppress-duplicate-includes-warning" CLI option
662+
// See the "--suppress-duplicate-includes-warning" CLI option.
656663
builder.machine.suppressDupWarning = <true|false>;
657664

658-
// See the "--save-dependencies" CLI option
665+
// See the "--save-dependencies" CLI option.
659666
builder.machine.dependenciesSaveFile = <false|"PATH_TO_FILE">;
660-
// See the "--use-dependencies" CLI option
667+
// See the "--use-dependencies" CLI option.
661668
builder.machine.dependenciesUseFile = <false|"PATH_TO_FILE">;
662669

663-
// See the "--save-directives" CLI option
670+
// See the "--save-directives" CLI option.
664671
builder.machine.directivesSaveFile = <false|"PATH_TO_FILE">;
665-
// See the "--use-directives" CLI option
672+
// See the "--use-directives" CLI option.
666673
builder.machine.directivesUseFile = <false|"PATH_TO_FILE">;
667674

668675
const inputFile = "PATH_TO_YOUR_INPUT_FILE";
@@ -675,11 +682,11 @@ To understand Builder setup, please review [this source code](./src/cli.js).
675682

676683
## Reproducible Artifacts ##
677684

678-
It is possible to save the build configuration used for preprocessing a source file &mdash; references to the concrete versions of GitHub files and libraries that are used, and to Builder variable definitions &mdash; and preprocess the source file again later with the saved configuration.
685+
It is possible to save the build configuration used for preprocessing a source file &mdash; references to the concrete versions of GitHub files and libraries that are used, and Builder variable definitions which are used &mdash; and preprocess the source file again later with the saved configuration.
679686

680687
### GitHub Files: Dependencies ###
681688

682-
`--save-dependencies [<path_to_file>]` and `--use-dependencies [<path_to_file>]` options are used to save and to reuse, respectively, references to concrete versions of GitHub files and libraries. The references are saved in a JSON file. If a file is not specified, Builder will attempt to read a `dependencies.json` file from the local directory. Every reference consists of GitHub file URL and Git Blob ID (Git Blob SHA). For more information, please see [the Git Manual](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) and [the GitA API](https://developer.github.com/v3/git/blobs/).
689+
`--save-dependencies [<path_to_file>]` and `--use-dependencies [<path_to_file>]` options are used to save and to reuse, respectively, references to concrete versions of GitHub files and libraries. The references are saved in a JSON file. If a file name is not specified, the `dependencies.json` file in the local directory is used. Every reference consists of GitHub file URL and Git Blob ID (Git Blob SHA). For more information, please see [the Git Manual](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) and [the Git API](https://developer.github.com/v3/git/blobs/).
683690

684691
**Note** It is possible to obtain the Git Blob ID of a GitHub file using the following *git* command: `git hash-object <path_to_file>`
685692

@@ -695,14 +702,6 @@ These options are processed the following way:
695702

696703
**Note** If either `--save-dependencies` or `--use-dependencies` is specified, the `--cache` option is ignored.
697704

698-
### Builder Variables: Directives ###
699-
700-
The `--save-directives [<path_to_file>]` and `--use-directives [<path_to_file>]` options are used to, respectively, save and reuse Builder variable definitions. The definitions are saved in a JSON file. If a file is not specified, Builder will attempt to read a `directives.json` file from the local directory. These options are processed the similar way as the `--save-dependencies` and `--use-dependencies` options, above.
701-
702-
When the `--use-directives [<path_to_file>]` option is used, the saved Builder variable definitions are merged with definitions specified by `-D <variable> <value>` options.
703-
704-
### Example Files ###
705-
706705
A typical `dependencies.json` file looks like this:
707706

708707
```json
@@ -718,6 +717,12 @@ A typical `dependencies.json` file looks like this:
718717
]
719718
```
720719

720+
### Builder Variables: Directives ###
721+
722+
The `--save-directives [<path_to_file>]` and `--use-directives [<path_to_file>]` options are used to, respectively, save and reuse Builder variable definitions. The definitions are saved in a JSON file. If a file is not specified, the `directives.json` file in the local directory is used. These options are processed the similar way as the `--save-dependencies` and `--use-dependencies` options, above.
723+
724+
When the `--use-directives [<path_to_file>]` option is used, the saved Builder variable definitions are merged with definitions specified by `-D<variable> <value>` options.
725+
721726
A typical `directives.json` file looks like this:
722727

723728
```json
@@ -843,6 +848,16 @@ For example, to operate through a proxy running at IP address 192.168.10.2 on po
843848

844849
**Note** Files retrieved from GitHub (`github:` protocol) are always accessed using HTTPS. So when specifying a proxy in this case, make sure you use set the `HTTPS_PROXY` environment variable.
845850

851+
### Local Includes From Remote Files ###
852+
853+
By default, all [local includes](#local-files), even if they are mentioned in remote source files, are always interpreted as relative to the system where Builder is running.
854+
855+
If `--use-remote-relative-includes` option is specified, every [local include](#local-files) is interpreted as relative to the location of the source file where it is mentioned. For example, a local include mentioned in remote source file from GitHub will be downloaded from the same GitHub URL as the source file.
856+
857+
`--use-remote-relative-includes` option does not affect includes with [absolute remote paths](#remote-files).
858+
859+
**Note** In the current Builder version `--use-remote-relative-includes` option affects includes mentioned in remote source files from GitHub only.
860+
846861
# Testing #
847862

848863
```sh

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Builder",
3-
"version": "2.7.0",
3+
"version": "2.8.0",
44
"description": "Builder Language Implementation",
55
"main": "src/index.js",
66
"bin": {

Diff for: spec/Machine/remote-relative-includes.spec.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2016-2019 Electric Imp
2+
// This file is licensed under the MIT License
3+
// http://opensource.org/licenses/MIT
4+
5+
'use strict';
6+
7+
require('jasmine-expect');
8+
9+
const init = require('./init')('main');
10+
const eol = require('eol');
11+
12+
const githubPathA = "github:electricimp/Builder/spec/fixtures/sample-1/inc-a.nut"
13+
14+
describe('Machine', () => {
15+
let machine;
16+
17+
beforeEach(() => {
18+
machine = init.createMachine();
19+
});
20+
21+
it('check that locally included file will be checkouted from github', () => {
22+
const fileNotFoundMessage = 'Local file "inc-b.nut" not found (github:electricimp/Builder/spec/fixtures/sample-1/inc-a.nut:2)';
23+
try {
24+
eol.lf(machine.execute(`@include once "${githubPathA}"`));
25+
fail();
26+
} catch (e) {
27+
expect(e.message).toEqual(fileNotFoundMessage);
28+
}
29+
30+
// check respect-local-includes feature
31+
machine.remoteRelativeIncludes = true;
32+
const res = eol.lf(machine.execute(`@include once "${githubPathA}"`));
33+
expect(res).toEqual(`// included file a\n// included file b\n`);
34+
});
35+
});

Diff for: src/Machine.js

+34-1
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,36 @@ class Machine {
283283
}
284284
}
285285

286+
/**
287+
* Replace local includes to github URLs if requested
288+
* @param {string} includePath
289+
* @param {{}} context
290+
* @private
291+
*/
292+
_remoteRelativeIncludes(includePath, context) {
293+
if (!this.remoteRelativeIncludes) {
294+
return includePath;
295+
}
296+
297+
// check if the file is included locally
298+
if (this._getReader(includePath) !== this.readers.file) {
299+
return includePath;
300+
}
301+
302+
// check that path is not absolute
303+
if (path.isAbsolute(includePath)) {
304+
return includePath;
305+
}
306+
307+
// check if file is included from github source
308+
const remotePath = this._formatPath(context.__PATH__, includePath);
309+
if (this._getReader(remotePath) === this.readers.github) {
310+
return remotePath;
311+
}
312+
313+
return includePath;
314+
}
315+
286316
/**
287317
* Include source
288318
* @param {string} source
@@ -295,7 +325,7 @@ class Machine {
295325
_includeSource(source, context, buffer, once, evaluated) {
296326

297327
// path is an expression, evaluate it
298-
const includePath = evaluated ? source : this.expression.evaluate(
328+
let includePath = evaluated ? source : this.expression.evaluate(
299329
source,
300330
context,
301331
).trim();
@@ -306,6 +336,9 @@ class Machine {
306336
return;
307337
}
308338

339+
// checkout local includes in the github sources from github
340+
includePath = this._remoteRelativeIncludes(includePath, context);
341+
309342
const reader = this._getReader(includePath);
310343
this.logger.info(`Including source "${includePath}"`);
311344

Diff for: src/cli.js

+18-13
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,26 @@ function usageInfo() {
6262
6363
usage:\n\t\u001b[34m${Object.getOwnPropertyNames((packageJson.bin))[0]} [-l] [-D<variable> <value>]
6464
\t\t[--github-user <username> --github-token <token>]
65-
\t\t[--lib <path_to_file>] [--suppress-duplicate-includes-warning]
65+
\t\t[--lib <path_to_file>] [--use-remote-relative-includes] [--suppress-duplicate-includes-warning]
6666
\t\t[--cache] [--clear-cache] [--cache-exclude-list <path_to_file>]
6767
\t\t[--save-dependencies [<path_to_file>]] [--use-dependencies [<path_to_file>]]
6868
\t\t[--save-directives [<path_to_file>]] [--use-directives [<path_to_file>]] <input_file>\u001b[39m
6969
7070
where:
7171
\t\u001b[34m-l\u001b[39m - generates line control statements
72-
\t\u001b[34m-D<varname> <value>\u001b[39m - define a variable that will be available from the source
73-
\t\u001b[34m--github-user <username>\u001b[39m - username for GitHub
74-
\t\u001b[34m--github-token <token>\u001b[39m - personal access token or password for GitHub
75-
\t\u001b[34m--lib <path_to_file>\u001b[39m - includes the specified JavaScript file(s) as a library
76-
\t\u001b[34m--suppress-duplicate-includes-warning\u001b[39m - does not show a warning if a source file with the exact content was included multiple times
77-
\t\u001b[34m--cache>\u001b[39m - turns on cache for all files included from remote resources
78-
\t\u001b[34m--clear-cache\u001b[39m - clears cache before Builder starts running
79-
\t\u001b[34m--cache-exclude-list <path_to_file>\u001b[39m - path to the file that lists the resources which should be excluded from caching
80-
\t\u001b[34m--save-dependencies [path_to_file]\u001b[39m - saves references to the used versions of GitHub files in the specified file
81-
\t\u001b[34m--use-dependencies [path_to_file]\u001b[39m - reads from the specified file references to the versions of GitHub files which should be used
82-
\t\u001b[34m--save-directives [path_to_file]\u001b[39m - saves Builder variable definitions in the specified file
83-
\t\u001b[34m--use-directives [path_to_file]\u001b[39m - reads from the specified file Builder variable definitions which should be used
72+
\t\u001b[34m-D<varname> <value>\u001b[39m - defines a variable
73+
\t\u001b[34m--github-user <username>\u001b[39m - a GitHub username
74+
\t\u001b[34m--github-token <token>\u001b[39m - a GitHub personal access token or password
75+
\t\u001b[34m--lib <path_to_file>\u001b[39m - include the specified JavaScript file(s) as a library
76+
\t\u001b[34m--use-remote-relative-includes\u001b[39m - interpret every local include as relative to the location of the source file where it is mentioned
77+
\t\u001b[34m--suppress-duplicate-includes-warning\u001b[39m - do not show a warning if a source file with the same content was included multiple times
78+
\t\u001b[34m--cache>\u001b[39m - turn on caching for all files included from remote resources
79+
\t\u001b[34m--clear-cache\u001b[39m - clear the cache before Builder starts running
80+
\t\u001b[34m--cache-exclude-list <path_to_file>\u001b[39m - set the path to the file that lists resources which should not be cached
81+
\t\u001b[34m--save-dependencies [path_to_file]\u001b[39m - save references to the required GitHub files in the specified file
82+
\t\u001b[34m--use-dependencies [path_to_file]\u001b[39m - use the specified file to set which GitHub files are required
83+
\t\u001b[34m--save-directives [path_to_file]\u001b[39m - save Builder variable definitions in the specified file
84+
\t\u001b[34m--use-directives [path_to_file]\u001b[39m - use Builder variable definitions from the specified file
8485
\t\u001b[34m<input_file>\u001b[39m — is the path to source file which should be preprocessed
8586
`.trim());
8687
}
@@ -163,6 +164,8 @@ function readArgs() {
163164
throw Error('Expected argument value after ' + argument);
164165
}
165166
res.directivesSaveFile = getOption(args, directivesDefaultFileName);
167+
} else if ('--use-remote-relative-includes' === argument) {
168+
res.remoteRelativeIncludes = true;
166169
} else if ('--suppress-duplicate-includes-warning' === argument || '--suppress-duplicate' === argument) {
167170
res.suppressDupWarning = true;
168171
} else if ('--use-dependencies' === argument) {
@@ -209,6 +212,8 @@ try {
209212
builder.machine.readers.github.token = args.gh.token;
210213
//set cache settings
211214
builder.machine.excludeList = args.excludeFile;
215+
// set remote relative includes
216+
builder.machine.remoteRelativeIncludes = args.remoteRelativeIncludes;
212217
// set supress dupicate includes warning
213218
builder.machine.suppressDupWarning = args.suppressDupWarning;
214219
// use dependencies

0 commit comments

Comments
 (0)