diff --git a/.travis.yml b/.travis.yml index 474f1195b4a417..5eb44fa252c118 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ script: - if [[ "$TEST_TYPE" = e2e-objc-tvos ]]; then node ./scripts/run-ci-e2e-tests.js --tvos --retries 3; fi - if [[ "$TEST_TYPE" = js ]]; then npm run flow check; fi - if [[ "$TEST_TYPE" = js ]]; then npm test -- --maxWorkers=1; fi + - if [[ ( "$TEST_TYPE" = podspecs ) && ( "$TRAVIS_PULL_REQUEST" = "false" ) ]]; then gem install cocoapods && ./scripts/process-podspecs.sh; fi env: matrix: @@ -29,6 +30,7 @@ env: - TEST_TYPE=objc-ios - TEST_TYPE=objc-tvos - TEST_TYPE=js + - TEST_TYPE=podspecs branches: only: diff --git a/React.podspec b/React.podspec index 5eac3dbcd768c7..fb64f20b6f7fdb 100644 --- a/React.podspec +++ b/React.podspec @@ -1,140 +1,138 @@ -require 'json' +require "json" -package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) +package = JSON.parse(File.read(File.join(__dir__, "package.json"))) Pod::Spec.new do |s| - s.name = "React" - s.version = package['version'] - s.summary = package['description'] - s.description = <<-DESC - React Native apps are built using the React JS - framework, and render directly to native UIKit - elements using a fully asynchronous architecture. - There is no browser and no HTML. We have picked what - we think is the best set of features from these and - other technologies to build what we hope to become - the best product development framework available, - with an emphasis on iteration speed, developer - delight, continuity of technology, and absolutely - beautiful and fast products with no compromises in - quality or capability. - DESC - s.homepage = "http://facebook.github.io/react-native/" - s.license = package['license'] - s.author = "Facebook" - s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "v#{s.version}" } - s.default_subspec = 'Core' - s.requires_arc = true - s.platform = :ios, "8.0" - s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++14" } - s.header_dir = 'React' - s.preserve_paths = "package.json", "LICENSE", "LICENSE-CustomComponents", "PATENTS" + s.name = "React" + s.version = package["version"] + s.summary = package["description"] + s.description = <<-DESC + React Native apps are built using the React JS + framework, and render directly to native UIKit + elements using a fully asynchronous architecture. + There is no browser and no HTML. We have picked what + we think is the best set of features from these and + other technologies to build what we hope to become + the best product development framework available, + with an emphasis on iteration speed, developer + delight, continuity of technology, and absolutely + beautiful and fast products with no compromises in + quality or capability. + DESC + s.homepage = "http://facebook.github.io/react-native/" + s.license = package["license"] + s.author = "Facebook" + s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "v#{s.version}" } + s.default_subspec = "Core" + s.requires_arc = true + s.platform = :ios, "8.0" + s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++14" } + s.preserve_paths = "package.json", "LICENSE", "LICENSE-CustomComponents", "PATENTS" + s.cocoapods_version = ">= 1.2.0" - s.subspec 'Core' do |ss| - ss.dependency 'React/yoga' - ss.dependency 'React/cxxreact' - ss.source_files = "React/**/*.{c,h,m,mm,S}" - ss.exclude_files = "**/__tests__/*", "IntegrationTests/*", "React/**/RCTTVView.*", "ReactCommon/yoga/*" - ss.frameworks = "JavaScriptCore" - ss.libraries = "stdc++" + s.subspec "Core" do |ss| + ss.dependency "Yoga", "#{package["version"]}.React" + ss.dependency "React/cxxreact" + ss.source_files = "React/**/*.{c,h,m,mm,S}" + ss.exclude_files = "**/__tests__/*", "IntegrationTests/*", "React/**/RCTTVView.*", "ReactCommon/yoga/*", "React/Cxx*/*" + ss.framework = "JavaScriptCore" + ss.libraries = "stdc++" end - s.subspec 'tvOS' do |ss| - ss.dependency 'React/Core' - ss.source_files = "React/**/RCTTVView.{h, m}" + s.subspec "tvOS" do |ss| + ss.dependency "React/Core" + ss.source_files = "React/**/RCTTVView.{h, m}" end - s.subspec 'jschelpers' do |ss| - ss.source_files = 'ReactCommon/jschelpers/{JavaScriptCore,JSCWrapper}.{cpp,h}' - ss.header_dir = 'jschelpers' + s.subspec "jschelpers" do |ss| + ss.source_files = "ReactCommon/jschelpers/{JavaScriptCore,JSCWrapper}.{cpp,h}" + ss.private_header_files = "ReactCommon/jschelpers/{JavaScriptCore,JSCWrapper}.h" + ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "$(PODS_TARGET_SRCROOT)/ReactCommon" } + ss.framework = "JavaScriptCore" end - s.subspec 'cxxreact' do |ss| - ss.dependency 'React/jschelpers' - ss.source_files = 'ReactCommon/cxxreact/{JSBundleType,oss-compat-util}.{cpp,h}' - ss.header_dir = 'cxxreact' + s.subspec "cxxreact" do |ss| + ss.dependency "React/jschelpers" + ss.source_files = "ReactCommon/cxxreact/{JSBundleType,oss-compat-util}.{cpp,h}" + ss.private_header_files = "ReactCommon/cxxreact/{JSBundleType,oss-compat-util}.h" + ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "$(PODS_TARGET_SRCROOT)/ReactCommon" } end - s.subspec 'yoga' do |ss| - ss.source_files = 'ReactCommon/yoga/**/*.{c,h}' - ss.header_dir = 'yoga' + s.subspec "ART" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/ART/**/*.{h,m}" end - s.subspec 'ART' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/ART/**/*.{h,m}" + s.subspec "RCTActionSheet" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/ActionSheetIOS/*.{h,m}" end - s.subspec 'RCTActionSheet' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/ActionSheetIOS/*.{h,m}" + s.subspec "RCTAdSupport" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/AdSupport/*.{h,m}" end - s.subspec 'RCTAdSupport' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/AdSupport/*.{h,m}" + s.subspec "RCTAnimation" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/NativeAnimation/{Drivers/*,Nodes/*,*}.{h,m}" end - s.subspec 'RCTAnimation' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/NativeAnimation/{Drivers/*,Nodes/*,*}.{h,m}" + s.subspec "RCTCameraRoll" do |ss| + ss.dependency "React/Core" + ss.dependency "React/RCTImage" + ss.source_files = "Libraries/CameraRoll/*.{h,m}" end - s.subspec 'RCTCameraRoll' do |ss| - ss.dependency 'React/Core' - ss.dependency 'React/RCTImage' - ss.source_files = "Libraries/CameraRoll/*.{h,m}" + s.subspec "RCTGeolocation" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/Geolocation/*.{h,m}" end - s.subspec 'RCTGeolocation' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/Geolocation/*.{h,m}" + s.subspec "RCTImage" do |ss| + ss.dependency "React/Core" + ss.dependency "React/RCTNetwork" + ss.source_files = "Libraries/Image/*.{h,m}" end - s.subspec 'RCTImage' do |ss| - ss.dependency 'React/Core' - ss.dependency 'React/RCTNetwork' - ss.source_files = "Libraries/Image/*.{h,m}" + s.subspec "RCTNetwork" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/Network/*.{h,m,mm}" end - s.subspec 'RCTNetwork' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/Network/*.{h,m,mm}" + s.subspec "RCTPushNotification" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/PushNotificationIOS/*.{h,m}" end - s.subspec 'RCTPushNotification' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/PushNotificationIOS/*.{h,m}" + s.subspec "RCTSettings" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/Settings/*.{h,m}" end - s.subspec 'RCTSettings' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/Settings/*.{h,m}" + s.subspec "RCTText" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/Text/*.{h,m}" end - s.subspec 'RCTText' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/Text/*.{h,m}" + s.subspec "RCTVibration" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/Vibration/*.{h,m}" end - s.subspec 'RCTVibration' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/Vibration/*.{h,m}" + s.subspec "RCTWebSocket" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/WebSocket/*.{h,m}" end - s.subspec 'RCTWebSocket' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/WebSocket/*.{h,m}" + s.subspec "RCTLinkingIOS" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/LinkingIOS/*.{h,m}" end - s.subspec 'RCTLinkingIOS' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/LinkingIOS/*.{h,m}" - end - - s.subspec 'RCTTest' do |ss| - ss.dependency 'React/Core' - ss.source_files = "Libraries/RCTTest/**/*.{h,m}" - ss.frameworks = "XCTest" + s.subspec "RCTTest" do |ss| + ss.dependency "React/Core" + ss.source_files = "Libraries/RCTTest/**/*.{h,m}" + ss.frameworks = "XCTest" end end diff --git a/ReactCommon/yoga/Yoga.podspec b/ReactCommon/yoga/Yoga.podspec new file mode 100644 index 00000000000000..1e9c75ff7721ed --- /dev/null +++ b/ReactCommon/yoga/Yoga.podspec @@ -0,0 +1,44 @@ +package = JSON.parse(File.read(File.expand_path('../../package.json', __dir__))) +version = package['version'] + +source = { :git => 'https://github.com/facebook/react-native.git' } +if version == '1000.0.0' + # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in. + source[:commit] = `git rev-parse HEAD`.strip +else + source[:tag] = "v#{version}" +end + +Pod::Spec.new do |spec| + spec.name = 'Yoga' + spec.version = "#{version}.React" + spec.license = { :type => 'BSD' } + spec.homepage = 'https://facebook.github.io/yoga/' + spec.documentation_url = 'https://facebook.github.io/yoga/docs/api/c/' + + spec.summary = 'Yoga is a cross-platform layout engine which implements Flexbox.' + spec.description = 'Yoga is a cross-platform layout engine enabling maximum collaboration within your team by implementing an API many designers are familiar with, and opening it up to developers across different platforms.' + + spec.authors = 'Facebook' + spec.source = source + + spec.module_name = 'yoga' + spec.requires_arc = false + spec.compiler_flags = [ + '-fno-omit-frame-pointer', + '-fexceptions', + '-Wall', + '-Werror', + '-std=c11', + '-fPIC' + ] + + # Pinning to the same version as React.podspec. + spec.platform = :ios, "8.0" + + # Set this environment variable when not using the `:path` option to install the pod. + # E.g. when publishing this spec to a spec repo. + source_files = 'yoga/**/*.{c,h}' + source_files = File.join('ReactCommon/yoga', source_files) if ENV['INSTALL_YOGA_WITHOUT_PATH_OPTION'] + spec.source_files = source_files +end diff --git a/scripts/process-podspecs.sh b/scripts/process-podspecs.sh new file mode 100755 index 00000000000000..d87fa4f719131b --- /dev/null +++ b/scripts/process-podspecs.sh @@ -0,0 +1,62 @@ +#!/bin/bash +set -ex + +SCRIPTS=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +ROOT=$(dirname $SCRIPTS) +YOGA_ROOT="$ROOT/ReactCommon/yoga" + +# Specify `SPEC_REPO` as an env variable if you want to push to a specific spec repo. +# Defaults to `react-test`, which is meant to be a dummy repo used to test that the specs fully lint. +: ${SPEC_REPO:="react-test"} +SPEC_REPO_DIR="$HOME/.cocoapods/repos/$SPEC_REPO" + +# If the `SPEC_REPO` does not exist yet, assume this is purely for testing and create a dummy repo. +if ! [ -d "$SPEC_REPO_DIR" ]; then + mkdir -p "$SPEC_REPO_DIR" + cd "$SPEC_REPO_DIR" + echo "testing" > .gitkeep + git init + git add .gitkeep + git commit -m "init" + git remote add origin "https://example.com/$SPEC_REPO.git" +fi + +cd "$SPEC_REPO_DIR" +SPEC_REPO_REMOTE=$(git remote get-url origin) + +POD_LINT_OPT="--verbose --no-subspecs --allow-warnings --fail-fast --private --swift-version=3.0 --sources=$SPEC_REPO_REMOTE" + +# Get the version from a podspec. +version() { + ruby -rcocoapods-core -rjson -e "puts Pod::Specification.from_file('$1').version" +} + +# Lint both framework and static library builds. +lint() { + pod lib lint $POD_LINT_OPT + pod lib lint $POD_LINT_OPT --use-libraries +} + +# Push the spec in arg `$1`, which is expected to be in the cwd, to the `SPEC_REPO` in JSON format. +push() { + local SPEC_NAME=$1 + local POD_NAME=$(basename $SPEC_NAME .podspec) + local SPEC_DIR="$SPEC_REPO_DIR/$POD_NAME/$(version $SPEC_NAME)" + local SPEC_PATH="$SPEC_DIR/$SPEC_NAME.json" + mkdir -p $SPEC_DIR + env INSTALL_YOGA_WITHOUT_PATH_OPTION=1 pod ipc spec $SPEC_NAME > $SPEC_PATH +} + +# Perform linting and publishing of podspec in cwd. +# Skip linting with `SKIP_LINT` if e.g. publishing to a private spec repo. +process() { + cd $1 + if [ -z "$SKIP_LINT" ]; then + lint + fi + local SPEC_NAME=(*.podspec) + push $SPEC_NAME +} + +process $YOGA_ROOT +process $ROOT