From c3daebfdf49f737110616a87f52c1a0feb6fdbd9 Mon Sep 17 00:00:00 2001 From: Cody Peter Mello Date: Mon, 27 Aug 2018 18:45:58 +0000 Subject: [PATCH] joyent/node-bunyan-syslog#49 Release v0.3.2 joyent/node-bunyan-syslog#50 Use ESLint for linting and style checking Reviewed by: Patrick Mooney Approved by: Patrick Mooney --- .eslintrc | 22 ++++ .gitignore | 7 +- .gitmodules | 4 +- .npmignore | 21 ++-- Makefile | 46 ++++++-- README.md | 44 ++++++++ deps/javascriptlint | 2 +- deps/jsstyle | 2 +- lib/index.js | 4 +- lib/sys.js | 35 +++--- lib/tcp.js | 9 +- lib/udp.js | 5 +- package.json | 16 ++- test/rsyslog.conf | 10 ++ test/run.js | 15 +++ test/sys.test.js | 13 ++- test/tcp.test.js | 14 ++- test/udp.test.js | 17 +-- tools/mk/Makefile.defs | 66 ++++++++++- tools/mk/Makefile.deps | 45 +++++++- tools/mk/Makefile.node.defs | 110 ++++++++++++++++++ tools/mk/Makefile.node.targ | 42 +++++++ tools/mk/Makefile.node_deps.defs | 10 +- tools/mk/Makefile.node_deps.targ | 10 +- tools/mk/Makefile.node_prebuilt.defs | 159 +++++++++++++++++++++++++++ tools/mk/Makefile.node_prebuilt.targ | 42 +++++++ tools/mk/Makefile.targ | 91 ++++++++++++--- 27 files changed, 770 insertions(+), 91 deletions(-) create mode 100644 .eslintrc mode change 100755 => 100644 lib/tcp.js create mode 100644 test/rsyslog.conf create mode 100644 test/run.js create mode 100644 tools/mk/Makefile.node.defs create mode 100644 tools/mk/Makefile.node.targ create mode 100644 tools/mk/Makefile.node_prebuilt.defs create mode 100644 tools/mk/Makefile.node_prebuilt.targ diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..27aadf9 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,22 @@ +{ + "plugins": [ "joyent" ], + "extends": [ + "eslint:recommended", + "plugin:joyent/style", + "plugin:joyent/lint" + ], + "parserOptions": { + "ecmaVersion": 5, + "sourceType": "script", + "ecmaFeatures": { + } + }, + "env": { + "node": true + }, + "rules": { + // Style: + "func-style": [ "error", "declaration" ], + "multiline-comment-style": [ "error", "starred-block" ] + } +} diff --git a/.gitignore b/.gitignore index 64b569a..277c54f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ +/build +/coverage +/node /node_modules /tmp -build +/package-lock.json +*.log docs/*.json docs/*.html cscope.in.out cscope.po.out cscope.out -npm-debug.log diff --git a/.gitmodules b/.gitmodules index d528541..d2c7b86 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "deps/jsstyle"] path = deps/jsstyle - url = git://github.com/davepacheco/jsstyle.git + url = https://github.com/joyent/jsstyle.git [submodule "deps/javascriptlint"] path = deps/javascriptlint - url = git://github.com/davepacheco/javascriptlint.git + url = https://github.com/joyent/javascriptlint.git diff --git a/.npmignore b/.npmignore index 777c48e..2e34f58 100644 --- a/.npmignore +++ b/.npmignore @@ -1,8 +1,15 @@ -deps -tools -build -test -.gitmodules -.npmignore +*.log +/Makefile +/deps +/test +/tools +/.gitmodules +/.npmignore +/.eslintrc +/.travis.yml +/CONTRIBUTING.md +/build +/node +/coverage +/test.pid *.tgz -Makefile diff --git a/Makefile b/Makefile index 5c6e21c..dd3b0af 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,13 @@ # -# Copyright (c) 2013, Mark Cavage. All rights reserved. +# Copyright (c) 2018, Joyent, Inc. +# # # Tools # -NPM := npm -NPM_EXEC := npm -TAP := ./node_modules/.bin/tap + +ISTANBUL := node_modules/.bin/istanbul +FAUCET := node_modules/.bin/faucet # # Files @@ -16,22 +17,45 @@ JSL_CONF_NODE = tools/jsl.node.conf JSL_FILES_NODE = $(JS_FILES) JSSTYLE_FILES = $(JS_FILES) JSSTYLE_FLAGS = -f tools/jsstyle.conf +ESLINT_FILES = $(JS_FILES) +BUILD := node -CLEAN_FILES += ./node_modules build +ifeq ($(shell uname -s),SunOS) + NODE_PREBUILT_VERSION = v4.9.0 + NODE_PREBUILT_TAG = zone + NODE_PREBUILT_IMAGE = 18b094b0-eb01-11e5-80c1-175dac7ddf02 +endif include ./tools/mk/Makefile.defs -include ./tools/mk/Makefile.node_deps.defs +ifeq ($(shell uname -s),SunOS) + include ./tools/mk/Makefile.node_prebuilt.defs +else + NODE := node + NPM := $(shell which npm) + NPM_EXEC=$(NPM) +endif # # Repo-specific targets # -.PHONY: all test -all: $(REPO_DEPS) +.PHONY: all +all: $(NPM_EXEC) + $(NPM) install + +$(ISTANBUL): | $(NPM_EXEC) $(NPM) install -test: - $(TAP) test +$(FAUCET): | $(NPM_EXEC) + $(NPM) install + +.PHONY: test +test: $(ISTANBUL) $(FAUCET) + $(NODE) $(ISTANBUL) cover --print none test/run.js | $(FAUCET) + +CLEAN_FILES += ./node_modules ./build include ./tools/mk/Makefile.deps -include ./tools/mk/Makefile.node_deps.targ +ifeq ($(shell uname -s),SunOS) + include ./tools/mk/Makefile.node_prebuilt.targ +endif include ./tools/mk/Makefile.targ diff --git a/README.md b/README.md index 33d2bba..f520800 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,31 @@ var log = bunyan.createLogger({ log.debug({foo: 'bar'}, 'hello %s', 'world'); ``` + That's pretty much it. You create a syslog stream, and point it at a syslog server (UDP by default; you can force TCP by setting `type: tcp` in the constructor); default is to use facility `user` and a syslog server on `127.0.0.1:514`. Note you *must* pass `type: 'raw'` to bunyan in the top-level stream object or this won't work. +If you want your logs to be in the normal bunyan format, `rsyslog` allows you to +setup a template to format it as just the JSON object: + +``` +template(name="bunyan" type="string" + string="%msg:R,ERE,1,FIELD:(\\{.*\\})--end%\n") + +local0.* /var/log/application.log;bunyan +``` + +You can also write this using the older `$template` syntax: + +``` +$template bunyan,"%msg:R,ERE,1,FIELD:(\{.*\})--end%\n" + +local0.* /var/log/application.log;bunyan +``` + ## Mappings This module maps bunyan levels to syslog levels as follows: @@ -53,6 +72,31 @@ This module maps bunyan levels to syslog levels as follows: +--------+--------+ ``` +## Running the test suite + +You can run the test suite using the provided `rsyslog` configuration: + +``` +$ rsyslogd -f ./test/rsyslog.conf -i ./test.pid -u $USER +$ make test +$ kill $(cat test.pid) +``` + +If you have an older `rsyslog` installed, you can adjust it to use the legacy +syntax: + +``` +$ModLoad imudp +$ModLoad imtcp + +$UDPServerAddress 127.0.0.1 +$UDPServerRun 10514 + +$InputTCPServerRun 10514 +``` + +Note that when run this way, the TCP socket will listen on `0.0.0.0`. + # License MIT. diff --git a/deps/javascriptlint b/deps/javascriptlint index e1bd0ab..ad52812 160000 --- a/deps/javascriptlint +++ b/deps/javascriptlint @@ -1 +1 @@ -Subproject commit e1bd0abfd424811af469d1ece3af131d95443924 +Subproject commit ad52812e77bdfb1e90fb71a1201adb2b665a27e6 diff --git a/deps/jsstyle b/deps/jsstyle index da42b50..52dc973 160000 --- a/deps/jsstyle +++ b/deps/jsstyle @@ -1 +1 @@ -Subproject commit da42b50ceb12d431437b32efd4c411a8e2fac0c8 +Subproject commit 52dc973cf64da11834eca7cf46ebce8518e3ee88 diff --git a/lib/index.js b/lib/index.js index 96b2ce5..79e1759 100644 --- a/lib/index.js +++ b/lib/index.js @@ -8,7 +8,7 @@ var UDPStream = require('./udp'); -///--- Globals +// --- Globals var FACILITY = { kern: 0, @@ -35,7 +35,7 @@ var FACILITY = { -///--- Exports +// --- Exports module.exports = { createBunyanStream: function createBunyanStream(opts) { diff --git a/lib/sys.js b/lib/sys.js index 5b691f2..c6d0b81 100644 --- a/lib/sys.js +++ b/lib/sys.js @@ -1,6 +1,5 @@ // Copyright 2013 Mark Cavage, Inc. All rights reserved. -var dgram = require('dgram'); var os = require('os'); var Stream = require('stream').Stream; var util = require('util'); @@ -11,25 +10,27 @@ var binding = require('../build/Release/syslog'); -///--- Globals +// --- Globals var sprintf = util.format; var HOSTNAME = os.hostname(); -// Harcoded from https://github.com/trentm/node-bunyan so this module -// can have minimal dependencies +/* + * Harcoded from https://github.com/trentm/node-bunyan so this module + * can have minimal dependencies. + */ var bunyan = { FATAL: 60, ERROR: 50, - WARN: 40, - INFO: 30, + WARN: 40, + INFO: 30, DEBUG: 20, TRACE: 10, safeCycles: function safeCycles() { var seen = []; - function bunyanCycles(k, v) { + function bunyanCycles(_, v) { if (!v || typeof (v) !== 'object') { return (v); } @@ -45,7 +46,8 @@ var bunyan = { }; -// Syslog Levels +/* Syslog Levels */ +/* eslint-disable */ var LOG_EMERG = 0; var LOG_ALERT = 1; var LOG_CRIT = 2; @@ -54,9 +56,10 @@ var LOG_WARNING = 4; var LOG_NOTICE = 5; var LOG_INFO = 6; var LOG_DEBUG = 7; +/* eslint-enable */ -///--- Helpers +// --- Helpers // Translates a Bunyan level into a syslog level function level(l) { @@ -94,7 +97,7 @@ function time(t) { -///--- API +// --- API function SyslogStream(opts) { assert.object(opts, 'options'); @@ -129,8 +132,9 @@ SyslogStream.prototype.destroy = function destroy() { SyslogStream.prototype.end = function end() { - if (arguments.length > 0) + if (arguments.length > 0) { this.write.apply(this, Array.prototype.slice.call(arguments)); + } this.writable = false; this.close(); @@ -138,8 +142,9 @@ SyslogStream.prototype.end = function end() { SyslogStream.prototype.write = function write(r) { - if (!this.writable) + if (!this.writable) { throw new Error('SyslogStream has been ended already'); + } var h; var l; @@ -178,10 +183,12 @@ SyslogStream.prototype.write = function write(r) { SyslogStream.prototype.toString = function toString() { var str = '[object SyslogStream=0.10.0" diff --git a/test/rsyslog.conf b/test/rsyslog.conf new file mode 100644 index 0000000..434587d --- /dev/null +++ b/test/rsyslog.conf @@ -0,0 +1,10 @@ +module(load="imudp") +input(type="imudp" address="127.0.0.1" port="10514") + +module(load="imtcp") +input(type="imtcp" address="127.0.0.1" port="10514") + +template(name="bunyan" type="string" + string="%msg:R,ERE,1,FIELD:(\\{.*\\})--end%\n") + +local0.* /tmp/application.log;bunyan diff --git a/test/run.js b/test/run.js new file mode 100644 index 0000000..7617247 --- /dev/null +++ b/test/run.js @@ -0,0 +1,15 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * Copyright (c) 2018, Joyent, Inc. + */ + +// --- Run All Tests + +require('./sys.test.js'); +require('./tcp.test.js'); +require('./udp.test.js'); diff --git a/test/sys.test.js b/test/sys.test.js index b0d469e..a4713b3 100644 --- a/test/sys.test.js +++ b/test/sys.test.js @@ -1,13 +1,16 @@ -// Copyright 2013 Mark Cavage, Inc. All rights reserved. +/* + * Copyright 2013 Mark Cavage, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. + */ var bunyan = require('bunyan'); -var test = require('tap').test; +var test = require('tape'); var bsyslog = require('../lib'); -///--- Globals +// --- Globals var I = 0; var LOG; @@ -15,7 +18,7 @@ var STREAM; -///--- Tests +// --- Tests test('create a logger', function (t) { STREAM = bsyslog.createBunyanStream({ @@ -24,7 +27,7 @@ test('create a logger', function (t) { type: 'sys' }); t.ok(STREAM); - console.error(STREAM.toString()); + t.equal(typeof (STREAM.toString()), 'string'); LOG = bunyan.createLogger({ name: 'systest', diff --git a/test/tcp.test.js b/test/tcp.test.js index 5f74fb5..22a33c8 100644 --- a/test/tcp.test.js +++ b/test/tcp.test.js @@ -1,13 +1,16 @@ -// Copyright 2013 Mark Cavage, Inc. All rights reserved. +/* + * Copyright 2013 Mark Cavage, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. + */ var bunyan = require('bunyan'); -var test = require('tap').test; +var test = require('tape'); var bsyslog = require('../lib'); -///--- Globals +// --- Globals var I = 0; var LOG; @@ -15,7 +18,7 @@ var STREAM; -///--- Tests +// --- Tests test('create a logger', function (t) { STREAM = bsyslog.createBunyanStream({ @@ -25,6 +28,7 @@ test('create a logger', function (t) { type: 'tcp' }); t.ok(STREAM); + t.equal(typeof (STREAM.toString()), 'string'); LOG = bunyan.createLogger({ name: 'tcptest', @@ -78,4 +82,4 @@ test('write a fatal record', function (t) { test('teardown', function (t) { STREAM.close(); t.end(); -}); \ No newline at end of file +}); diff --git a/test/udp.test.js b/test/udp.test.js index 72686a6..5c145a1 100644 --- a/test/udp.test.js +++ b/test/udp.test.js @@ -1,13 +1,16 @@ -// Copyright 2013 Mark Cavage, Inc. All rights reserved. +/* + * Copyright 2013 Mark Cavage, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. + */ var bunyan = require('bunyan'); -var test = require('tap').test; +var test = require('tape'); var bsyslog = require('../lib'); -///--- Globals +// --- Globals var I = 0; var LOG; @@ -15,16 +18,16 @@ var STREAM; -///--- Tests +// --- Tests test('create a logger', function (t) { STREAM = bsyslog.createBunyanStream({ host: process.env.LOG_HOST, - port: parseInt(process.env.LOG_PORT || 514, 10), + port: parseInt(process.env.LOG_PORT || 10514, 10), facility: bsyslog.facility.local0 }); t.ok(STREAM); - console.error(STREAM.toString()); + t.equal(typeof (STREAM.toString()), 'string'); LOG = bunyan.createLogger({ name: 'udptest', @@ -78,4 +81,4 @@ test('write a fatal record', function (t) { test('teardown', function (t) { STREAM.close(); t.end(); -}); \ No newline at end of file +}); diff --git a/tools/mk/Makefile.defs b/tools/mk/Makefile.defs index 50a13c5..73dd612 100644 --- a/tools/mk/Makefile.defs +++ b/tools/mk/Makefile.defs @@ -1,6 +1,13 @@ -# -*- mode: makefile -*- # -# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# +# Copyright (c) 2018, Joyent, Inc. +# + # # Makefile.defs: common defines. # @@ -20,6 +27,14 @@ # the TIMESTAMP envvar (used by MG-based builds). # STAMP A build stamp to use in built package names. # +# MAKE_STAMPS_DIR The directory in which make stamp files are to be +# created. See comments below on expensive targets. +# +# CACHE_DIR A directory tree in which temporary files may be +# collected by download, tarball extraction, etc. This +# directory is completely removed by "make distclean". +# Files in this directory are not intended to be shipped. +# TOP := $(shell pwd) @@ -41,3 +56,50 @@ STAMP := $(BRANCH)-$(TIMESTAMP)-$(_GITDESCRIBE) # node-gyp will print build info useful for debugging with V=1 export V=1 + +CACHE_DIR ?= cache +DISTCLEAN_FILES += $(CACHE_DIR) + +# +# EXPENSIVE TARGETS AND MAKE STAMP FILES +# +# Targets which are expensive to run and lack a single file that marks +# completion are difficult to track with make; e.g., "npm install". One +# solution to this problem is to create "stamp" files with symbolic names which +# are created as the final step in a complex make rule in order to mark +# completion. +# +# In order to make these more uniform, and easier to target with "make clean", +# we will attempt to store them under a single directory. Note that these +# files are never targets for shipping in build artefacts. +# +# Stamp-backed targets come in several parts. First, a macro should be defined +# which names a file in the MAKE_STAMPS_DIR directory. Then, a target which +# creates this stamp file must be provided. The recipe for this target should +# use MAKE_STAMP_REMOVE and MAKE_STAMP_CREATE to perform the appropriate stamp +# management. +# +# For example: +# +# --- Makefile.*.defs: +# +# $(STAMP_EXPENSIVE_RESULT) := $(MAKE_STAMPS_DIR)/expensive-result +# +# --- Makefile.*.targ: +# +# $(STAMP_EXPENSIVE_RESULT): input/file another/input/file +# $(MAKE_STAMP_REMOVE) +# rm -rf output_tree/ # <--- ensure a clean slate +# expensive_program -o output_tree/ $^ +# $(MAKE_STAMP_CREATE) +# +# NOTE: Every stamp file is exposed as an implicit "stamp-$STAMP_NAME" target. +# The example above could be built manually by invoking: +# +# make stamp-expensive-result +# +MAKE_STAMPS_DIR ?= make_stamps +CLEAN_FILES += $(MAKE_STAMPS_DIR) + +MAKE_STAMP_REMOVE = mkdir -p $(@D); rm -f $(@) +MAKE_STAMP_CREATE = mkdir -p $(@D); touch $(@) diff --git a/tools/mk/Makefile.deps b/tools/mk/Makefile.deps index eeae27f..91f8346 100644 --- a/tools/mk/Makefile.deps +++ b/tools/mk/Makefile.deps @@ -1,6 +1,14 @@ # -*- mode: makefile -*- # -# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# +# Copyright (c) 2017, Joyent, Inc. +# + # # Makefile.deps: Makefile for including common tools as dependencies # @@ -36,9 +44,44 @@ JSSTYLE ?= $(JSSTYLE_EXEC) $(JSSTYLE_EXEC): | deps/jsstyle/.git +# +# eslint +# +ESLINT_EXEC ?= node_modules/.bin/eslint +ifdef NODE + ESLINT := $(NODE) $(ESLINT_EXEC) +else + ESLINT ?= $(ESLINT_EXEC) +endif + +# Install eslint. +# +# The install of specific modules is to allow running "make check" +# without having to do a complete install of all npm dependencies. +# +# NPM_EXEC will be defined if either of "Makefile.{node,node_prebuilt}.defs" +# is included. +ifdef NPM +$(ESLINT_EXEC): package.json | $(NPM_EXEC) + ESLINT_VER=$$($(NODE) -e 'console.log(require("./package.json").devDependencies["eslint"] || "")') && \ + ESLINT_JOY_VER=$$($(NODE) -e 'console.log(require("./package.json").devDependencies["eslint-plugin-joyent"] || "")') && \ + [[ -n $$ESLINT_VER && -n $$ESLINT_JOY_VER ]] && \ + $(NPM) install --no-save eslint@$$ESLINT_VER eslint-plugin-joyent@$$ESLINT_JOY_VER && \ + touch $(ESLINT_EXEC) +else +$(ESLINT_EXEC): package.json + ESLINT_VER=$$(node -e 'console.log(require("./package.json").devDependencies["eslint"] || "")') && \ + ESLINT_JOY_VER=$$(node -e 'console.log(require("./package.json").devDependencies["eslint-plugin-joyent"] || "")') && \ + [[ -n $$ESLINT_VER && -n $$ESLINT_JOY_VER ]] && \ + npm install --no-save eslint@$$ESLINT_VER eslint-plugin-joyent@$$ESLINT_JOY_VER && \ + touch $(ESLINT_EXEC) +endif + # # restdown # RESTDOWN_EXEC ?= deps/restdown/bin/restdown RESTDOWN ?= python $(RESTDOWN_EXEC) $(RESTDOWN_EXEC): | deps/restdown/.git + +EXTRA_DOC_DEPS ?= diff --git a/tools/mk/Makefile.node.defs b/tools/mk/Makefile.node.defs new file mode 100644 index 0000000..487824d --- /dev/null +++ b/tools/mk/Makefile.node.defs @@ -0,0 +1,110 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# +# Copyright (c) 2017, Joyent, Inc. +# + +# +# Makefile.node.defs: Makefile for building and bundling your own Node.js. +# +# NOTE: This makefile comes from the "eng" repo. It's designed to be dropped +# into other repos as-is without requiring any modifications. If you find +# yourself changing this file, you should instead update the original copy in +# eng.git and then update your repo to use the new version. +# + +# +# This Makefile facilitates building and bundling your own copy of Node.js in +# your repo. All it does is define variables for node, node-waf, and npm for +# you to use elsewhere in your Makefile and rules to build these tools when +# needed. +# +# To use this facility, include "Makefile.node.defs", use the variables as +# described below to define targets, and then include "Makefile.node.targ". +# +# There are two use cases addressed here: +# +# (1) Invoking node, node-waf, or npm as part of the build process, as in "npm +# install" and "node-waf configure build". To facilitate this, this +# Makefile defines Make variables NODE, NODE_WAF, and NPM that you can use +# to invoke these commands during the build process. You MUST NOT assume +# that these variables just evaluate to the filenames themselves, as they +# may have environment variable definitions and other things that prevent +# you from using them directly as a filename. If you want that, see (2). +# +# Wherever you use one of these variables, you MUST include a dependency on +# the corresponding *_EXEC variable as well, like so: +# +# node_modules/restify: deps/restify $(NPM_EXEC) +# $(NPM) install deps/restify +# +# or better, use an order-only dependency to avoid spurious rebuilds: +# +# node_modules/restify: deps/restify | $(NPM_EXEC) +# $(NPM) install deps/restify +# +# Otherwise, the underlying file will not get built. We don't +# automatically build them as part of "all" because that approach is +# brittle. +# +# (2) Specifying paths for invoking node, node-waf, or npm at RUNTIME, as in +# specifying the path to node used for the start method of your service's +# SMF manifest. For this, this Makefile defines variables NODE_EXEC, +# NODE_WAF_EXEC, and NPM_EXEC, which represent the relative paths of these +# files from the root of the workspace. You MUST NOT use these variables +# to invoke these commands during the build process. See (1) instead. +# +# However, in order to work at runtime, you must build the tool as well. +# That is, if you use NODE_EXEC to specify the path to node, you must +# depend on NODE_EXEC somewhere. This usually happens anyway because you +# usually need them during the build process too, but if you don't then +# you need to explicitly add NODE_EXEC (or whichever) to your "all" +# target. +# +# When including this Makefile, you MAY also specify: +# +# BUILD top-level directory for built binaries +# (default: "build") +# +# NODE_INSTALL where node should install its built items +# (default: "$BUILD/node") +# +# NODE_CONFIG_FLAGS extra flags to pass to Node's "configure" +# (default: "--with-dtrace" on SmartOS; empty +# otherwise.) +# + +TOP ?= $(error You must include Makefile.defs before this makefile) + +BUILD ?= build +NODE_INSTALL ?= $(BUILD)/node +DISTCLEAN_FILES += $(NODE_INSTALL) + +NODE_CONFIG_FLAGS += --prefix=$(TOP)/$(NODE_INSTALL) + +ifeq ($(shell uname -s),SunOS) + NODE_CONFIG_FLAGS += --with-dtrace \ + --openssl-libpath=/opt/local/lib \ + --openssl-includes=/opt/local/include +endif + +NODE_EXEC = $(NODE_INSTALL)/bin/node +NODE_WAF_EXEC = $(NODE_INSTALL)/bin/node-waf +NPM_EXEC = $(NODE_INSTALL)/bin/npm + +# +# These paths should be used during the build process to invoke Node and +# Node-related build tools like NPM. All paths are fully qualified so that +# they work regardless of the current working directory at the point of +# invocation. +# +# Note that where PATH is overridden, the value chosen must cause execution of +# "node" to find the same binary to which the NODE macro refers. +# +NODE := $(TOP)/$(NODE_EXEC) +NODE_WAF := $(TOP)/$(NODE_WAF_EXEC) +NPM := PATH=$(TOP)/$(NODE_INSTALL)/bin:$(PATH) $(NODE) $(TOP)/$(NPM_EXEC) diff --git a/tools/mk/Makefile.node.targ b/tools/mk/Makefile.node.targ new file mode 100644 index 0000000..bf53f78 --- /dev/null +++ b/tools/mk/Makefile.node.targ @@ -0,0 +1,42 @@ +# -*- mode: makefile -*- +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# +# Copyright (c) 2014, Joyent, Inc. +# + +# +# Makefile.node.targ: See Makefile.node.defs. +# +# NOTE: This makefile comes from the "eng" repo. It's designed to be dropped +# into other repos as-is without requiring any modifications. If you find +# yourself changing this file, you should instead update the original copy in +# eng.git and then update your repo to use the new version. +# + +ifneq ($(shell uname -s),SunOS) +NODE_PREBUILT_VERSION ?= $(error You must define NODE_PREBUILT_VERSION to use Makefile.node.targ on non-SunOS) +endif + +ifeq ($(shell uname -s),SunOS) +$(NODE_EXEC) $(NPM_EXEC) $(NODE_WAF_EXEC): | deps/node/.git + (cd deps/node; ./configure $(NODE_CONFIG_FLAGS) && $(MAKE) && $(MAKE) install) +else +$(NODE_EXEC) $(NPM_EXEC) $(NODE_WAF_EXEC): + (mkdir -p $(BUILD) \ + && cd $(BUILD) \ + && [[ -d src-node ]] && (cd src-node && git checkout master && git pull) || git clone https://github.com/joyent/node.git src-node \ + && cd src-node \ + && git checkout $(NODE_PREBUILT_VERSION) \ + && ./configure $(NODE_CONFIG_FLAGS) \ + && $(MAKE) && $(MAKE) install) +endif + +DISTCLEAN_FILES += $(NODE_INSTALL) $(BUILD)/src-node + +distclean:: + -([[ ! -d deps/node ]] || (cd deps/node && $(MAKE) distclean)) diff --git a/tools/mk/Makefile.node_deps.defs b/tools/mk/Makefile.node_deps.defs index dc11cd0..29a83f7 100644 --- a/tools/mk/Makefile.node_deps.defs +++ b/tools/mk/Makefile.node_deps.defs @@ -1,6 +1,14 @@ # -*- mode: makefile -*- # -# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# +# Copyright (c) 2014, Joyent, Inc. +# + # # Makefile.node_deps.defs: Makefile for including npm modules whose sources # reside inside the repo. This should NOT be used for modules in the npm diff --git a/tools/mk/Makefile.node_deps.targ b/tools/mk/Makefile.node_deps.targ index 603c87c..bb2ab4f 100644 --- a/tools/mk/Makefile.node_deps.targ +++ b/tools/mk/Makefile.node_deps.targ @@ -1,6 +1,14 @@ # -*- mode: makefile -*- # -# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# +# Copyright (c) 2014, Joyent, Inc. +# + # # Makefile.node_deps.targ: targets for Makefile.node_deps.defs. # diff --git a/tools/mk/Makefile.node_prebuilt.defs b/tools/mk/Makefile.node_prebuilt.defs new file mode 100644 index 0000000..2129742 --- /dev/null +++ b/tools/mk/Makefile.node_prebuilt.defs @@ -0,0 +1,159 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# +# Copyright (c) 2017, Joyent, Inc. +# + +# +# Makefile.node_prebuilt.defs: Makefile for including a prebuilt Node.js build. +# +# NOTE: This makefile comes from the "eng" repo. It's designed to be dropped +# into other repos as-is without requiring any modifications. If you find +# yourself changing this file, you should instead update the original copy in +# eng.git and then update your repo to use the new version. +# + +# +# This Makefile facilitates downloading and bundling a prebuilt node.js +# build (using the 'sdcnode' distro builds). This is an alternative to +# the "Makefile.node.*" makefiles for *building* a node from source. +# +# Usage: +# +# - Define `NODE_PREBUILT_VERSION` in your Makefile to choose a node version. +# E.g.: `NODE_PREBUILT_VERSION=v0.6.19`. See other optional variables +# below. +# - `include tools/mk/Makefile.node_prebuilt.defs` after this in your Makefile. +# - `include tools/mk/Makefile.node_prebuilt.targ` near the end of your +# Makefile. +# - Have at least one of your Makefile targets depend on either `$(NODE_EXEC)` +# or `$(NPM_EXEC)`. E.g.: +# +# node_modules/restify: deps/restify $(NPM_EXEC) +# $(NPM) install deps/restify +# +# or better, use an order-only dependency to avoid spurious rebuilds: +# +# node_modules/restify: deps/restify | $(NPM_EXEC) +# $(NPM) install deps/restify +# +# - Use `$(NPM)` or `$(NODE)` to use your node build. +# - Include the "$(NODE_INSTALL)" tree in your release package. +# +# +# When including this Makefile, you MUST also specify: +# +# NODE_PREBUILT_VERSION The node version in the prebuilt 'sdcnode' +# package to use. Typically this is one of the +# node version tags, e.g. "v0.6.18" but it +# can be any commitish. +# +# When including this Makefile, you MAY also specify: +# +# NODE_PREBUILT_DIR The dir in which to find sdcnode builds. This +# can either be a *local directory* or *a +# URL* dir (with trailing '/') which serves +# Apache/Nginx dir listing HTML. +# (default: sdcnode master build dir on stuff) +# +# NODE_PREBUILT_TAG The 'sdcnode' project supports special +# configuration builds of node, e.g. say a +# build configured `--without-ssl`. These +# special configurations are given a tag, e.g. +# 'gz', that is used in the filename. Optionally +# specify a tag name here. +# (default: empty) +# +# NODE_PREBUILT_BRANCH Specify a particular branch of 'sdcnode' builds +# from which to pull. Generally one should stick +# with the default. +# (default: master) +# +# NODE_PREBUILT_IMAGE If you have a zone image that differs from that +# for an sdcnode build that you want to use (potential compat +# issues be damned), then set this to the UUID of the sdcnode +# build you want. See here for available build image uuids: +# +# +# BUILD top-level directory for built binaries +# (default: "build") +# +# NODE_INSTALL where node should install its built items +# (default: "$BUILD/node") +# +# +# Dev Notes: +# +# This works by getting "NODE_PREBUILT_NAME" from the provided "NODE_PREBUILT_*" +# vars and the image version (via 'mdata-get sdc:image_uuid'). The image uuid is +# included to ensure an exact match with the build machine. This name (e.g. +# "v0.6.18-zone-$uuid") is used to find a matching "sdcnode-$name-*.tgz" build +# in "NODE_PREBUILT_DIR" (either a local directory or a URL). That tarball is +# downloaded and extracted into "NODE_INSTALL". +# +# The "*_EXEC" vars are set to named symlinks, e.g. +# "build/prebuilt-node-v0.6.18-$uuid", so that a change of selected node +# build (say the developer changes NODE_PREBUILT_VERSION) will recreate the +# node install. +# +# See for details on 'sdcnode-*' +# package naming. +# + +TOP ?= $(error You must include Makefile.defs before this makefile) +NODE_PREBUILT_VERSION ?= $(error NODE_PREBUILT_VERSION is not set.) + + +BUILD ?= build +NODE_INSTALL ?= $(BUILD)/node +DISTCLEAN_FILES += $(NODE_INSTALL) \ + $(BUILD)/prebuilt-node-* $(BUILD)/prebuilt-npm-* + +NODE_PREBUILT_BRANCH ?= master +NODE_PREBUILT_IMAGE ?= $(shell pfexec mdata-get sdc:image_uuid) +ifeq ($(NODE_PREBUILT_TAG),) + NODE_PREBUILT_NAME := $(NODE_PREBUILT_VERSION)-$(NODE_PREBUILT_IMAGE) +else + NODE_PREBUILT_NAME := $(NODE_PREBUILT_VERSION)-$(NODE_PREBUILT_TAG)-$(NODE_PREBUILT_IMAGE) +endif +NODE_PREBUILT_PATTERN := sdcnode-$(NODE_PREBUILT_NAME)-$(NODE_PREBUILT_BRANCH)-.*\.tgz +NODE_PREBUILT_DIR ?= https://download.joyent.com/pub/build/sdcnode/$(NODE_PREBUILT_IMAGE)/$(NODE_PREBUILT_BRANCH)-latest/sdcnode/ +ifeq ($(shell echo $(NODE_PREBUILT_DIR) | cut -c 1-4),http) + NODE_PREBUILT_BASE := $(shell curl -ksS --fail --connect-timeout 30 $(NODE_PREBUILT_DIR) | grep 'href=' | cut -d'"' -f2 | grep "^$(NODE_PREBUILT_PATTERN)$$" | sort | tail -1) + ifneq ($(NODE_PREBUILT_BASE),) + NODE_PREBUILT_TARBALL := $(NODE_PREBUILT_DIR)$(NODE_PREBUILT_BASE) + endif +else + NODE_PREBUILT_BASE := $(shell ls -1 $(NODE_PREBUILT_DIR)/ | grep "^$(NODE_PREBUILT_PATTERN)$$" 2>/dev/null | sort | tail -1) + ifneq ($(NODE_PREBUILT_BASE),) + NODE_PREBUILT_TARBALL := $(NODE_PREBUILT_DIR)/$(NODE_PREBUILT_BASE) + endif +endif +ifeq ($(NODE_PREBUILT_TARBALL),) + NODE_PREBUILT_TARBALL = $(error NODE_PREBUILT_TARBALL is empty: no '$(NODE_PREBUILT_DIR)/$(NODE_PREBUILT_PATTERN)' found) +endif + + +# Prebuild-specific paths for the "*_EXEC" vars to ensure that +# a prebuild change (e.g. if master Makefile's NODE_PREBUILT_VERSION +# choice changes) causes a install of the new node. +NODE_EXEC := $(BUILD)/prebuilt-node-$(NODE_PREBUILT_NAME) +NODE_WAF_EXEC := $(BUILD)/prebuilt-node-waf-$(NODE_PREBUILT_NAME) +NPM_EXEC := $(BUILD)/prebuilt-npm-$(NODE_PREBUILT_NAME) + +# +# These paths should be used during the build process to invoke Node and +# Node-related build tools like NPM. All paths are fully qualified so that +# they work regardless of the current working directory at the point of +# invocation. +# +# Note that where PATH is overridden, the value chosen must cause execution of +# "node" to find the same binary to which the NODE macro refers. +# +NODE := $(TOP)/$(NODE_INSTALL)/bin/node +NODE_WAF := $(TOP)/$(NODE_INSTALL)/bin/node-waf +NPM := PATH=$(TOP)/$(NODE_INSTALL)/bin:$(PATH) $(NODE) $(TOP)/$(NODE_INSTALL)/bin/npm diff --git a/tools/mk/Makefile.node_prebuilt.targ b/tools/mk/Makefile.node_prebuilt.targ new file mode 100644 index 0000000..6877333 --- /dev/null +++ b/tools/mk/Makefile.node_prebuilt.targ @@ -0,0 +1,42 @@ +# -*- mode: makefile -*- +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# +# Copyright (c) 2014, Joyent, Inc. +# + +# +# Makefile.node_prebuilt.targ: Makefile for including a prebuilt Node.js +# build. +# +# NOTE: This makefile comes from the "eng" repo. It's designed to be dropped +# into other repos as-is without requiring any modifications. If you find +# yourself changing this file, you should instead update the original copy in +# eng.git and then update your repo to use the new version. + + +NODE_PREBUILT_TARBALL ?= $(error NODE_PREBUILT_TARBALL is not set: was Makefile.node_prebuilt.defs included?) + + +# TODO: remove this limitation +# Limitation: currently presuming that the NODE_INSTALL basename is +# 'node' and that sdcnode tarballs have a 'node' top-level dir. +$(NODE_EXEC) $(NPM_EXEC) $(NODE_WAF_EXEC): + [[ $(shell basename $(NODE_INSTALL)) == "node" ]] \ + || (echo "Limitation: 'basename NODE_INSTALL' is not 'node'" && exit 1) + rm -rf $(NODE_INSTALL) \ + $(BUILD)/prebuilt-node-* $(BUILD)/prebuilt-npm-* + mkdir -p $(shell dirname $(NODE_INSTALL)) + if [[ $(shell echo $(NODE_PREBUILT_TARBALL) | cut -c 1-4) == "http" ]]; then \ + echo "Downloading '$(NODE_PREBUILT_BASE)'."; \ + curl -ksS --fail --connect-timeout 30 -o $(shell dirname $(NODE_INSTALL))/$(NODE_PREBUILT_BASE) $(NODE_PREBUILT_TARBALL); \ + (cd $(shell dirname $(NODE_INSTALL)) && $(TAR) xf $(NODE_PREBUILT_BASE)); \ + else \ + (cd $(shell dirname $(NODE_INSTALL)) && $(TAR) xf $(NODE_PREBUILT_TARBALL)); \ + fi + ln -s $(TOP)/$(NODE_INSTALL)/bin/node $(NODE_EXEC) + ln -s $(TOP)/$(NODE_INSTALL)/bin/npm $(NPM_EXEC) diff --git a/tools/mk/Makefile.targ b/tools/mk/Makefile.targ index 22c9bef..8ae89c2 100644 --- a/tools/mk/Makefile.targ +++ b/tools/mk/Makefile.targ @@ -1,6 +1,13 @@ -# -*- mode: makefile -*- # -# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# +# Copyright (c) 2017, Joyent, Inc. +# + # # Makefile.targ: common targets. # @@ -58,37 +65,57 @@ # JSL_FILES_NODE JavaScript files to check with Node config file. # JSL_FILES_WEB JavaScript files to check with Web config file. # +# JSON_FILES JSON files to be validated +# +# JSSTYLE_FILES JavaScript files to be style-checked +# # You can also override these variables: # -# BASH Path to bash (default: bash) +# BASH Path to bash (default: "bash") +# +# BUILD top-level directory for node binaries, generated docs, +# and any other build output (default: "build") # # CSCOPE_DIRS Directories to search for source files for the cscope # index. (default: ".") # +# ESLINT Path to eslint (default: "eslint") +# +# ESLINT_FLAGS Additional flags to pass through to eslint +# # JSL Path to JavaScriptLint (default: "jsl") # # JSL_FLAGS_NODE Additional flags to pass through to JSL # JSL_FLAGS_WEB # JSL_FLAGS # -# JSSTYLE Path to jsstyle (default: jsstyle) +# JSON Path to json tool (default: "json") +# +# JSSTYLE Path to jsstyle (default: "jsstyle") # # JSSTYLE_FLAGS Additional flags to pass through to jsstyle # +# RESTDOWN_EXT By default '.md' is required for DOC_FILES (see above). +# If you want to use, say, '.restdown' instead, then set +# 'RESTDOWN_EXT=.restdown' in your Makefile. +# # # Defaults for the various tools we use. # BASH ?= bash -BASHSTYLE ?= tools/bashstyle +BASHSTYLE ?= $(NODE) tools/bashstyle CP ?= cp CSCOPE ?= cscope CSCOPE_DIRS ?= . +ESLINT ?= eslint JSL ?= jsl +JSON ?= json JSSTYLE ?= jsstyle MKDIR ?= mkdir -p MV ?= mv RESTDOWN_FLAGS ?= +RESTDOWN_EXT ?= .md RMTREE ?= rm -rf JSL_FLAGS ?= --nologo --nosummary @@ -102,7 +129,7 @@ endif # # Defaults for other fixed values. # -BUILD = build +BUILD ?= build DISTCLEAN_FILES += $(BUILD) DOC_BUILD = $(BUILD)/docs/public @@ -157,6 +184,12 @@ check-bash: $(BASH_FILES:%=%.bashchk) $(BASH_FILES:%=%.bashstyle) %.bashstyle: % $(BASHSTYLE) $^ +.PHONY: check-json +check-json: $(JSON_FILES:%=%.jsonchk) + +%.jsonchk: % + $(JSON) --validate -f $^ + # # The above approach can be slow when there are many files to check because it # requires that "make" invoke the check tool once for each file, rather than @@ -164,6 +197,12 @@ check-bash: $(BASH_FILES:%=%.bashchk) $(BASH_FILES:%=%.bashstyle) # a variable for the target itself *only if* the list of input files is # non-empty. This avoids invoking the tool if there are no files to check. # + +ESLINT_TARGET = $(if $(ESLINT_FILES), check-eslint) +.PHONY: check-eslint +check-eslint: $(ESLINT_EXEC) + $(ESLINT) $(ESLINT_FLAGS) $(ESLINT_FILES) + JSL_NODE_TARGET = $(if $(JSL_FILES_NODE), check-jsl-node) .PHONY: check-jsl-node check-jsl-node: $(JSL_EXEC) @@ -183,7 +222,7 @@ check-jsstyle: $(JSSTYLE_EXEC) $(JSSTYLE) $(JSSTYLE_FLAGS) $(JSSTYLE_FILES) .PHONY: check -check: check-jsl $(JSSTYLE_TARGET) check-bash +check:: $(ESLINT_TARGET) check-jsl check-json $(JSSTYLE_TARGET) check-bash @echo check ok .PHONY: clean @@ -238,26 +277,26 @@ DOC_MEDIA_FILES_BUILD := $(DOC_MEDIA_FILES:%=$(DOC_BUILD)/media/%) # to get there. # .PHONY: docs -docs: \ - $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.html) \ - $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.json) \ - $(DOC_MEDIA_FILES_BUILD) +docs:: \ + $(DOC_FILES:%$(RESTDOWN_EXT)=$(DOC_BUILD)/%.html) \ + $(DOC_FILES:%$(RESTDOWN_EXT)=$(DOC_BUILD)/%.json) \ + $(DOC_MEDIA_FILES_BUILD) # # We keep the intermediate files so that the next build can see whether the # files in DOC_BUILD are up to date. # .PRECIOUS: \ - $(DOC_FILES:%.restdown=docs/%.html) \ - $(DOC_FILES:%.restdown=docs/%json) + $(DOC_FILES:%$(RESTDOWN_EXT)=docs/%.html) \ + $(DOC_FILES:%$(RESTDOWN_EXT)=docs/%json) # # We do clean those intermediate files, as well as all of DOC_BUILD. # CLEAN_FILES += \ - $(DOC_BUILD) \ - $(DOC_FILES:%.restdown=docs/%.html) \ - $(DOC_FILES:%.restdown=docs/%.json) + $(DOC_BUILD) \ + $(DOC_FILES:%$(RESTDOWN_EXT)=docs/%.html) \ + $(DOC_FILES:%$(RESTDOWN_EXT)=docs/%.json) # # Before installing the files, we must make sure the directories exist. The | @@ -268,9 +307,11 @@ CLEAN_FILES += \ $(DOC_MEDIA_FILES_BUILD): | $(DOC_MEDIA_DIRS_BUILD) $(DOC_BUILD)/%: docs/% | $(DOC_BUILD) + $(MKDIR) $(shell dirname $@) $(CP) $< $@ -docs/%.json docs/%.html: docs/%.restdown | $(DOC_BUILD) $(RESTDOWN_EXEC) +docs/%.json docs/%.html: docs/%$(RESTDOWN_EXT) | $(DOC_BUILD) $(RESTDOWN_EXEC) \ + $(EXTRA_DOC_DEPS) $(RESTDOWN) $(RESTDOWN_FLAGS) -m $(DOC_BUILD) $< $(DOC_BUILD): @@ -289,3 +330,19 @@ test: .PHONY: prepush prepush: check test + +# +# This rule automatically exposes every "stamp" file as a target that can be +# invoked manually as "stamp-$STAMP_NAME". For example, if a stamp has been +# defined thus: +# +# STAMP_EXPENSIVE_RESULT := $(MAKE_STAMPS_DIR)/expensive-result +# +# ... this can be invoked manually as "make stamp-expensive-result". Note that +# these phony targets are essentially just for interactive usage. Targets +# should be specified to depend on the macro containing the stamp file name. +# +# See also the comments in "Makefile.defs". +# +stamp-%: $(MAKE_STAMPS_DIR)/% + @: