Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit 7271b94

Browse files
Script to copy types from @opencensus/core (#26)
1 parent 5db95d7 commit 7271b94

2 files changed

Lines changed: 190 additions & 0 deletions

File tree

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
* Copyright 2019, OpenCensus Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* @fileoverview This script copies (and lightly patches) type definitions from
19+
* the @opencensus/core package. This allows sharing types with @opencensus/core
20+
* without directly depending on it as an NPM package, which is tricky because
21+
* @opencensus/core pulls in various Node-specific dependencies.
22+
*/
23+
24+
'use strict';
25+
26+
const fs = require('fs');
27+
const os = require('os');
28+
const path = require('path');
29+
const process = require('process');
30+
const util = require('util');
31+
32+
const exec = util.promisify(require('child_process').exec);
33+
const exists = util.promisify(fs.exists);
34+
const mkdtemp = util.promisify(fs.mkdtemp);
35+
const readFile = util.promisify(fs.readFile);
36+
const writeFile = util.promisify(fs.writeFile);
37+
38+
/** List of files in the @opencensus/core `src` folder to copy over. */
39+
const FILES_TO_COPY = [
40+
'common/types.ts',
41+
'exporters/types.ts',
42+
'metrics/export/types.ts',
43+
'stats/types.ts',
44+
'tags/tag-map.ts',
45+
'tags/types.ts',
46+
'tags/validation.ts',
47+
'trace/config/types.ts',
48+
'trace/instrumentation/types.ts',
49+
'trace/model/types.ts',
50+
'trace/propagation/types.ts',
51+
'trace/sampler/types.ts',
52+
'trace/types.ts',
53+
];
54+
55+
const OPENCENSUS_NODE_URL =
56+
'http://github.com/census-instrumentation/opencensus-node';
57+
58+
copyFiles().then(() => {}, (err) => {
59+
console.error(err);
60+
process.exit(1);
61+
});
62+
63+
async function copyFiles() {
64+
if (process.argv.length < 3) {
65+
throw new Error(
66+
'Must specify git tag of @opencensus/core copy types from.');
67+
}
68+
const openCensusNodeTag = process.argv[2];
69+
70+
console.log('Copying types from @opencensus/node package ...');
71+
72+
// Clone and checkout the @opencensus/core repo in a temp directory.
73+
const tempDir = await mkdtemp(path.join(os.tmpdir(), 'opencensus-core-'));
74+
console.log(`Cloning to temp directory: ${tempDir}`);
75+
await logAndExec(`git clone ${OPENCENSUS_NODE_URL}`, {cwd: tempDir});
76+
const srcDir =
77+
path.join(tempDir, 'opencensus-node/packages/opencensus-core/src');
78+
await logAndExec(`git checkout ${openCensusNodeTag}`, {cwd: srcDir});
79+
80+
console.log('Patching and copying type files ...');
81+
const destDir = path.join(__dirname, '../src');
82+
83+
for (const srcFile of FILES_TO_COPY) {
84+
console.log(`Processing ${srcFile} ...`);
85+
const srcPath = path.join(srcDir, srcFile);
86+
const destPath = path.join(destDir, srcFile);
87+
88+
if (!(await exists(srcPath))) {
89+
throw new Error(`Source file ${destPath} does not exist!`)
90+
}
91+
92+
const contents = await readFile(srcPath, {encoding: 'utf8'});
93+
const patchedContents = getPatchedContents(srcFile, contents);
94+
await exec(`mkdir -p ${path.dirname(destPath)}`);
95+
await writeFile(destPath, patchedContents);
96+
console.log(` Wrote ${destPath}`);
97+
}
98+
}
99+
100+
async function logAndExec(cmd, options) {
101+
console.log(cmd);
102+
return exec(cmd, options);
103+
}
104+
105+
function getPatchedContents(srcFile, contents) {
106+
contents = updateCopyright(srcFile, contents);
107+
contents = fixNodeJsEventEmitterType(srcFile, contents);
108+
return contents;
109+
}
110+
111+
function updateCopyright(srcFile, contents) {
112+
const curYear = new Date().getFullYear();
113+
const curYearCopyright = `Copyright ${curYear}`;
114+
if (contents.indexOf(curYearCopyright) > -1) {
115+
return contents;
116+
}
117+
console.log(` Updating copyright year for: ${srcFile}`);
118+
return contents.replace(/Copyright \d{4}/, curYearCopyright);
119+
}
120+
121+
/**
122+
* Replaces the `NodeJS.EventEmitter` type with a polyfilled
123+
* `NodeJsEventEmitter` type and includes an `import` line for it. This allows
124+
* removing the `@types/node` dependency to compile.
125+
*/
126+
function fixNodeJsEventEmitterType(srcFile, contents) {
127+
if (contents.indexOf('NodeJS.EventEmitter') === -1) {
128+
return contents;
129+
}
130+
131+
console.log(` Using NodeJS.EventEmitter polyfill type for: ${srcFile}`);
132+
133+
contents = contents.replace(/NodeJS.EventEmitter/g, 'NodeJsEventEmitter');
134+
const lines = contents.split('\n');
135+
let lastImportLine = lines.length - 1;
136+
while (lastImportLine > 0 && lines[lastImportLine].indexOf('import ') !== 0) {
137+
lastImportLine--;
138+
}
139+
140+
const srcDirDepth = srcFile.length - srcFile.replace(/\//g, '').length;
141+
const relativeSrcDir = '../'.repeat(srcDirDepth);
142+
143+
lines.splice(
144+
lastImportLine + 1, 0,
145+
`import {NodeJsEventEmitter} from '${relativeSrcDir}node/types';`);
146+
contents = lines.join('\n');
147+
return contents;
148+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright 2019, OpenCensus Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* NodeJS.EventEmitter type included here so that this package does not
19+
* need to take a dependency on the Node typings.
20+
* See:
21+
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/events.d.ts
22+
*/
23+
// tslint:disable:no-any Follows DefinintelyTyped `any` types.
24+
export interface NodeJsEventEmitter {
25+
addListener(event: string|symbol, listener: (...args: any[]) => void): this;
26+
on(event: string|symbol, listener: (...args: any[]) => void): this;
27+
once(event: string|symbol, listener: (...args: any[]) => void): this;
28+
removeListener(event: string|symbol, listener: (...args: any[]) => void):
29+
this;
30+
removeAllListeners(event?: string|symbol): this;
31+
setMaxListeners(n: number): this;
32+
getMaxListeners(): number;
33+
listeners(event: string|symbol): Function[];
34+
emit(event: string|symbol, ...args: any[]): boolean;
35+
listenerCount(type: string|symbol): number;
36+
// Added in Node 6...
37+
prependListener(event: string|symbol, listener: (...args: any[]) => void):
38+
this;
39+
prependOnceListener(event: string|symbol, listener: (...args: any[]) => void):
40+
this;
41+
eventNames(): Array<string|symbol>;
42+
}

0 commit comments

Comments
 (0)