summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rwxr-xr-xplatform/darwin/scripts/check-public-symbols.js83
-rwxr-xr-xplatform/macos/scripts/package.sh3
3 files changed, 90 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 393dad481b..5469fb1f70 100644
--- a/Makefile
+++ b/Makefile
@@ -277,6 +277,10 @@ idocument:
darwin-style-code:
node platform/darwin/scripts/generate-style-code.js
style-code: darwin-style-code
+
+.PHONY: check-public-symbols
+check-public-symbols:
+ node platform/darwin/scripts/check-public-symbols.js macOS
endif
#### Linux targets #####################################################
diff --git a/platform/darwin/scripts/check-public-symbols.js b/platform/darwin/scripts/check-public-symbols.js
new file mode 100755
index 0000000000..4dde5d677b
--- /dev/null
+++ b/platform/darwin/scripts/check-public-symbols.js
@@ -0,0 +1,83 @@
+#!/usr/bin/env node
+
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const execFileSync = require('child_process').execFileSync;
+const _ = require('lodash');
+
+const keyword = /\bMGL_EXPORT\b/;
+
+let scanned = [];
+
+function hasMissingSymbols(os) {
+ let missing = false;
+ let sdk = os === 'iOS' ? 'iphonesimulator' : 'macosx';
+ let sysroot = execFileSync('xcrun', ['--show-sdk-path', '--sdk', sdk]).toString().trim();
+ let umbrellaPath = `platform/${os.toLowerCase()}/src/Mapbox.h`;
+ let docArgs = ['doc', '--objc', umbrellaPath, '--',
+ '-x', 'objective-c', '-I', 'platform/darwin/src/', '-isysroot', sysroot];
+ let docStr = execFileSync('sourcekitten', docArgs).toString().trim();
+ let docJson = JSON.parse(docStr);
+ _.forEach(docJson, function (result) {
+ _.forEach(result, function (structure, path) {
+ // Prevent multiple scans of the same file.
+ if (scanned.indexOf(path) >= 0) return;
+ scanned.push(path);
+
+ const src = fs.readFileSync(path, 'utf8').split('\n');
+ _.forEach(structure['key.substructure'], function (substructure) {
+ switch (substructure['key.kind']) {
+ case 'sourcekitten.source.lang.objc.decl.class':
+ if (!(keyword.test(src[substructure['key.doc.line'] - 1]) || keyword.test(src[substructure['key.doc.line'] - 2]))) {
+ console.warn(`- missing symbol export for class ${substructure['key.name']} in ${path}:${substructure['key.doc.line']}:${substructure['key.doc.column']}`);
+ missing = true;
+ }
+ break;
+ case 'sourcekitten.source.lang.objc.decl.constant':
+ if (!keyword.test(src[substructure['key.doc.line'] - 1])) {
+ console.warn(`- missing symbol export for constant ${substructure['key.name']} in ${path}:${substructure['key.doc.line']}:${substructure['key.doc.column']}`);
+ missing = true;
+ }
+ break;
+ }
+ });
+ });
+ });
+
+ return missing;
+}
+
+function ensureSourceKittenIsInstalled() {
+ try {
+ execFileSync('which', ['sourcekitten']);
+ } catch (e) {
+ console.log(`Installing SourceKitten via Homebrew…`);
+ execFileSync('brew', ['install', 'sourcekitten']);
+ }
+}
+
+if (process.argv.length < 3) {
+ console.warn(`Usage: ${path.relative(process.cwd(), process.argv[1])} [macOS|iOS] ...`);
+ process.exit(1);
+}
+
+ensureSourceKittenIsInstalled();
+
+let missing = false;
+for (var i = 2; i < process.argv.length; i++) {
+ let os = process.argv[i];
+ if (os == 'iOS' || os == 'macOS') {
+ missing |= hasMissingSymbols(os);
+ } else {
+ console.warn(`Argument must be one of iOS or macOS`);
+ process.exit(1);
+ }
+}
+
+if (missing) {
+ process.exit(1);
+} else {
+ console.warn(`All symbols are correctly exported.`);
+}
diff --git a/platform/macos/scripts/package.sh b/platform/macos/scripts/package.sh
index 9cb38c6c71..2f30b0917d 100755
--- a/platform/macos/scripts/package.sh
+++ b/platform/macos/scripts/package.sh
@@ -75,3 +75,6 @@ sed -n -e '/^## /,$p' platform/macos/CHANGELOG.md > "${OUTPUT}/CHANGELOG.md"
step "Generating API documentation…"
make xdocument OUTPUT="${OUTPUT}/documentation"
+
+step "Checking that all public symbols are exported…"
+node platform/darwin/scripts/check-public-symbols.js macOS