const path = require("path"); const fse = require("fs-extra"); const os = require('os'); const exec = require('../../utils/execPromise'); const utils = require("./utils"); module.exports = function generateNativeCode() { const combyne = require("combyne"); const js_beautify = require("js-beautify").js_beautify; const beautify = function (input) { return js_beautify(input, { "brace_style": "end-expand", "max_preserve_newlines": 2, "preserve_newlines": true, "indent_size": 2, "indent_char": " " }); }; // Customize the delimiters so as to not process `{{{` or `}}}`. combyne.settings.delimiters = { START_RAW: "{{=", END_RAW: "=}}" }; var partials = { asyncFunction: utils.readLocalFile("templates/partials/async_function.cc"), callbackHelpers: utils.readLocalFile("templates/partials/callback_helpers.cc"), configurableCallbacks: utils.readLocalFile("templates/partials/configurable_callbacks.cc"), convertFromV8: utils.readLocalFile("templates/partials/convert_from_v8.cc"), convertToV8: utils.readLocalFile("templates/partials/convert_to_v8.cc"), doc: utils.readLocalFile("templates/partials/doc.cc"), fields: utils.readLocalFile("templates/partials/fields.cc"), guardArguments: utils.readLocalFile("templates/partials/guard_arguments.cc"), syncFunction: utils.readLocalFile("templates/partials/sync_function.cc"), fieldAccessors: utils.readLocalFile("templates/partials/field_accessors.cc"), traits: utils.readLocalFile("templates/partials/traits.h") }; var templates = { class_content: utils.readLocalFile("templates/templates/class_content.cc"), struct_content: utils.readLocalFile("templates/templates/struct_content.cc"), class_header: utils.readLocalFile("templates/templates/class_header.h"), struct_header: utils.readLocalFile("templates/templates/struct_header.h"), binding: utils.readLocalFile("templates/templates/binding.gyp"), nodegitCC: utils.readLocalFile("templates/templates/nodegit.cc"), nodegitJS: utils.readLocalFile("templates/templates/nodegit.js"), enums: utils.readLocalFile("templates/templates/enums.js") }; var filters = { and: require("../templates/filters/and"), argsInfo: require("../templates/filters/args_info"), arrayTypeToPlainType: require("../templates/filters/array_type_to_plain_type"), asElementPointer: require("../templates/filters/as_element_pointer"), callbackArgsInfo: require("../templates/filters/callback_args_info"), callbackArgsCount: require("../templates/filters/callback_args_count"), cppToV8: require("../templates/filters/cpp_to_v8"), defaultValue: require("../templates/filters/default_value"), fieldsInfo: require("../templates/filters/fields_info"), getCPPFunctionForRootProto: require("../templates/filters/get_cpp_function_for_root_proto"), hasFunctionOnRootProto: require("../templates/filters/has_function_on_root_proto"), hasReturnType: require("../templates/filters/has_return_type"), hasReturnValue: require("../templates/filters/has_return_value"), isArrayType: require("../templates/filters/is_array_type"), isDoublePointer: require("../templates/filters/is_double_pointer"), isFixedLengthString: require("../templates/filters/is_fixed_length_string"), isOid: require("../templates/filters/is_oid"), isPayload: require("../templates/filters/is_payload"), isPointer: require("../templates/filters/is_pointer"), isV8Value: require("../templates/filters/is_v8_value"), jsArgsCount: require("../templates/filters/js_args_count"), or: require("../templates/filters/or"), payloadFor: require("../templates/filters/payload_for"), replace: require("../templates/filters/replace"), returnsCount: require("../templates/filters/returns_count"), returnsInfo: require("../templates/filters/returns_info"), subtract: require("../templates/filters/subtract"), thisInfo: require("../templates/filters/this_info"), titleCase: require("../templates/filters/title_case"), toBool: require('../templates/filters/to_bool'), toSizeOfArray: require("../templates/filters/to_size_of_array"), unPointer: require("../templates/filters/un_pointer"), setUnsigned: require("../templates/filters/unsigned"), upper: require("../templates/filters/upper") }; // Convert Buffers to Combyne templates. Object.keys(templates).forEach(function(template) { templates[template] = combyne(templates[template]); // Attach all filters to all templates. Object.keys(filters).forEach(function(filter) { templates[template].registerFilter(filter, filters[filter]); }); }); // Attach all partials to select templates. Object.keys(partials).forEach(function(partial) { templates.class_header.registerPartial(partial, combyne(partials[partial])); templates.class_content.registerPartial(partial, combyne(partials[partial])); templates.struct_header.registerPartial(partial, combyne(partials[partial])); templates.struct_content.registerPartial(partial, combyne(partials[partial])); }); // Determine which definitions to actually include in the source code. // This might not be needed anymore but to be frank I'm not totally positive const idefs = require("../output/idefs"); var enabled = idefs.filter(function(idef) { return !idef.ignore; }); const tempDirPath = path.join(os.tmpdir(), 'nodegit_build'); const tempSrcDirPath = path.join(tempDirPath, "src"); const tempIncludeDirPath = path.join(tempDirPath, "include"); const finalSrcDirPath = path.join(__dirname, '../../src'); const finalIncludeDirPath = path.join(__dirname, '../../include'); fse.remove(tempDirPath).then(function() { return fse.copy(path.resolve(__dirname, "../templates/manual/include"), tempIncludeDirPath); }).then(function() { return fse.copy(path.resolve(__dirname, "../templates/manual/src"), tempSrcDirPath); }).then(function() { // Write out single purpose templates. utils.writeLocalFile("../binding.gyp", beautify(templates.binding.render(enabled)), "binding.gyp"); utils.writeFile(path.join(tempSrcDirPath, "nodegit.cc"), templates.nodegitCC.render(enabled), "nodegit.cc"); utils.writeLocalFile("../lib/nodegit.js", beautify(templates.nodegitJS.render(enabled)), "nodegit.js"); // Write out all the classes. enabled.forEach(function(idef) { if (idef.type && idef.type != "enum") { utils.writeFile( path.join(tempSrcDirPath, idef.filename + ".cc"), templates[idef.type + "_content"].render(idef), idef.type + "_content.cc" ); utils.writeFile( path.join(tempIncludeDirPath, idef.filename + ".h"), templates[idef.type + "_header"].render(idef), idef.type + "_header.h" ); } }); utils.writeLocalFile("../lib/enums.js", beautify(templates.enums.render(enabled)), "enums.js"); }).then(function() { return exec("command -v astyle").then(function(astyle) { if (astyle) { return exec( "astyle --options=\".astylerc\" " + tempSrcDirPath + "/*.cc " + tempIncludeDirPath + "/*.h" ).then(function() { return exec( "rm " + tempSrcDirPath + "/*.cc.orig " + tempIncludeDirPath + "/*.h.orig " ); }); } }, function() {}) }).then(function() { return Promise.all([ utils.syncDirs(tempSrcDirPath, finalSrcDirPath), utils.syncDirs(tempIncludeDirPath, finalIncludeDirPath), ]); }).then(function() { return fse.remove(tempDirPath); }).catch(console.log); }; if (require.main === module) { module.exports(); }