Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-sync with internal repository #80

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions lib/CodeGenerator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* @format
* strict-local
*/

'use strict';

// $FlowFixMe

var _minimist = require('minimist');

var _minimist2 = _interopRequireDefault(_minimist);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _Procedure = require('./common/Procedure');

var _Procedure2 = _interopRequireDefault(_Procedure);

var _Utils = require('./common/Utils');

var _Utils2 = _interopRequireDefault(_Utils);

var _SpecFileLoader = require('./loaders/SpecFileLoader');

var _SpecFileLoader2 = _interopRequireDefault(_SpecFileLoader);

var _AutoAddIdFieldForRootNodeProcessor = require('./processors/AutoAddIdFieldForRootNodeProcessor');

var _AutoAddIdFieldForRootNodeProcessor2 = _interopRequireDefault(_AutoAddIdFieldForRootNodeProcessor);

var _CreationEndpointHackProcessor = require('./processors/CreationEndpointHackProcessor');

var _CreationEndpointHackProcessor2 = _interopRequireDefault(_CreationEndpointHackProcessor);

var _FlaggingProcessor = require('./processors/FlaggingProcessor');

var _FlaggingProcessor2 = _interopRequireDefault(_FlaggingProcessor);

var _LanguageSpecificProcessor = require('./processors/LanguageSpecificProcessor');

var _LanguageSpecificProcessor2 = _interopRequireDefault(_LanguageSpecificProcessor);

var _NamingConventionProcessor = require('./processors/NamingConventionProcessor');

var _NamingConventionProcessor2 = _interopRequireDefault(_NamingConventionProcessor);

var _NodeEndpointHackProcessor = require('./processors/NodeEndpointHackProcessor');

var _NodeEndpointHackProcessor2 = _interopRequireDefault(_NodeEndpointHackProcessor);

var _NormalizationProcessor = require('./processors/NormalizationProcessor');

var _NormalizationProcessor2 = _interopRequireDefault(_NormalizationProcessor);

var _ReferenceProcessor = require('./processors/ReferenceProcessor');

var _ReferenceProcessor2 = _interopRequireDefault(_ReferenceProcessor);

var _SpecOverridingProcessor = require('./processors/SpecOverridingProcessor');

var _SpecOverridingProcessor2 = _interopRequireDefault(_SpecOverridingProcessor);

var _DebugJsonRenderer = require('./renderers/DebugJsonRenderer');

var _DebugJsonRenderer2 = _interopRequireDefault(_DebugJsonRenderer);

var _MustacheRenderer = require('./renderers/MustacheRenderer');

var _MustacheRenderer2 = _interopRequireDefault(_MustacheRenderer);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const procedure = new _Procedure2.default({
loader: _SpecFileLoader2.default,
processors: [_SpecOverridingProcessor2.default, _AutoAddIdFieldForRootNodeProcessor2.default, _NodeEndpointHackProcessor2.default, _NormalizationProcessor2.default, _FlaggingProcessor2.default, _CreationEndpointHackProcessor2.default, _NamingConventionProcessor2.default, _ReferenceProcessor2.default, _LanguageSpecificProcessor2.default],
renderers: [_MustacheRenderer2.default, _DebugJsonRenderer2.default]
});

const args = (0, _minimist2.default)(process.argv.slice(2));

const language = args._[0];
_Utils2.default.validateLanguage(language);

const version = args.v || _Utils2.default.loadDefaultVersion();
const sdk_version = _Utils2.default.loadDefaultSDKVersion(language);
const outputDir = args.o || _path2.default.resolve(__dirname, '../../', './sdk/servers/' + language + '/release');
const cleandir = args.c ? args.c.split(',') : [];

procedure.run(version, sdk_version, language, outputDir, cleandir);
53 changes: 53 additions & 0 deletions lib/common/Procedure.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* @format
* strict-local
*/

'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _types = require('./types');

class Procedure {

constructor(props) {
this.loader = props.loader;
this.processors = props.processors;
this.renderers = props.renderers;
}

run(version, sdk_version, language, outputDir, cleandir) {
const inputs = this.loader.load(version, sdk_version);

const metadata = inputs.metadata;
metadata.language = language;
metadata.version = version;
metadata.sdk_version = sdk_version;
metadata.outputDir = outputDir;
metadata.cleandir = cleandir;

let specs = inputs.specs;
this.processors.forEach(processor => {
specs = processor.process(specs, metadata);
});

this.renderers.forEach(renderer => {
renderer.render({
APISpecs: specs.api_specs,
SDKConfig: {
api_version: metadata.version,
sdk_version: metadata.sdk_version,
api_version_num_only: metadata.version.replace('v', ''),
version: metadata.versionedFeaturesWithDepreciation
}
}, metadata.language || '', metadata.version, metadata.outputDir || '', metadata.cleandir || []);
});
}
}

exports.default = Procedure;
69 changes: 69 additions & 0 deletions lib/common/Utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* @format
* strict
*/

'use strict';

var _fs = require('fs');

var _fs2 = _interopRequireDefault(_fs);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _version_path = require('../../api_specs/version_path.json');

var _version_path2 = _interopRequireDefault(_version_path);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const Utils = {
// special signature that can mark a codegen file should be removed.
codeGenFileDepreciationSign: '@remove_depreciated_file@' + new Date().getTime().toString(),

throwUsageError(message) {
console.log('Usage: codegen <language> [-v api_version] [-o output_path] [-c folder_to_cleanup]');
throw message;
},

validateLanguage(language) {
// @fb-only
'java', 'nodejs', 'php', 'python', 'ruby'];
if (!language) {
this.throwUsageError('language is not specified! available languages: ' + supportedLanguages.join(', '));
}

if (supportedLanguages.indexOf(language) < 0) {
this.throwUsageError('unsupported language: ' + language + '! available languages: ' + supportedLanguages.join(', '));
}
},

loadDefaultVersion() {
const fileName = 'api_specs/specs/version.txt';
const filePath = _path2.default.resolve(__dirname, '..', '..', fileName);
return _fs2.default.readFileSync(filePath, 'utf8').trim();
},

loadDefaultSDKVersion(language) {
const fileName = _version_path2.default[language]['base_path'] + '/' + _version_path2.default[language]['file_path'];
const filePath = _path2.default.resolve(__dirname, '..', '..', '..', fileName);
var array = _fs2.default.readFileSync(filePath, 'utf8').toString().split("\n");

for (let line of array) {
if (line.trim().startsWith(_version_path2.default[language]['line_starter'])) {
let match = line.match(/^.*?(\d+\.\d+\.\d+(\.\d+)?).*$/i);
if (match) {
return match[1];
}
}
}

throw 'Not able to find sdk version.';
}
};

module.exports = Utils;
8 changes: 8 additions & 0 deletions lib/common/types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* @format
*
*/

'use strict';
74 changes: 74 additions & 0 deletions lib/loaders/SpecFileLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* @format
* strict-local
*/

'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _Utils = require('./Utils');

var _Utils2 = _interopRequireDefault(_Utils);

var _versions = require('../../api_specs/versions.json');

var _versions2 = _interopRequireDefault(_versions);

var _Utils3 = require('../common/Utils');

var _Utils4 = _interopRequireDefault(_Utils3);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const SpecFileLoader = {
load(version, sdk_version) {
const APISpecDir = _path2.default.resolve(__dirname, '..', '..', 'api_specs');
const overriddenAPISpecName = 'SDKCodegen';
const overriddenAPISpecs = _Utils2.default.loadJSONFile(_path2.default.join(APISpecDir, overriddenAPISpecName + '.json'));

// Compute version features
const versionedFeatures = {};
const versionedFeaturesWithDepreciation = {};
const codeGenFileDepreciationSign = _Utils4.default.codeGenFileDepreciationSign;
for (const currentVersion in _versions2.default) {
if (_Utils2.default.versionCompare(currentVersion, version) <= 0) {
if (_versions2.default[currentVersion]) {
const currentVersions = _versions2.default[currentVersion];
currentVersions.forEach(feature => {
const hasFeatureName = 'has_' + feature;
versionedFeatures[hasFeatureName] = true;
versionedFeaturesWithDepreciation[hasFeatureName] = {
'@remove_file': codeGenFileDepreciationSign
};
});
}
}
}

// Load API specs
const loadedAPISpecs = _Utils2.default.loadSpecsFromFile(APISpecDir);

// merge versioned overridden API specs
return {
specs: loadedAPISpecs,
metadata: {
version: version,
sdk_version: sdk_version,
mergedOverriding: overriddenAPISpecs,
versionedFeatures: versionedFeatures,
versionedFeaturesWithDepreciation: versionedFeaturesWithDepreciation
}
};
}
};

exports.default = SpecFileLoader;
88 changes: 88 additions & 0 deletions lib/loaders/Utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* @format
* strict-local
*/

'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _fs = require('fs');

var _fs2 = _interopRequireDefault(_fs);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const Utils = {
loadJSONFile(fileName, keepComments = false) {
let content = _fs2.default.readFileSync(fileName, 'utf8');
if (!keepComments) {
content = content.replace(/^\/\/.*\n/gm, '');
}
try {
return JSON.parse(content);
} catch (e) {
console.error('Failed ot parse json ', fileName);
throw e;
}
},

loadSpecsFromFile(specDir) {
// Load API specs
const specs = {};
const enumMetadataMap = {};
const versionedSpecDir = _path2.default.join(specDir, 'specs');
_fs2.default.readdirSync(versionedSpecDir).forEach(file => {
const match = file.match(/^([a-z0-9_\-\.]+)\.json$/i);
if (match) {
const name = match[1];
/** @type {Array<{ values: { [x: string]: any }; name: string; }>} */
const json = this.loadJSONFile(_path2.default.join(versionedSpecDir, file));
if ('enum_types' === name) {
json.forEach(enumType => {
for (const i in enumType.values) {
if (enumType.values[i].trim) {
enumType.values[i] = enumType.values[i].trim();
}
}

enumMetadataMap[enumType.name] = enumType;
});
} else {
specs[name] = json;
}
}
});
return {
api_specs: specs,
enumMetadataMap: enumMetadataMap
};
},
versionCompare(verA, verB) {
if (verA.charAt(0) != 'v' || verB.charAt(0) != 'v') {
throw new Error('invalid version number');
}
const partsA = verA.substring(1).split('.');
const partsB = verB.substring(1).split('.');
for (let i = 0; i < Math.max(partsA.length, partsB.length); ++i) {
const numA = parseInt(partsA[i] || '-1');
const numB = parseInt(partsB[i] || '-1');
if (numA > numB) {
return 1;
} else if (numA < numB) {
return -1;
}
}
return 0;
}
};

exports.default = Utils;
Loading