diff options
-rw-r--r-- | Makefile | 4 | ||||
-rwxr-xr-x | platform/darwin/scripts/check-public-symbols.js | 83 | ||||
-rwxr-xr-x | platform/macos/scripts/package.sh | 3 |
3 files changed, 90 insertions, 0 deletions
@@ -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 |