playground/client: Fortune example: generate all go/js combinations.
pgbundle now bundles files matching globs from a config file
and writes the bundle to stdout.
Added glob files for all combinations of go/js for fortune
client/server.
Change-Id: Id871efa6a39eac6e02898ffa27eda80d29ad104f
diff --git a/client/.gitignore b/client/.gitignore
index f587daf..709f25d 100644
--- a/client/.gitignore
+++ b/client/.gitignore
@@ -1,7 +1,7 @@
bundles/*/*/bin
bundles/*/*/pkg
src/example_bundles
-bundle.json
+bundle_*.json
node_modules
npm-debug.log
build
diff --git a/client/Makefile b/client/Makefile
index d4fdc65..494248a 100644
--- a/client/Makefile
+++ b/client/Makefile
@@ -31,18 +31,29 @@
mkdir -p $(@D)
browserify -d $< -p [ minifyify --map $(@F).map --output $@.map ] -o $@
-# All paths of the form bundles/<project>/<example>.
-example_code_bundle_dirs := $(shell find bundles -maxdepth 2 -mindepth 2)
-example_code_files := $(shell find bundles -mindepth 2)
+# Each profile (glob file with file patterns to include) from
+# `bundles/<profile>.bundle` is applied to each example folder of the
+# form `bundles/<example>/`.
+example_profiles := $(shell find bundles -maxdepth 1 -name "*.bundle")
+example_code_bundle_dirs := $(shell find bundles -maxdepth 1 -mindepth 1 -type d)
+example_files := $(shell find bundles -mindepth 1)
+bundle_temp_file := build/bundle.json
-# Builds the playground bundles for the examples.
+# Builds the playground bundles for each folder and profile combination.
# This is an empty target.
# See http://www.gnu.org/software/make/manual/html_node/Empty-Targets.html
-# This task depends on example_code_files because we want to re-bundle if any of
-# those change. However, the bundle tool works on directories, so we pass in
-# example_code_bundle_dirs as the argument.
-src/example_bundles: $(example_code_files) node_modules
- pgbundle $(example_code_bundle_dirs)
+# This task depends on example_profiles and example_files because we want
+# to re-bundle if any of those change. However, the bundle tool works on
+# directories, so we pass in example_code_bundle_dirs as the path argument.
+src/example_bundles: $(example_profiles) $(example_files) node_modules
+ mkdir -p $(dir $(bundle_temp_file))
+ @for profile in $(example_profiles); do \
+ echo "Bundling with profile \"$${profile}\""; \
+ for folder in $(example_code_bundle_dirs); do \
+ pgbundle --verbose "$${profile}" "$${folder}" > $(bundle_temp_file); \
+ mv -f $(bundle_temp_file) "$${folder}/bundle_$$(basename $${profile} .bundle).json"; \
+ done; \
+ done
touch $@
node_modules: package.json
@@ -70,7 +81,7 @@
distclean: clean
@npm cache clean
@$(RM) -rf src/example_bundles
- @$(RM) -rf $(shell find bundles -name "bundle.json")
+ @$(RM) -rf $(shell find bundles -name "bundle_*.json")
.PHONY: lint
lint:
diff --git a/client/README.md b/client/README.md
index 84d9816..304406d 100644
--- a/client/README.md
+++ b/client/README.md
@@ -3,7 +3,7 @@
Source code for the Vanadium playground web client.
* `build` - Temporary directory used for building the client.
-* `bundles` - Default playground examples. Organized as `bundles/<group>/<example>/`.
+* `bundles` - Default playground examples. Each combination of directory and `.bundle` file forms a bundle.
* _Makefile_ - Targets for building the client (browserifying Javascript, etc.)
* `node_modules` - Disposable directory created by `npm install` - dependency modules.
* _package.json_ - Used by `npm install` to grab playground dependencies.
diff --git a/client/bundles/fortune/ex0_go/src/fortune/fortune.vdl b/client/bundles/fortune/ex0_go/src/fortune/fortune.vdl
deleted file mode 100644
index a823cab..0000000
--- a/client/bundles/fortune/ex0_go/src/fortune/fortune.vdl
+++ /dev/null
@@ -1,10 +0,0 @@
-// index=3
-package fortune
-
-type Fortune interface {
- // Returns a random fortune.
- Get() (Fortune string | error)
-
- // Adds a fortune to the set used by Get().
- Add(Fortune string) error
-}
diff --git a/client/bundles/fortune/ex0_go/src/client/client.go b/client/bundles/fortune/src/client/client.go
similarity index 83%
rename from client/bundles/fortune/ex0_go/src/client/client.go
rename to client/bundles/fortune/src/client/client.go
index e2087ac..32407a2 100644
--- a/client/bundles/fortune/ex0_go/src/client/client.go
+++ b/client/bundles/fortune/src/client/client.go
@@ -20,7 +20,7 @@
// Create a new stub that binds to address without
// using the name service.
- stub := fortune.FortuneClient("fortune")
+ stub := fortune.FortuneClient("bakery/cookie/fortune")
// Issue a Get() RPC.
// We do this in a loop to give the server time to start up.
@@ -28,7 +28,7 @@
var fortune string
for {
var err error
- if fortune, err = stub.Get(ctx); err == nil {
+ if fortune, err = stub.GetRandomFortune(ctx); err == nil {
break
}
fmt.Printf("%v\nRetrying in 100ms...\n", err)
diff --git a/client/bundles/fortune/ex0_js/src/client/client.js b/client/bundles/fortune/src/client/client.js
similarity index 100%
rename from client/bundles/fortune/ex0_js/src/client/client.js
rename to client/bundles/fortune/src/client/client.js
diff --git a/client/bundles/fortune/ex0_js/src/fortune/fortune.vdl b/client/bundles/fortune/src/fortune/fortune.vdl
similarity index 100%
rename from client/bundles/fortune/ex0_js/src/fortune/fortune.vdl
rename to client/bundles/fortune/src/fortune/fortune.vdl
diff --git a/client/bundles/fortune/ex0_go/src/server/server.go b/client/bundles/fortune/src/server/server.go
similarity index 83%
rename from client/bundles/fortune/ex0_go/src/server/server.go
rename to client/bundles/fortune/src/server/server.go
index 96620ee..93d906c 100644
--- a/client/bundles/fortune/ex0_go/src/server/server.go
+++ b/client/bundles/fortune/src/server/server.go
@@ -39,13 +39,13 @@
}
// Methods that get called by RPC requests.
-func (f *fortuned) Get(_ ipc.ServerCall) (Fortune string, err error) {
+func (f *fortuned) GetRandomFortune(_ ipc.ServerCall) (Fortune string, err error) {
Fortune = f.fortunes[f.random.Intn(len(f.fortunes))]
fmt.Printf("Serving: %s\n", Fortune)
return Fortune, nil
}
-func (f *fortuned) Add(_ ipc.ServerCall, Fortune string) error {
+func (f *fortuned) AddNewFortune(_ ipc.ServerCall, Fortune string) error {
fmt.Printf("Adding: %s\n", Fortune)
f.fortunes = append(f.fortunes, Fortune)
return nil
@@ -74,8 +74,8 @@
}
// Start the fortune server at "fortune".
- if err := server.Serve("fortune", fortuneServer, vflag.NewAuthorizerOrDie()); err == nil {
- fmt.Printf("Fortune server serving under: fortune\n")
+ if err := server.Serve("bakery/cookie/fortune", fortuneServer, vflag.NewAuthorizerOrDie()); err == nil {
+ fmt.Printf("Fortune server serving under: bakery/cookie/fortune\n")
} else {
vlog.Panic("error serving fortune server: ", err)
}
diff --git a/client/bundles/fortune/ex0_js/src/server/server.js b/client/bundles/fortune/src/server/server.js
similarity index 100%
rename from client/bundles/fortune/ex0_js/src/server/server.js
rename to client/bundles/fortune/src/server/server.js
diff --git a/client/bundles/go.bundle b/client/bundles/go.bundle
new file mode 100644
index 0000000..93e083b
--- /dev/null
+++ b/client/bundles/go.bundle
@@ -0,0 +1,3 @@
+*.vdl
+client/**/*.go
+server/**/*.go
diff --git a/client/bundles/go_js.bundle b/client/bundles/go_js.bundle
new file mode 100644
index 0000000..dd4fb3e
--- /dev/null
+++ b/client/bundles/go_js.bundle
@@ -0,0 +1,3 @@
+*.vdl
+client/**/*.go
+server/**/*.js
diff --git a/client/bundles/js.bundle b/client/bundles/js.bundle
new file mode 100644
index 0000000..ae990f5
--- /dev/null
+++ b/client/bundles/js.bundle
@@ -0,0 +1,3 @@
+*.vdl
+client/**/*.js
+server/**/*.js
diff --git a/client/bundles/js_go.bundle b/client/bundles/js_go.bundle
new file mode 100644
index 0000000..33edac3
--- /dev/null
+++ b/client/bundles/js_go.bundle
@@ -0,0 +1,3 @@
+*.vdl
+client/**/*.js
+server/**/*.go
diff --git a/client/lib/shell/pg_test_util.sh b/client/lib/shell/pg_test_util.sh
index ee8de06..73f5ac3 100755
--- a/client/lib/shell/pg_test_util.sh
+++ b/client/lib/shell/pg_test_util.sh
@@ -55,19 +55,25 @@
# Bundles a playground example and tests it using builder.
# $1: root directory of example to test
-# $2: arguments to call builder with
+# $2: glob file with file patterns to bundle from $1
+# $3: arguments to call builder with
test_pg_example() {
local -r PGBUNDLE_DIR="$1"
- local -r BUILDER_ARGS="$2"
+ local -r PATTERN_FILE="$2"
+ local -r BUILDER_ARGS="$3"
- ./node_modules/.bin/pgbundle "${PGBUNDLE_DIR}"
+ # Create a fresh dir to save the bundle and run builder in.
+ local -r TEMP_DIR=$(shell::tmp_dir)
- # Create a fresh dir to run builder in.
+ ./node_modules/.bin/pgbundle --verbose "${PATTERN_FILE}" "${PGBUNDLE_DIR}" > "${TEMP_DIR}/test.json" || return
+
local -r ORIG_DIR=$(pwd)
- pushd $(shell::tmp_dir)
+ pushd "${TEMP_DIR}"
+
ln -s "${ORIG_DIR}/node_modules" ./ # for release/javascript/core
- "${shell_test_BIN_DIR}/builder" ${BUILDER_ARGS} < "${PGBUNDLE_DIR}/bundle.json" 2>&1 | tee builder.out
+ "${shell_test_BIN_DIR}/builder" ${BUILDER_ARGS} < "test.json" 2>&1 | tee builder.out
# Move builder output to original dir for verification.
mv builder.out "${ORIG_DIR}"
+
popd
}
diff --git a/client/src/javascript/index.js b/client/src/javascript/index.js
index 7fb0f38..e40017e 100644
--- a/client/src/javascript/index.js
+++ b/client/src/javascript/index.js
@@ -5,16 +5,16 @@
var Playground = require('./playground');
_.forEach(document.querySelectorAll('.playground'), function(el) {
- var srcdir = el.getAttribute('data-srcdir');
- console.log('Creating playground', srcdir);
+ var src = el.getAttribute('data-src');
+ console.log('Creating playground', src);
- fetchBundle(srcdir, function(err, bundle) {
+ fetchBundle(src, function(err, bundle) {
if (err) {
el.innerHTML = '<div class="error"><p>Playground error.' +
- '<br>Bundle not found: <strong>' + srcdir + '</strong></p></div>';
+ '<br>Bundle not found: <strong>' + src + '</strong></p></div>';
return;
}
- new Playground(el, srcdir, bundle); // jshint ignore:line
+ new Playground(el, src, bundle); // jshint ignore:line
});
});
@@ -22,7 +22,7 @@
var basePath = '/bundles';
console.log('Fetching bundle', loc);
superagent
- .get(path.join(basePath, loc, 'bundle.json'))
+ .get(path.join(basePath, loc))
.accept('json')
.end(function(err, res) {
if (err) {
diff --git a/client/src/static/go/index.html b/client/src/static/go/index.html
index c529f7c..1eea88b 100644
--- a/client/src/static/go/index.html
+++ b/client/src/static/go/index.html
@@ -8,7 +8,7 @@
<body>
<main>
<h1>Hello, go playground!</h1>
- <div class="lang-go playground" data-srcdir="/fortune/ex0_go"></div>
+ <div class="lang-go playground" data-src="/fortune/bundle_go.json"></div>
</main>
</body>
</html>
diff --git a/client/src/static/go_js/index.html b/client/src/static/go_js/index.html
new file mode 100644
index 0000000..a632f91
--- /dev/null
+++ b/client/src/static/go_js/index.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Playground</title>
+ <link rel="stylesheet" href="/stylesheets/playground.css">
+ <script src="/playground.js" async></script>
+ </head>
+ <body>
+ <main>
+ <h1>Hello, go-js playground!</h1>
+ <div class="lang-go lang-js playground" data-src="/fortune/bundle_go_js.json"></div>
+ </main>
+ </body>
+</html>
diff --git a/client/src/static/index.html b/client/src/static/index.html
index 8b9752e..ac3bad8 100644
--- a/client/src/static/index.html
+++ b/client/src/static/index.html
@@ -10,6 +10,11 @@
<li><a href="./go">Go</a></li>
<li><a href="./js">Javascript</a></li>
</ul>
+ <h3>More challenge?</h3>
+ <ul>
+ <li><a href="./go_js">Go client, Javascript server</a></li>
+ <li><a href="./js_go">Javascript client, Go server</a></li>
+ </ul>
</main>
</body>
</html>
diff --git a/client/src/static/js/index.html b/client/src/static/js/index.html
index 2592f82..4a3b9f6 100644
--- a/client/src/static/js/index.html
+++ b/client/src/static/js/index.html
@@ -8,7 +8,8 @@
<body>
<main>
<h1>Hello, js playground!</h1>
- <div class="lang-js playground" data-srcdir="/fortune/ex0_js"></div>
+ <!-- lang-go needed for vdl -->
+ <div class="lang-js lang-go playground" data-src="/fortune/bundle_js.json"></div>
</main>
</body>
</html>
diff --git a/client/src/static/js_go/index.html b/client/src/static/js_go/index.html
new file mode 100644
index 0000000..4b97867
--- /dev/null
+++ b/client/src/static/js_go/index.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Playground</title>
+ <link rel="stylesheet" href="/stylesheets/playground.css">
+ <script src="/playground.js" async></script>
+ </head>
+ <body>
+ <main>
+ <h1>Hello, js-go playground!</h1>
+ <div class="lang-js lang-go playground" data-src="/fortune/bundle_js_go.json"></div>
+ </main>
+ </body>
+</html>
diff --git a/client/test.sh b/client/test.sh
index 5ebb503..d66b476 100755
--- a/client/test.sh
+++ b/client/test.sh
@@ -4,7 +4,7 @@
# If any new examples are added, they should be appended to $EXAMPLES below.
# To debug playground compile errors you can build examples locally, e.g.:
-# $ cd bundles/fortune/ex0_go/src
+# $ cd bundles/fortune/src
# $ GOPATH=$(dirname $(pwd)) VDLPATH=$(dirname $(pwd)) v23 go install ./...
# v.io/core/shell/lib/shell_test.sh sourced via playground/lib/pg_test_util.sh
@@ -22,15 +22,18 @@
local -r PG_BUNDLES_DIR="${PLAYGROUND_ROOT}/client/bundles"
- local -r EXAMPLES="fortune/ex0_go fortune/ex0_js"
+ local -r EXAMPLES="fortune"
- for e in $EXAMPLES; do
- local d="${PG_BUNDLES_DIR}/${e}"
- echo -e "\n\n>>>>> Test ${d}\n\n"
- test_pg_example "${d}" "-v=true --runTimeout=5s" || shell_test::fail "${d}: failed to run"
- # TODO(sadovsky): Make this "clean exit" check more robust.
- grep -q "\"Exited cleanly.\"" builder.out || shell_test::fail "${d}: did not exit cleanly"
- rm -f builder.out
+ for e in ${EXAMPLES}; do
+ for p in "${PG_BUNDLES_DIR}"/*.bundle; do
+ local d="${PG_BUNDLES_DIR}/${e}"
+ local description="${e} with $(basename ${p})"
+ echo -e "\n\n>>>>> Test ${description}\n\n"
+ test_pg_example "${d}" "${p}" "-v=true --runTimeout=5s" || shell_test::fail "${description}: failed to run"
+ # TODO(sadovsky): Make this "clean exit" check more robust.
+ grep -q "\"Exited cleanly.\"" builder.out || shell_test::fail "${description}: did not exit cleanly"
+ rm -f builder.out
+ done
done
shell_test::pass
diff --git a/go/src/playground/playground_v23_test.go b/go/src/playground/playground_v23_test.go
index 6150d3e..7b4057a 100644
--- a/go/src/playground/playground_v23_test.go
+++ b/go/src/playground/playground_v23_test.go
@@ -1,8 +1,11 @@
package playground_test
import (
+ "bytes"
+ "io/ioutil"
"os"
"path/filepath"
+ "strings"
_ "v.io/x/ref/profiles"
"v.io/x/ref/test/v23tests"
@@ -36,21 +39,19 @@
// Bundles a playground example and tests it using builder.
// - dir is the root directory of example to test
+// - globFile is the path to the glob file with file patterns to use from dir
// - args are the arguments to call builder with
-func runPGExample(i *v23tests.T, dir string, args ...string) *v23tests.Invocation {
- i.Run("./node_modules/.bin/pgbundle", dir)
+func runPGExample(i *v23tests.T, globFile, dir string, args ...string) *v23tests.Invocation {
+ bundle := i.Run("./node_modules/.bin/pgbundle", "--verbose", globFile, dir)
+
tmp := i.NewTempDir()
cwd := i.Pushd(tmp)
+ defer i.Popd()
old := filepath.Join(cwd, "node_modules")
if err := os.Symlink(old, filepath.Join(".", filepath.Base(old))); err != nil {
i.Fatalf("%s: symlink: failed: %v", i.Caller(2), err)
}
- bundleName := filepath.Join(dir, "bundle.json")
- stdin, err := os.Open(bundleName)
- if err != nil {
- i.Fatalf("%s: open(%s) failed: %v", i.Caller(2), bundleName, err)
- }
// TODO(ivanpi): move this out so it only gets invoked once even though
// the binary is cached.
builderBin := i.BuildGoPkg("playground/builder")
@@ -59,22 +60,18 @@
if path := os.Getenv("PATH"); len(path) > 0 {
PATH += ":" + path
}
- defer i.Popd()
+ stdin := bytes.NewBufferString(bundle)
return builderBin.WithEnv(PATH).WithStdin(stdin).Start(args...)
}
-// Sets up a directory with the given files, then runs builder.
+// Sets up a glob file with the given files, then runs builder.
func testWithFiles(i *v23tests.T, pgRoot string, files ...string) *v23tests.Invocation {
testdataDir := filepath.Join(pgRoot, "testdata")
- pgBundleDir := i.NewTempDir()
- for _, f := range files {
- fdir := filepath.Join(pgBundleDir, filepath.Dir(f))
- if err := os.MkdirAll(fdir, 0755); err != nil {
- i.Fatalf("%s: mkdir(%q): failed: %v", i.Caller(1), fdir, err)
- }
- i.Run("/bin/cp", filepath.Join(testdataDir, f), fdir)
+ globFile := filepath.Join(i.NewTempDir(), "test.bundle")
+ if err := ioutil.WriteFile(globFile, []byte(strings.Join(files, "\n")+"\n"), 0644); err != nil {
+ i.Fatalf("%s: write(%q): failed: %v", i.Caller(1), globFile, err)
}
- return runPGExample(i, pgBundleDir, "-v=true", "--includeV23Env=true", "--runTimeout=5s")
+ return runPGExample(i, globFile, testdataDir, "-v=true", "--includeV23Env=true", "--runTimeout=5s")
}
func V23TestPlayground(i *v23tests.T) {
diff --git a/go/src/playground/test.sh b/go/src/playground/test.sh
index 043efb6..4bd6378 100755
--- a/go/src/playground/test.sh
+++ b/go/src/playground/test.sh
@@ -6,19 +6,15 @@
# (shell_test.sh has side effects, should not be sourced again)
source "$(go list -f {{.Dir}} playground)/../../../client/lib/shell/pg_test_util.sh"
-# Sets up a directory with the given files, then runs builder.
+# Sets up a glob file with the given files, then runs builder.
test_with_files() {
local -r TESTDATA_DIR="$(go list -f {{.Dir}} playground)/testdata"
- # Write input files to a fresh dir before bundling and running them.
- local -r PGBUNDLE_DIR=$(shell::tmp_dir)
- for f in $@; do
- fdir="${PGBUNDLE_DIR}/$(dirname ${f})"
- mkdir -p "${fdir}"
- cp "${TESTDATA_DIR}/${f}" "${fdir}/"
- done
+ # Write input file paths to the glob file.
+ local -r CONFIG_FILE="$(shell::tmp_dir)/test.bundle"
+ echo "$*" | tr ' ' '\n' > "${CONFIG_FILE}"
- test_pg_example "${PGBUNDLE_DIR}" "-v=true --includeV23Env=true --runTimeout=5s"
+ test_pg_example "${TESTDATA_DIR}" "${CONFIG_FILE}" "-v=true --includeV23Env=true --runTimeout=5s"
}
main() {
diff --git a/pgbundle/index.js b/pgbundle/index.js
index bf8428a..4b9bf98 100644
--- a/pgbundle/index.js
+++ b/pgbundle/index.js
@@ -3,15 +3,19 @@
var glob = require('glob');
var path = require('path');
-// Filename to write the data to.
-var BUNDLE_NAME = 'bundle.json';
-
module.exports = {run: run};
-// TODO(nlacasse): Improve this.
function usage() {
- console.log('Usage: pgbundle [options] <path> [<path> <path> ...]');
- console.log('Options: --verbose: Enable verbose output.');
+ console.error('Usage: pgbundle [options] <glob_file> <root_path>');
+ console.error('Arguments: <glob_file>: Path to file containing a list of' +
+ ' glob patterns, one per line. The bundle includes only files with path' +
+ ' suffixes matching one of the globs. Each glob must match at least one' +
+ ' file, otherwise bundling fails with a non-zero exit code.');
+ console.error(' <root_path>: Path to directory where files' +
+ ' matching glob patterns are taken from.');
+ console.error('Options: --verbose: Enable verbose output.');
+ console.error(' --empty: Omit file contents in bundle, include only' +
+ ' paths and metadata.');
process.exit(1);
}
@@ -47,87 +51,80 @@
};
}
-function shouldIgnore(fileName) {
- // Ignore directories.
- if (_.last(fileName) === '/') {
- return true;
- }
- // Ignore bundle files.
- if (fileName === BUNDLE_NAME) {
- return true;
- }
- // Ignore generated .vdl.go and .vdl.js files.
- if ((/\.vdl\.(go|js)$/i).test(fileName)) {
- return true;
- }
- // Ignore files inside "bin" and "pkg" directories.
- if (fileName.indexOf('bin/') === 0 ||
- fileName.indexOf('pkg/') === 0) {
- return true;
- }
- return false;
-}
-
// Main function.
function run() {
- // Get the paths from process.argv.
- var argv = require('minimist')(process.argv.slice(2));
- var dirs = argv._;
+ // Get the flags and positional arguments from process.argv.
+ var argv = require('minimist')(process.argv.slice(2), {
+ boolean: ['verbose', 'empty']
+ });
- // Make sure there is at least one path.
- if (!dirs || dirs.length === 0) {
+ // Make sure the glob file and the root path path are specified.
+ if (!argv._ || argv._.length !== 2) {
return usage();
}
- // Loop over each path.
- _.each(dirs, function(dir) {
- var relpaths = glob.sync('**', {
+ var globFile = argv._[0];
+ var dir = argv._[1];
+ // Read glob file, filtering out empty lines.
+ var patterns = _.filter(
+ fs.readFileSync(globFile, {encoding: 'utf8'}).split('\n'));
+ // The root path must be a directory.
+ if (!fs.lstatSync(dir).isDirectory()) {
+ return usage();
+ }
+
+ var unmatched = [];
+
+ // Apply each glob pattern to the directory.
+ var relpaths = _.flatten(_.map(patterns, function(pattern) {
+ var match = glob.sync('**/' + pattern, {
cwd: dir,
- mark: true // Add a '/' char to directory matches.
+ nodir: true
});
-
- if (relpaths.length === 0) {
- return usage();
+ if (match.length === 0) {
+ unmatched.push(pattern);
}
+ return match;
+ }));
- var out = {files: []};
+ // If any pattern matched zero files, halt with a non-zero exit code.
+ // TODO(ivanpi): Allow optional patterns, e.g. prefixed by '?'?
+ if (unmatched.length > 0) {
+ console.warn('Error bundling "%s": unmatched patterns %j', dir, unmatched);
+ process.exit(2);
+ }
- // Loop over each file.
- _.each(relpaths, function(relpath) {
- if (shouldIgnore(relpath)) {
- return;
- }
+ var out = {files: []};
- var abspath = path.resolve(dir, relpath);
- var text = fs.readFileSync(abspath, {encoding: 'utf8'});
+ // Loop over each file.
+ _.each(relpaths, function(relpath) {
+ var abspath = path.resolve(dir, relpath);
+ var lines = fs.readFileSync(abspath, {encoding: 'utf8'}).split('\n');
- var lines = text.split('\n');
- lines = stripBuildIgnore(lines);
- lines = stripLeadingBlankLines(lines);
- var indexAndLines = getIndex(lines);
- var index = indexAndLines.index;
- lines = indexAndLines.lines;
+ lines = stripBuildIgnore(lines);
+ lines = stripLeadingBlankLines(lines);
+ var indexAndLines = getIndex(lines);
+ var index = indexAndLines.index;
+ lines = indexAndLines.lines;
- out.files.push({
- name: relpath,
- body: lines.join('\n'),
- index: index
- });
+ out.files.push({
+ name: relpath,
+ body: argv.empty ? '' : lines.join('\n'),
+ index: index
});
-
- out.files = _.sortBy(out.files, 'index');
-
- // Drop the index fields -- we don't need them anymore.
- out.files = _.map(out.files, function(f) {
- return _.omit(f, 'index');
- });
-
- // Write the bundle.json.
- var outFile = path.resolve(dir, BUNDLE_NAME);
- fs.writeFileSync(outFile, JSON.stringify(out));
-
- if (argv.verbose) {
- console.log('Wrote ' + outFile);
- }
});
+
+ out.files = _.sortBy(out.files, 'index');
+
+ // Drop the index fields -- we don't need them anymore.
+ out.files = _.map(out.files, function(f) {
+ return _.omit(f, 'index');
+ });
+
+ // Write the bundle to stdout.
+ process.stdout.write(JSON.stringify(out) + '\n');
+
+ if (argv.verbose) {
+ console.warn('Bundled "%s" using "%s"', dir, globFile);
+ }
}