diff --git a/.travis.yml b/.travis.yml index 66cd1f8..1e03128 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,64 +1,65 @@ -branches: - only: - - master -matrix: - include: - - stage: "Lint" - language: node_js - os: linux - node_js: "6" - script: cd src && npm run ci.tslint && cd ../demo && npm run ci.tslint - - stage: "WebPack and Build" - os: osx - env: - - Platform="iOS" - - Xcode="9.2" - osx_image: xcode9.2 - language: node_js - node_js: "6" - jdk: oraclejdk8 - script: cd demo && npm run build.plugin && npm i && npm run build-ios-bundle - - os: linux - language: android - env: - - Platform="Android" - - AndroidSDK="26" - jdk: oraclejdk8 - before_install: nvm install 6.10.3 - script: > - echo { \"project_info\": { \"project_number\": \"424050927453\", \"firebase_url\": \"https://pptest-53916.firebaseio.com\", \"project_id\": \"pptest-53916\", \"storage_bucket\": \"pptest-53916.appspot.com\" }, \"client\": [ { \"client_info\": { \"mobilesdk_app_id\": \"1:424050927453:android:21d2dd8987e1e3d1\", \"android_client_info\": { \"package_name\": \"org.nativescript.ppTest\" } }, \"oauth_client\": [ { \"client_id\": \"424050927453-o7gv6bcmknujjoaaoa5r4d452cutb9jf.apps.googleusercontent.com\", \"client_type\": 3 } ], \"api_key\": [ { \"current_key\": \"AIzaSyDr3fqH7Z8-vhBNpAges_KFTA7oOoylGvU\" } ], \"services\": { \"analytics_service\": { \"status\": 1 }, \"appinvite_service\": { \"status\": 1, \"other_platform_oauth_client\": [] }, \"ads_service\": { \"status\": 2 } } } ], \"configuration_version\": \"1\"} > demo/app/App_Resources/Android/google-services.json && - cd demo && npm run build.plugin && npm i && npm run build-android-bundle - - language: android - env: - - Platform="Android" - - AndroidSDK="26" - os: linux - jdk: oraclejdk8 - before_install: nvm install stable - script: > - echo { \"project_info\": { \"project_number\": \"424050927453\", \"firebase_url\": \"https://pptest-53916.firebaseio.com\", \"project_id\": \"pptest-53916\", \"storage_bucket\": \"pptest-53916.appspot.com\" }, \"client\": [ { \"client_info\": { \"mobilesdk_app_id\": \"1:424050927453:android:21d2dd8987e1e3d1\", \"android_client_info\": { \"package_name\": \"org.nativescript.ppTest\" } }, \"oauth_client\": [ { \"client_id\": \"424050927453-o7gv6bcmknujjoaaoa5r4d452cutb9jf.apps.googleusercontent.com\", \"client_type\": 3 } ], \"api_key\": [ { \"current_key\": \"AIzaSyDr3fqH7Z8-vhBNpAges_KFTA7oOoylGvU\" } ], \"services\": { \"analytics_service\": { \"status\": 1 }, \"appinvite_service\": { \"status\": 1, \"other_platform_oauth_client\": [] }, \"ads_service\": { \"status\": 2 } } } ], \"configuration_version\": \"1\"} > demo/app/App_Resources/Android/google-services.json && - cd demo && npm run ci.android.build - - os: osx - env: - - Platform="iOS" - - Xcode="9.2" - osx_image: xcode9.2 - language: node_js - node_js: "6" - jdk: oraclejdk8 - script: cd demo && npm run ci.ios.build - -android: - components: - - tools - - platform-tools - - build-tools-26.0.1 - - android-23 - - android-26 - - extra-android-m2repository - -install: - - echo no | npm install -g nativescript - - tns usage-reporting disable - - tns error-reporting disable - \ No newline at end of file +branches: + only: + - master +matrix: + include: + - stage: "Lint" + language: node_js + os: linux + node_js: "6" + script: cd src && npm run ci.tslint && cd ../demo && npm run ci.tslint + - stage: "WebPack and Build" + os: osx + env: + - Platform="iOS" + - Xcode="9.2" + - Webpack="true" + osx_image: xcode9.2 + language: node_js + node_js: "6" + jdk: oraclejdk8 + script: cd demo && npm run build.plugin && npm i && tns build ios --bundle --env.uglify + - os: linux + language: android + env: + - Platform="Android" + - AndroidSDK="26" + - Webpack="true" + jdk: oraclejdk8 + before_install: nvm install 6.10.3 + script: > + echo { \"project_info\": { \"project_number\": \"424050927453\", \"firebase_url\": \"https://pptest-53916.firebaseio.com\", \"project_id\": \"pptest-53916\", \"storage_bucket\": \"pptest-53916.appspot.com\" }, \"client\": [ { \"client_info\": { \"mobilesdk_app_id\": \"1:424050927453:android:21d2dd8987e1e3d1\", \"android_client_info\": { \"package_name\": \"org.nativescript.ppTest\" } }, \"oauth_client\": [ { \"client_id\": \"424050927453-o7gv6bcmknujjoaaoa5r4d452cutb9jf.apps.googleusercontent.com\", \"client_type\": 3 } ], \"api_key\": [ { \"current_key\": \"AIzaSyDr3fqH7Z8-vhBNpAges_KFTA7oOoylGvU\" } ], \"services\": { \"analytics_service\": { \"status\": 1 }, \"appinvite_service\": { \"status\": 1, \"other_platform_oauth_client\": [] }, \"ads_service\": { \"status\": 2 } } } ], \"configuration_version\": \"1\"} > demo/app/App_Resources/Android/google-services.json && + cd demo && npm run build.plugin && npm i && tns build android --bundle --env.uglify + - language: android + env: + - Platform="Android" + - AndroidSDK="26" + os: linux + jdk: oraclejdk8 + before_install: nvm install stable + script: > + echo { \"project_info\": { \"project_number\": \"424050927453\", \"firebase_url\": \"https://pptest-53916.firebaseio.com\", \"project_id\": \"pptest-53916\", \"storage_bucket\": \"pptest-53916.appspot.com\" }, \"client\": [ { \"client_info\": { \"mobilesdk_app_id\": \"1:424050927453:android:21d2dd8987e1e3d1\", \"android_client_info\": { \"package_name\": \"org.nativescript.ppTest\" } }, \"oauth_client\": [ { \"client_id\": \"424050927453-o7gv6bcmknujjoaaoa5r4d452cutb9jf.apps.googleusercontent.com\", \"client_type\": 3 } ], \"api_key\": [ { \"current_key\": \"AIzaSyDr3fqH7Z8-vhBNpAges_KFTA7oOoylGvU\" } ], \"services\": { \"analytics_service\": { \"status\": 1 }, \"appinvite_service\": { \"status\": 1, \"other_platform_oauth_client\": [] }, \"ads_service\": { \"status\": 2 } } } ], \"configuration_version\": \"1\"} > demo/app/App_Resources/Android/google-services.json && + cd demo && npm run ci.android.build + - os: osx + env: + - Platform="iOS" + - Xcode="9.2" + osx_image: xcode9.2 + language: node_js + node_js: "6" + jdk: oraclejdk8 + script: cd demo && npm run ci.ios.build + +android: + components: + - tools + - platform-tools + - build-tools-26.0.1 + - android-23 + - android-26 + - extra-android-m2repository + +install: + - echo no | npm install -g nativescript + - tns usage-reporting disable + - tns error-reporting disable diff --git a/demo/package.json b/demo/package.json index b5a28c4..4820375 100644 --- a/demo/package.json +++ b/demo/package.json @@ -4,10 +4,10 @@ "nativescript": { "id": "org.nativescript.ppTest", "tns-ios": { - "version": "3.3.0" + "version": "3.4.0" }, "tns-android": { - "version": "3.3.1" + "version": "3.4.0" } }, "repository": { @@ -21,36 +21,31 @@ "tns-core-modules": "^3.3.0" }, "devDependencies": { - "awesome-typescript-loader": "~3.1.3", + "awesome-typescript-loader": "~3.4.1", "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "copy-webpack-plugin": "~4.0.1", + "copy-webpack-plugin": "~4.3.1", "extract-text-webpack-plugin": "~3.0.0", "lazy": "1.0.11", "nativescript-css-loader": "~0.26.0", - "nativescript-dev-typescript": "~0.5.0", - "nativescript-dev-webpack": "^0.8.0", + "nativescript-dev-typescript": "~0.6.0", + "nativescript-dev-webpack": "^0.9.0", "nativescript-worker-loader": "~0.8.1", "raw-loader": "~0.5.1", - "resolve-url-loader": "~2.1.0", + "resolve-url-loader": "~2.2.1", "tslint": "^5.8.0", - "typescript": "~2.4.2", - "webpack": "~3.2.0", + "typescript": "~2.6.2", + "webpack": "~3.10.0", "webpack-bundle-analyzer": "^2.8.2", - "webpack-sources": "~1.0.1" + "webpack-sources": "~1.1.0", + "css-loader": "~0.28.7" }, "scripts": { "build.plugin": "cd ../src && npm run build", "ci.tslint": "npm run build.plugin && npm i && tslint --config ../tslint.json 'app/**/*.ts' --exclude '**/node_modules/**'", "ci.android.build": "npm run build.plugin && tns build android", "ci.ios.build": "npm run build.plugin && tns build ios", - "ns-bundle": "ns-bundle", - "publish-ios-bundle": "npm run ns-bundle --ios --publish-app", - "generate-android-snapshot": "generate-android-snapshot --targetArchs arm,arm64,ia32 --install", - "start-android-bundle": "npm run ns-bundle --android --run-app", - "start-ios-bundle": "npm run ns-bundle --ios --run-app", - "build-android-bundle": "npm run ns-bundle --android --build-app", - "build-ios-bundle": "npm run ns-bundle --ios --build-app" + "generate-android-snapshot": "generate-android-snapshot --targetArchs arm,arm64,ia32 --install" } } diff --git a/src/hooks/utils.js b/src/hooks/utils.js index d8a2e17..a79aa20 100755 --- a/src/hooks/utils.js +++ b/src/hooks/utils.js @@ -1,159 +1,193 @@ -var path = require('path'); -var fs = require('fs'); -var os = require('os'); - -var PLUGIN_VERSION = '3.1.1'; -var _log = console.log.bind(console); - -function targetsAndroid (projectDir) { - var pkg = require(path.join(projectDir, 'package.json')); - if (!pkg.nativescript) { - throw new Error('Not a NativeScript project'); - } - - return ('tns-android' in pkg.nativescript); -} - -function buildGradleExists (platformsDir) { - return fs.existsSync(_getBuildGradlePath(platformsDir)); -} - -function checkForGoogleServicesJson (projectDir, resourcesDir) { - var androidIsTargeted = targetsAndroid(projectDir); - var resourcesPath = path.join(resourcesDir, 'Android', 'google-services.json'); - - if (androidIsTargeted && !fs.existsSync(resourcesPath)) { - _log('|!| google-services.json appears to be missing. Please make sure it is present in the "app/App_Resources/Android" folder, in order to use FCM push notifications |!|'); - } -} - -function addOnPluginInstall (platformsDir) { - var path = _getBuildGradlePath(platformsDir); - if (buildGradleExists(platformsDir)) { - addIfNecessary(platformsDir); - } -} - -function addIfNecessary (platformsDir) { - _amendBuildGradle(platformsDir, function (pluginImported, pluginApplied, fileContents) { - var newContents = fileContents; - if (!pluginImported) { - newContents = _addPluginImport(newContents); - } - - if (!pluginApplied) { - newContents = _addPluginApplication(newContents); - } - return newContents; - }); -} - -function removeIfPresent (platformsDir) { - _amendBuildGradle(platformsDir, function (pluginImported, pluginApplied, fileContents) { - var newFileContents = fileContents; - if (pluginImported) { - newFileContents = _removePluginImport(newFileContents); - } - - if (pluginApplied) { - newFileContents = _removePluginApplication(newFileContents); - } - return newFileContents; - }); -} - -function setLogger (logFunc) { - _log = logFunc; -} - -// ============= private - -var _quotesRegExp = '["\']'; -var _versionRegExp = '[^\'"]+'; -var _pluginImportName = 'com.google.gms:google-services'; -var _pluginApplicationName = 'com.google.gms.google-services'; - -function _amendBuildGradle (platformsDir, applyAmendment) { - var path = _getBuildGradlePath(platformsDir); - - if (!buildGradleExists(platformsDir)) { - return _log('build.gradle file not found'); - } - - var fileContents = fs.readFileSync(path, 'utf8'); - var pluginImported = _checkForImport(fileContents); - var pluginApplied = _checkForApplication(fileContents); - var newContents = applyAmendment(pluginImported, pluginApplied, fileContents); - - fs.writeFileSync(path, newContents, 'utf8'); -} - -function _removePluginImport (buildGradleContents) { - var regExpStr = '\\s*classpath +' + _formNamePartOfRegExp(true) + '{0,0}:' + _versionRegExp + _quotesRegExp; - var regExp = new RegExp(regExpStr, 'i'); - return buildGradleContents.replace(regExp, ''); -} - -function _removePluginApplication (buildGradleContents) { - var regExpStr = '\\s*apply plugin: +' + _formNamePartOfRegExp(false); - var regExp = new RegExp(regExpStr, 'i'); - return buildGradleContents.replace(regExp, ''); -} - -function _addPluginImport (buildGradleContents) { - var androidGradle = 'com.android.tools.build:gradle'; - var insertBeforeDoubleQuotes = 'classpath "' + androidGradle; - var insertBeforeSingleQoutes = 'classpath \'' + androidGradle; - - var ind = buildGradleContents.indexOf(insertBeforeDoubleQuotes); - if (ind === -1) { - ind = buildGradleContents.indexOf(insertBeforeSingleQoutes); - } - - if (ind === -1) { - _log('build.gradle has unexpected contents -- please check it manually'); - return buildGradleContents; - } - - var result = buildGradleContents.substring(0, ind); - result += 'classpath "' + _pluginImportName + ':' + PLUGIN_VERSION + '"' + os.EOL; - result += '\t\t' + insertBeforeDoubleQuotes; - result += buildGradleContents.substring(ind + ('classpath "' + androidGradle).length); - return result; -} - -function _addPluginApplication (buildGradleContents) { - buildGradleContents += os.EOL + 'apply plugin: "' + _pluginApplicationName + '"' + os.EOL; - return buildGradleContents; -} - -function _formNamePartOfRegExp (useImportName) { - var name = useImportName ? _pluginImportName : _pluginApplicationName; - return _quotesRegExp + name + _quotesRegExp; -} - -function _checkForImport (buildGradleContents) { - var re = new RegExp('classpath +' + _formNamePartOfRegExp(true) + '{0,0}', 'i'); - return re.test(buildGradleContents); -} - -function _checkForApplication (buildGradleContents) { - var re = new RegExp('apply plugin: +' + _formNamePartOfRegExp(false), 'i'); - return re.test(buildGradleContents); -} - -function _getBuildGradlePath (platformsDir) { - return path.join(platformsDir, 'android', 'build.gradle'); -} - -// ============= end private - -module.exports = { - removeIfPresent: removeIfPresent, - setLogger: setLogger, - addIfNecessary: addIfNecessary, - targetsAndroid: targetsAndroid, - buildGradleExists: buildGradleExists, - addOnPluginInstall: addOnPluginInstall, - checkForGoogleServicesJson: checkForGoogleServicesJson -}; +var path = require('path'); +var fs = require('fs'); +var os = require('os'); + +var PLUGIN_VERSION = '3.1.1'; +var _log = console.log.bind(console); + +function targetsAndroid(projectDir) { + var pkg = require(path.join(projectDir, 'package.json')); + if (!pkg.nativescript) { + throw new Error('Not a NativeScript project'); + } + + return ('tns-android' in pkg.nativescript); +} + +function buildGradleExists(platformsDir) { + return fs.existsSync(_getProjectBuildGradlePath(platformsDir)); +} + +function checkForGoogleServicesJson(projectDir, resourcesDir) { + var androidIsTargeted = targetsAndroid(projectDir); + var resourcesPath = path.join(resourcesDir, 'Android', 'google-services.json'); + + if (androidIsTargeted && !fs.existsSync(resourcesPath)) { + _log('|!| google-services.json appears to be missing. Please make sure it is present in the "app/App_Resources/Android" folder, in order to use FCM push notifications |!|'); + } +} + +function addOnPluginInstall(platformsDir) { + if (buildGradleExists(platformsDir)) { + addIfNecessary(platformsDir); + } +} + +function addIfNecessary(platformsDir) { + _amendBuildGradle(platformsDir, function(pluginImported, pluginApplied, fileContents) { + if (!pluginImported) { + fileContents.projectFileContents = _addPluginImport(fileContents.projectFileContents); + } + + if (!pluginApplied) { + if (fileContents.appFileContents) { + fileContents.appFileContents = _addPluginApplication(fileContents.appFileContents); + } else { + fileContents.projectFileContents = _addPluginApplication(fileContents.projectFileContents); + } + } + return fileContents; + }); + + _copyGoogleServices(platformsDir); +} + +function removeIfPresent(platformsDir) { + _amendBuildGradle(platformsDir, function(pluginImported, pluginApplied, fileContents) { + if (pluginImported) { + fileContents.projectFileContents = _removePluginImport(fileContents.projectFileContents); + } + + if (pluginApplied) { + if (fileContents.appFileContents) { + fileContents.appFileContents = _removePluginApplication(fileContents.appFileContents); + } else { + fileContents.projectFileContents = _removePluginApplication(fileContents.projectFileContents); + } + } + return fileContents; + }); +} + +function setLogger(logFunc) { + _log = logFunc; +} + +// ============= private + +var _quotesRegExp = '["\']'; +var _versionRegExp = '[^\'"]+'; +var _pluginImportName = 'com.google.gms:google-services'; +var _pluginApplicationName = 'com.google.gms.google-services'; + +function _copyGoogleServices(platformsDir) { + var srcServicesFile = path.join(platformsDir, '..', 'app', 'App_Resources', 'Android', 'google-services.json'); + var dstServicesFile = path.join(platformsDir, 'android', 'app', 'google-services.json'); + if (fs.existsSync(srcServicesFile) && !fs.existsSync(dstServicesFile) && fs.existsSync(path.join(platformsDir, 'android', 'app'))) { + // try to copy google-services config file to platform app directory + fs.writeFileSync(dstServicesFile, fs.readFileSync(srcServicesFile, 'utf-8')); + } +} + +function _amendBuildGradle(platformsDir, applyAmendment) { + if (!buildGradleExists(platformsDir)) { + return _log('build.gradle file not found'); + } + + var projectPath = _getProjectBuildGradlePath(platformsDir); + var appPath = _getAppBuildGradlePath(platformsDir); + + if (!fs.existsSync(appPath)) { + // NativeScript <= 3.3.1 + appPath = null; + } + var fileContents = { + projectFileContents: fs.readFileSync(projectPath, 'utf8'), + appFileContents: appPath ? fs.readFileSync(appPath, 'utf8') : null + }; + var pluginImported = _checkForImport(fileContents.projectFileContents); + var pluginApplied = _checkForApplication(fileContents.appFileContents ? fileContents.appFileContents : fileContents.projectFileContents); + var newContents = applyAmendment(pluginImported, pluginApplied, fileContents); + + fs.writeFileSync(projectPath, newContents.projectFileContents, 'utf8'); + if (appPath) { + fs.writeFileSync(appPath, newContents.appFileContents, 'utf8'); + } +} + +function _removePluginImport(buildGradleContents) { + var regExpStr = '\\s*classpath +' + _formNamePartOfRegExp(true) + '{0,0}:' + _versionRegExp + _quotesRegExp; + var regExp = new RegExp(regExpStr, 'i'); + return buildGradleContents.replace(regExp, ''); +} + +function _removePluginApplication(buildGradleContents) { + var regExpStr = '\\s*apply plugin: +' + _formNamePartOfRegExp(false); + var regExp = new RegExp(regExpStr, 'i'); + return buildGradleContents.replace(regExp, ''); +} + +function _addPluginImport(buildGradleContents) { + var androidGradle = 'com.android.tools.build:gradle'; + var insertBeforeDoubleQuotes = 'classpath "' + androidGradle; + var insertBeforeSingleQoutes = 'classpath \'' + androidGradle; + var quoteToInsert = '"' + var matchedString = insertBeforeDoubleQuotes; + var ind = buildGradleContents.indexOf(insertBeforeDoubleQuotes); + + if (ind === -1) { + ind = buildGradleContents.indexOf(insertBeforeSingleQoutes); + quoteToInsert = '\''; + matchedString = insertBeforeSingleQoutes; + } + + if (ind === -1) { + _log('build.gradle has unexpected contents -- please check it manually'); + return buildGradleContents; + } + + var result = buildGradleContents.substring(0, ind); + result += 'classpath ' + quoteToInsert + _pluginImportName + ':' + PLUGIN_VERSION + quoteToInsert + os.EOL; + result += '\t\t' + matchedString; + result += buildGradleContents.substring(ind + matchedString.length); + return result; +} + +function _addPluginApplication(buildGradleContents) { + buildGradleContents += os.EOL + 'apply plugin: "' + _pluginApplicationName + '"' + os.EOL; + return buildGradleContents; +} + +function _formNamePartOfRegExp(useImportName) { + var name = useImportName ? _pluginImportName : _pluginApplicationName; + return _quotesRegExp + name + _quotesRegExp; +} + +function _checkForImport(buildGradleContents) { + var re = new RegExp('classpath +' + _formNamePartOfRegExp(true) + '{0,0}', 'i'); + return re.test(buildGradleContents); +} + +function _checkForApplication(buildGradleContents) { + var re = new RegExp('apply plugin: +' + _formNamePartOfRegExp(false), 'i'); + return re.test(buildGradleContents); +} + +function _getProjectBuildGradlePath(platformsDir) { + return path.join(platformsDir, 'android', 'build.gradle'); +} + +function _getAppBuildGradlePath(platformsDir) { + return path.join(platformsDir, 'android', 'app', 'build.gradle'); +} +// ============= end private + +module.exports = { + removeIfPresent: removeIfPresent, + setLogger: setLogger, + addIfNecessary: addIfNecessary, + targetsAndroid: targetsAndroid, + buildGradleExists: buildGradleExists, + addOnPluginInstall: addOnPluginInstall, + checkForGoogleServicesJson: checkForGoogleServicesJson +}; \ No newline at end of file