blob: f29180b2526830fad809438fed63f4f837aee747 [file] [log] [blame]
murgatroid99cb46db02015-04-14 17:18:26 -07001/*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34'use strict';
35
36var fs = require('fs');
37var path = require('path');
38
39var _ = require('underscore');
40var async = require('async');
41var pbjs = require('protobufjs/cli/pbjs');
42var parseArgs = require('minimist');
43var Mustache = require('mustache');
44
45var package_json = require('../package.json');
46
47var template_path = path.resolve(__dirname, 'service_packager');
48
49var package_tpl_path = path.join(template_path, 'package.json.template');
50
51var arg_format = {
52 string: ['include', 'out', 'name', 'version'],
53 alias: {
54 include: 'i',
55 out: 'o',
56 name: 'n',
57 version: 'v'
58 }
59};
60
61// TODO(mlumish): autogenerate README.md from proto file
62
murgatroid9908b0e662015-05-15 09:34:49 -070063/**
64 * Render package.json file from template using provided parameters.
65 * @param {Object} params Map of parameter names to values
66 * @param {function(Error, string)} callback Callback to pass rendered template
67 * text to
68 */
murgatroid99cb46db02015-04-14 17:18:26 -070069function generatePackage(params, callback) {
70 fs.readFile(package_tpl_path, {encoding: 'utf-8'}, function(err, template) {
71 if (err) {
72 callback(err);
73 } else {
74 var rendered = Mustache.render(template, params);
75 callback(null, rendered);
76 }
77 });
78}
79
murgatroid9908b0e662015-05-15 09:34:49 -070080/**
81 * Copy a file
82 * @param {string} src_path The filepath to copy from
83 * @param {string} dest_path The filepath to copy to
84 */
murgatroid99cb46db02015-04-14 17:18:26 -070085function copyFile(src_path, dest_path) {
86 fs.createReadStream(src_path).pipe(fs.createWriteStream(dest_path));
87}
88
murgatroid9908b0e662015-05-15 09:34:49 -070089/**
90 * Run the script. Copies the index.js and LICENSE files to the output path,
91 * renders the package.json template to the output path, and generates a
92 * service.json file from the input proto files using pbjs. The arguments are
93 * taken directly from the command line, and handled as follows:
94 * -i (--include) : An include path for pbjs (can be dpulicated)
95 * -o (--output): The output path
96 * -n (--name): The name of the package
97 * -v (--version): The package version
98 * @param {Array} argv The argument vector
99 */
murgatroid99cb46db02015-04-14 17:18:26 -0700100function main(argv) {
101 var args = parseArgs(argv, arg_format);
102 var out_path = path.resolve(args.out);
murgatroid99b70d1d92015-05-13 10:55:00 -0700103 var include_dirs = [];
104 if (args.include) {
105 include_dirs = _.map(_.flatten([args.include]), function(p) {
106 return path.resolve(p);
107 });
108 }
murgatroid99cb46db02015-04-14 17:18:26 -0700109 args.grpc_version = package_json.version;
110 generatePackage(args, function(err, rendered) {
111 if (err) throw err;
112 fs.writeFile(path.join(out_path, 'package.json'), rendered, function(err) {
113 if (err) throw err;
114 });
115 });
116 copyFile(path.join(template_path, 'index.js'),
117 path.join(out_path, 'index.js'));
118 copyFile(path.join(__dirname, '..', 'LICENSE'),
119 path.join(out_path, 'LICENSE'));
120
murgatroid99cb46db02015-04-14 17:18:26 -0700121 var service_stream = fs.createWriteStream(path.join(out_path,
122 'service.json'));
123 var pbjs_args = _.flatten(['node', 'pbjs',
124 args._[0],
murgatroid99f4b28322015-05-12 12:39:22 -0700125 '-legacy',
murgatroid99cb46db02015-04-14 17:18:26 -0700126 _.map(include_dirs, function(dir) {
127 return "-path=" + dir;
128 })]);
129 var old_stdout = process.stdout;
130 process.__defineGetter__('stdout', function() {
131 return service_stream;
132 });
133 var pbjs_status = pbjs.main(pbjs_args);
134 process.__defineGetter__('stdout', function() {
135 return old_stdout;
136 });
137 if (pbjs_status !== pbjs.STATUS_OK) {
138 throw new Error('pbjs failed with status code ' + pbjs_status);
139 }
140}
141
142exports.main = main;