mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
214
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23fb972a06 | ||
|
|
70d5c97ab4 | ||
|
|
0ef21bf8ad | ||
|
|
b23c558a20 | ||
|
|
89fd398342 | ||
|
|
9f2389f074 | ||
|
|
6da351a5ed | ||
|
|
2ad845ccb2 | ||
|
|
e04bbf0497 | ||
|
|
78f089906c | ||
|
|
8480386d50 | ||
|
|
9910981d3a | ||
|
|
d1a1020a4a | ||
|
|
fb84932e48 | ||
|
|
3f848e7a54 | ||
|
|
df748ba083 | ||
|
|
defefb19e3 | ||
|
|
ba51aeaa90 | ||
|
|
24657ad5c4 | ||
|
|
b7b83cda0a | ||
|
|
9301badec1 | ||
|
|
14718b20c6 | ||
|
|
e7d89fa53a | ||
|
|
8197399e43 | ||
|
|
4a48364639 | ||
|
|
e3adf47214 | ||
|
|
59cc1738d7 | ||
|
|
8351a5d186 | ||
|
|
25104de5c4 | ||
|
|
21008c9992 | ||
|
|
bda85b8244 | ||
|
|
32d37f03ad | ||
|
|
1d4c9f96e4 | ||
|
|
b1642ad5b6 | ||
|
|
2b190f2029 | ||
|
|
775daf5972 | ||
|
|
1c838f32a9 | ||
|
|
635c707eec | ||
|
|
cf664c65e2 | ||
|
|
ffac8f8ef0 | ||
|
|
2726c1ab7c | ||
|
|
6b4af382c2 | ||
|
|
219fc99e99 | ||
|
|
6c37b5b682 | ||
|
|
180996683b | ||
|
|
47a9a2b44f | ||
|
|
686d14f1d1 | ||
|
|
f9b1b2eb1d | ||
|
|
e5c05ccbc1 | ||
|
|
a902267563 | ||
|
|
d55bbfedff | ||
|
|
f9a49e5c56 | ||
|
|
55fa36173b | ||
|
|
3a3e3b884c | ||
|
|
40ebcef183 | ||
|
|
6caf2dfa38 | ||
|
|
c7591d9b40 | ||
|
|
0e6b94f4ab | ||
|
|
9f2fbc23e4 | ||
|
|
c23e84ae9f | ||
|
|
63335e5913 | ||
|
|
0ac41fa386 | ||
|
|
e3183739bb | ||
|
|
f936780cd5 | ||
|
|
e89df6410f | ||
|
|
9a4df1cdc6 | ||
|
|
41029d8e91 | ||
|
|
ee5f229a4a | ||
|
|
a8bc74c009 | ||
|
|
8702b09bcc | ||
|
|
7f93b664b4 | ||
|
|
f502cae9b5 | ||
|
|
9ca43e4095 | ||
|
|
f6ba2dbf3b | ||
|
|
56ad53cb14 | ||
|
|
d2df64d2fc | ||
|
|
1d86fb67ee | ||
|
|
4d5caef76b | ||
|
|
2ab6f22f26 | ||
|
|
8a2e7efe01 | ||
|
|
38e1e0de53 | ||
|
|
256565cb11 | ||
|
|
f9c2aaf3e7 | ||
|
|
614231d4df | ||
|
|
856f52a6f0 | ||
|
|
22a4f79224 | ||
|
|
94d260ee6a | ||
|
|
35bee1a857 | ||
|
|
dd0008fee9 | ||
|
|
81abd306bb | ||
|
|
4340dcbae8 | ||
|
|
3d12d81126 | ||
|
|
b75031f3dd | ||
|
|
d009a02c6c | ||
|
|
e8bf982bac | ||
|
|
c17267ec87 | ||
|
|
50d5316b1b | ||
|
|
bc54a06fcb | ||
|
|
c5956da8c0 | ||
|
|
568f59e5b1 | ||
|
|
33ca53d9db | ||
|
|
91e69b5d4c | ||
|
|
9f0d24bb05 | ||
|
|
9f77d421bb | ||
|
|
1c7925abb0 | ||
|
|
b44e1839ca | ||
|
|
4ee326f52c | ||
|
|
90804fd088 | ||
|
|
e2035379b6 | ||
|
|
0bf7721862 | ||
|
|
35d8086881 | ||
|
|
65b5a5b25d | ||
|
|
27217e8bd6 | ||
|
|
7e461003c6 | ||
|
|
bd287e8e2c | ||
|
|
db2a9c089c | ||
|
|
40afa75a7c | ||
|
|
453508ada8 | ||
|
|
05eddd354e | ||
|
|
641a79dc51 | ||
|
|
f1d014adbb | ||
|
|
7bfec89a97 | ||
|
|
65974e938c | ||
|
|
9c201c0f8f | ||
|
|
4978385067 | ||
|
|
42db2f8405 | ||
|
|
c2c2e6b7c2 | ||
|
|
e0b22e1ebf | ||
|
|
6fb0072f01 | ||
|
|
739dfd2141 | ||
|
|
001736000f | ||
|
|
841866c354 | ||
|
|
677ee671d0 | ||
|
|
cc71f9c550 | ||
|
|
6738dbcc7e | ||
|
|
1feb364f72 | ||
|
|
a2eb3b299d | ||
|
|
8d998ce96c | ||
|
|
8dcb18d2b3 | ||
|
|
4fa3c00324 | ||
|
|
fc6d7d4f0f | ||
|
|
9eb90f8911 | ||
|
|
85b47afb48 | ||
|
|
9c9a39b58e | ||
|
|
0af4a1c71f | ||
|
|
749dbe0840 | ||
|
|
1c33774990 | ||
|
|
07835d3d67 | ||
|
|
4c570b5d31 | ||
|
|
fd600a24af | ||
|
|
6b05a59a0d | ||
|
|
94623ca8ec | ||
|
|
d3bbbd893a | ||
|
|
da74d5da2c | ||
|
|
07091a9ae8 | ||
|
|
c1f7c5e321 | ||
|
|
b29b86f275 | ||
|
|
25c011eb4d | ||
|
|
3306cdbbe9 | ||
|
|
22e4c25211 | ||
|
|
78a3ff81eb | ||
|
|
25f466cc4d | ||
|
|
718126fcf0 | ||
|
|
19a99dd088 | ||
|
|
c4715886a9 | ||
|
|
1a85185cfc | ||
|
|
d2912e7997 | ||
|
|
7d6d0a7735 | ||
|
|
dc879950d1 | ||
|
|
e0ea781908 | ||
|
|
b3f397f343 | ||
|
|
5517c046ab | ||
|
|
8ccfff9a46 | ||
|
|
0aeb26bdfc | ||
|
|
3d37d2d2ce | ||
|
|
5a38948034 | ||
|
|
1a58fdf172 | ||
|
|
618254d8e9 | ||
|
|
01e3f8d75e | ||
|
|
2812e20ecc | ||
|
|
674fd79eaf | ||
|
|
de76f3436c | ||
|
|
99ae977345 | ||
|
|
fee81401d7 | ||
|
|
ec9f62865c | ||
|
|
e16def43c9 | ||
|
|
afb6294335 | ||
|
|
5b9063ed70 | ||
|
|
404c975ff2 | ||
|
|
91f9ff042d | ||
|
|
20c91f2bd4 | ||
|
|
7035391b04 | ||
|
|
e547f466ee | ||
|
|
8363a4c515 | ||
|
|
ec3d9c60f1 | ||
|
|
2f33eece41 | ||
|
|
81fdb9dd93 | ||
|
|
d4ea32493e | ||
|
|
ba518bbb30 | ||
|
|
85610c8b43 | ||
|
|
7f5b2b8f84 | ||
|
|
39d24bade3 | ||
|
|
9831b03860 | ||
|
|
f21a89078c | ||
|
|
352e440459 | ||
|
|
aaf471278c | ||
|
|
384677f58e | ||
|
|
2e76fc8e8e | ||
|
|
5fc23d7c62 | ||
|
|
e92da16a9b | ||
|
|
ae5df7ee35 | ||
|
|
dacd8f26fd | ||
|
|
ede037ade7 | ||
|
|
fa921b3c7b |
+2
-2
@@ -75,7 +75,7 @@ module.system.haste.module_ref_prefix=m#
|
||||
|
||||
react.runtime=automatic
|
||||
|
||||
suppress_type=$FlowFixMe
|
||||
experimental.error_code_migration=new
|
||||
|
||||
ban_spread_key_props=true
|
||||
|
||||
@@ -100,4 +100,4 @@ untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.278.0
|
||||
^0.279.0
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
name: setup-xcode-build-cache
|
||||
description: Add caching to iOS jobs to speed up builds
|
||||
inputs:
|
||||
hermes-version:
|
||||
description: The version of hermes
|
||||
required: true
|
||||
flavor:
|
||||
description: The flavor that is going to be built
|
||||
default: Debug
|
||||
use-frameworks:
|
||||
description: Whether we are bulding with DynamicFrameworks or StaticLibraries
|
||||
default: StaticLibraries
|
||||
ruby-version:
|
||||
description: The ruby version we are going to use
|
||||
default: 2.6.10
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: See commands.yml with_xcodebuild_cache
|
||||
shell: bash
|
||||
run: echo "See commands.yml with_xcodebuild_cache"
|
||||
- name: Cache podfile lock
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: packages/rn-tester/Podfile.lock
|
||||
key: v13-podfilelock-${{ github.job }}-NewArch-${{ inputs.flavor }}-${{ inputs.use-frameworks }}-${{ inputs.ruby-version }}-${{ hashfiles('packages/rn-tester/Podfile') }}-${{ inputs.hermes-version }}
|
||||
- name: Cache cocoapods
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: packages/rn-tester/Pods
|
||||
key: v15-cocoapods-${{ github.job }}-NewArch-${{ inputs.flavor }}-${{ inputs.use-frameworks }}-${{ inputs.ruby-version }}-${{ hashfiles('packages/rn-tester/Podfile.lock') }}-${{ hashfiles('packages/rn-tester/Podfile') }}-${{ inputs.hermes-version}}
|
||||
@@ -102,13 +102,6 @@ runs:
|
||||
- name: Print ReactCore folder
|
||||
shell: bash
|
||||
run: ls -lR /tmp/ReactCore
|
||||
- name: Setup xcode build cache
|
||||
uses: ./.github/actions/setup-xcode-build-cache
|
||||
with:
|
||||
hermes-version: ${{ inputs.hermes-version }}
|
||||
use-frameworks: ${{ inputs.use-frameworks }}
|
||||
flavor: ${{ inputs.flavor }}
|
||||
ruby-version: ${{ inputs.ruby-version }}
|
||||
- name: Install CocoaPods dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
name: test-library-on-nightly
|
||||
description: Tests a library on a nightly
|
||||
inputs:
|
||||
library-npm-package:
|
||||
description: The library npm package to add
|
||||
required: true
|
||||
platform:
|
||||
description: whether we want to build for iOS or Android
|
||||
required: true
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Create new app
|
||||
shell: bash
|
||||
run: |
|
||||
cd /tmp
|
||||
npx @react-native-community/cli init RNApp --skip-install --version nightly
|
||||
- name: Add library
|
||||
shell: bash
|
||||
run: |
|
||||
cd /tmp/RNApp
|
||||
yarn add ${{ inputs.library-npm-package }}
|
||||
|
||||
# iOS
|
||||
- name: Setup xcode
|
||||
if: ${{ inputs.platform == 'ios' }}
|
||||
uses: ./.github/actions/setup-xcode
|
||||
- name: Build iOS
|
||||
shell: bash
|
||||
if: ${{ inputs.platform == 'ios' }}
|
||||
run: |
|
||||
cd /tmp/RNApp/ios
|
||||
bundle install
|
||||
RCT_USE_RN_DEP=1 RCT_USE_PREBUILT_RNCORE=1 bundle exec pod install
|
||||
xcodebuild build \
|
||||
-workspace RNApp.xcworkspace \
|
||||
-scheme RNApp \
|
||||
-sdk iphonesimulator
|
||||
|
||||
# Android
|
||||
- name: Setup Java for Android
|
||||
if: ${{ inputs.platform == 'android' }}
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'zulu'
|
||||
- name: Build Android
|
||||
shell: bash
|
||||
if: ${{ inputs.platform == 'android' }}
|
||||
run: |
|
||||
cd /tmp/RNApp/android
|
||||
./gradlew assembleDebug
|
||||
@@ -1,897 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
FirebaseClient,
|
||||
compareResults,
|
||||
getYesterdayDate,
|
||||
getTodayDate,
|
||||
} = require('../firebaseUtils');
|
||||
|
||||
describe('FirebaseClient', () => {
|
||||
const originalFetch = global.fetch;
|
||||
const originalEnv = process.env;
|
||||
|
||||
beforeEach(() => {
|
||||
global.fetch = jest.fn();
|
||||
process.env = {
|
||||
...originalEnv,
|
||||
FIREBASE_APP_EMAIL: 'test@example.com',
|
||||
FIREBASE_APP_PASS: 'testpassword',
|
||||
FIREBASE_APP_APIKEY: 'test-api-key',
|
||||
FIREBASE_APP_PROJECTNAME: 'test-project',
|
||||
};
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = originalFetch;
|
||||
process.env = originalEnv;
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
it('should initialize with environment variables', () => {
|
||||
const client = new FirebaseClient();
|
||||
expect(client.email).toBe('test@example.com');
|
||||
expect(client.password).toBe('testpassword');
|
||||
expect(client.apiKey).toBe('test-api-key');
|
||||
expect(client.projectId).toBe('test-project');
|
||||
expect(client.databaseUrl).toBe(
|
||||
'test-project-default-rtdb.firebaseio.com',
|
||||
);
|
||||
expect(client.idToken).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('authenticate', () => {
|
||||
it('should authenticate successfully', async () => {
|
||||
const mockResponse = {
|
||||
idToken: 'mock-id-token',
|
||||
refreshToken: 'mock-refresh-token',
|
||||
};
|
||||
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResponse)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
await client.authenticate();
|
||||
|
||||
expect(client.idToken).toBe('mock-id-token');
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=test-api-key',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: 'test@example.com',
|
||||
password: 'testpassword',
|
||||
returnSecureToken: true,
|
||||
}),
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error when email is missing', async () => {
|
||||
delete process.env.FIREBASE_APP_EMAIL;
|
||||
const client = new FirebaseClient();
|
||||
|
||||
await expect(client.authenticate()).rejects.toThrow(
|
||||
'Firebase credentials not found in environment variables',
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error when password is missing', async () => {
|
||||
delete process.env.FIREBASE_APP_PASS;
|
||||
const client = new FirebaseClient();
|
||||
|
||||
await expect(client.authenticate()).rejects.toThrow(
|
||||
'Firebase credentials not found in environment variables',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle authentication failure', async () => {
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 400,
|
||||
text: jest.fn().mockResolvedValueOnce(
|
||||
JSON.stringify({
|
||||
error: {message: 'Invalid credentials'},
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
|
||||
await expect(client.authenticate()).rejects.toThrow(
|
||||
'HTTP 400: Invalid credentials',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makeRequest', () => {
|
||||
it('should make successful GET request', async () => {
|
||||
const mockData = {test: 'data'};
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockData)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
const result = await client.makeRequest('example.com', '/test', 'GET');
|
||||
|
||||
expect(result).toEqual(mockData);
|
||||
expect(global.fetch).toHaveBeenCalledWith('https://example.com/test', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should make successful POST request with data', async () => {
|
||||
const mockData = {success: true};
|
||||
const postData = {test: 'post data'};
|
||||
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockData)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
const result = await client.makeRequest(
|
||||
'example.com',
|
||||
'/test',
|
||||
'POST',
|
||||
postData,
|
||||
);
|
||||
|
||||
expect(result).toEqual(mockData);
|
||||
expect(global.fetch).toHaveBeenCalledWith('https://example.com/test', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(postData),
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle non-JSON response', async () => {
|
||||
const textResponse = 'plain text response';
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(textResponse),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
const result = await client.makeRequest('example.com', '/test', 'GET');
|
||||
|
||||
expect(result).toBe(textResponse);
|
||||
});
|
||||
|
||||
it('should handle HTTP error with JSON error message', async () => {
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 404,
|
||||
text: jest.fn().mockResolvedValueOnce(
|
||||
JSON.stringify({
|
||||
error: {message: 'Not found'},
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
|
||||
await expect(
|
||||
client.makeRequest('example.com', '/test', 'GET'),
|
||||
).rejects.toThrow('HTTP 404: Not found');
|
||||
});
|
||||
|
||||
it('should handle HTTP error with plain text error message', async () => {
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 500,
|
||||
text: jest.fn().mockResolvedValueOnce('Internal Server Error'),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
|
||||
await expect(
|
||||
client.makeRequest('example.com', '/test', 'GET'),
|
||||
).rejects.toThrow('HTTP 500: Internal Server Error');
|
||||
});
|
||||
});
|
||||
|
||||
describe('makeDatabaseRequest', () => {
|
||||
it('should make database request with existing token', async () => {
|
||||
const mockData = {test: 'data'};
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockData)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const result = await client.makeDatabaseRequest('2023-12-01', 'GET');
|
||||
|
||||
expect(result).toEqual(mockData);
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
'https://test-project-default-rtdb.firebaseio.com/nightly-results/2023-12-01.json?auth=existing-token',
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should authenticate before making request if no token exists', async () => {
|
||||
const authResponse = {idToken: 'new-token'};
|
||||
const dataResponse = {test: 'data'};
|
||||
|
||||
global.fetch
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(authResponse)),
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(dataResponse)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
const result = await client.makeDatabaseRequest('2023-12-01', 'GET');
|
||||
|
||||
expect(result).toEqual(dataResponse);
|
||||
expect(global.fetch).toHaveBeenCalledTimes(2);
|
||||
expect(client.idToken).toBe('new-token');
|
||||
});
|
||||
|
||||
it('should make PUT request with data', async () => {
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce('null'),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
const testData = [{library: 'test', status: 'success'}];
|
||||
|
||||
await client.makeDatabaseRequest('2023-12-01', 'PUT', testData);
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
'https://test-project-default-rtdb.firebaseio.com/nightly-results/2023-12-01.json?auth=existing-token',
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(testData),
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('storeResults', () => {
|
||||
it('should store results successfully', async () => {
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce('null'),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
const results = [{library: 'test', status: 'success'}];
|
||||
|
||||
await client.storeResults('2023-12-01', results);
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
'https://test-project-default-rtdb.firebaseio.com/nightly-results/2023-12-01.json?auth=existing-token',
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(results),
|
||||
},
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Successfully stored results for 2023-12-01',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getResults', () => {
|
||||
it('should retrieve results successfully', async () => {
|
||||
const mockResults = [{library: 'test', status: 'success'}];
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResults)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const results = await client.getResults('2023-12-01');
|
||||
|
||||
expect(results).toEqual(mockResults);
|
||||
});
|
||||
|
||||
it('should return null for 404 errors', async () => {
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 404,
|
||||
text: jest.fn().mockResolvedValueOnce('Not Found'),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const results = await client.getResults('2023-12-01');
|
||||
|
||||
expect(results).toBeNull();
|
||||
});
|
||||
|
||||
it('should throw error for non-404 HTTP errors', async () => {
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 500,
|
||||
text: jest.fn().mockResolvedValueOnce('Internal Server Error'),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
await expect(client.getResults('2023-12-01')).rejects.toThrow(
|
||||
'HTTP 500: Internal Server Error',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLatestResults', () => {
|
||||
it('should authenticate before making requests if no token exists', async () => {
|
||||
const authResponse = {idToken: 'new-token'};
|
||||
const mockResults = [{library: 'test', status: 'success'}];
|
||||
|
||||
global.fetch
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(authResponse)),
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResults)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
const result = await client.getLatestResults('2023-12-15', 1);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: mockResults,
|
||||
date: '2023-12-14',
|
||||
});
|
||||
expect(client.idToken).toBe('new-token');
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Checking for results on 2023-12-14 (1 days back)...',
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Found results from 2023-12-14 (1 days back)',
|
||||
);
|
||||
});
|
||||
|
||||
it('should find results from the previous day', async () => {
|
||||
const mockResults = [{library: 'test', status: 'success'}];
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResults)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const result = await client.getLatestResults('2023-12-15', 7);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: mockResults,
|
||||
date: '2023-12-14',
|
||||
});
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Checking for results on 2023-12-14 (1 days back)...',
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Found results from 2023-12-14 (1 days back)',
|
||||
);
|
||||
});
|
||||
|
||||
it('should find results from several days back', async () => {
|
||||
const mockResults = [{library: 'test', status: 'success'}];
|
||||
|
||||
// Mock 404 responses for first 2 days, then success on 3rd day
|
||||
global.fetch
|
||||
.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 404,
|
||||
text: jest.fn().mockResolvedValueOnce('Not Found'),
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 404,
|
||||
text: jest.fn().mockResolvedValueOnce('Not Found'),
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResults)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const result = await client.getLatestResults('2023-12-15', 7);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: mockResults,
|
||||
date: '2023-12-12',
|
||||
});
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Checking for results on 2023-12-14 (1 days back)...',
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Checking for results on 2023-12-13 (2 days back)...',
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Checking for results on 2023-12-12 (3 days back)...',
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Found results from 2023-12-12 (3 days back)',
|
||||
);
|
||||
});
|
||||
|
||||
it('should skip empty results and continue searching', async () => {
|
||||
const mockResults = [{library: 'test', status: 'success'}];
|
||||
|
||||
// Mock empty array for first day, then valid results on second day
|
||||
global.fetch
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify([])),
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResults)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const result = await client.getLatestResults('2023-12-15', 7);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: mockResults,
|
||||
date: '2023-12-13',
|
||||
});
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Checking for results on 2023-12-14 (1 days back)...',
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Checking for results on 2023-12-13 (2 days back)...',
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Found results from 2023-12-13 (2 days back)',
|
||||
);
|
||||
});
|
||||
|
||||
it('should return null when no results found within maxDaysBack', async () => {
|
||||
// Mock 404 responses for all days
|
||||
global.fetch.mockResolvedValue({
|
||||
ok: false,
|
||||
status: 404,
|
||||
text: jest.fn().mockResolvedValue('Not Found'),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const result = await client.getLatestResults('2023-12-15', 3);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: null,
|
||||
date: null,
|
||||
});
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'No previous results found within the last 3 days',
|
||||
);
|
||||
expect(global.fetch).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it('should use default maxDaysBack of 7 when not specified', async () => {
|
||||
// Mock 404 responses for all days
|
||||
global.fetch.mockResolvedValue({
|
||||
ok: false,
|
||||
status: 404,
|
||||
text: jest.fn().mockResolvedValue('Not Found'),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const result = await client.getLatestResults('2023-12-15');
|
||||
|
||||
expect(result).toEqual({
|
||||
results: null,
|
||||
date: null,
|
||||
});
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'No previous results found within the last 7 days',
|
||||
);
|
||||
expect(global.fetch).toHaveBeenCalledTimes(7);
|
||||
});
|
||||
|
||||
it('should handle non-404 errors and continue searching', async () => {
|
||||
const mockResults = [{library: 'test', status: 'success'}];
|
||||
|
||||
// Mock 500 error for first day, then success on second day
|
||||
global.fetch
|
||||
.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 500,
|
||||
text: jest.fn().mockResolvedValueOnce('Internal Server Error'),
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResults)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const result = await client.getLatestResults('2023-12-15', 7);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: mockResults,
|
||||
date: '2023-12-13',
|
||||
});
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'No results found for 2023-12-14: HTTP 500: Internal Server Error',
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Found results from 2023-12-13 (2 days back)',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle date boundaries correctly', async () => {
|
||||
const mockResults = [{library: 'test', status: 'success'}];
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResults)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
// Test month boundary
|
||||
const result = await client.getLatestResults('2023-12-01', 1);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: mockResults,
|
||||
date: '2023-11-30',
|
||||
});
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Checking for results on 2023-11-30 (1 days back)...',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle year boundary correctly', async () => {
|
||||
const mockResults = [{library: 'test', status: 'success'}];
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResults)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
// Test year boundary
|
||||
const result = await client.getLatestResults('2024-01-01', 1);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: mockResults,
|
||||
date: '2023-12-31',
|
||||
});
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Checking for results on 2023-12-31 (1 days back)...',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle null results and continue searching', async () => {
|
||||
const mockResults = [{library: 'test', status: 'success'}];
|
||||
|
||||
// Mock null for first day, then valid results on second day
|
||||
global.fetch
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce('null'),
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValueOnce(JSON.stringify(mockResults)),
|
||||
});
|
||||
|
||||
const client = new FirebaseClient();
|
||||
client.idToken = 'existing-token';
|
||||
|
||||
const result = await client.getLatestResults('2023-12-15', 7);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: mockResults,
|
||||
date: '2023-12-13',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('compareResults', () => {
|
||||
it('should handle null previous results', () => {
|
||||
const currentResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'failed'},
|
||||
{library: 'lib2', platform: 'Android', status: 'success'},
|
||||
];
|
||||
|
||||
const result = compareResults(currentResults, null);
|
||||
|
||||
expect(result).toEqual({
|
||||
broken: [],
|
||||
recovered: [],
|
||||
newFailures: [{library: 'lib1', platform: 'iOS', status: 'failed'}],
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle undefined previous results', () => {
|
||||
const currentResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'failed'},
|
||||
];
|
||||
|
||||
const result = compareResults(currentResults, undefined);
|
||||
|
||||
expect(result).toEqual({
|
||||
broken: [],
|
||||
recovered: [],
|
||||
newFailures: [{library: 'lib1', platform: 'iOS', status: 'failed'}],
|
||||
});
|
||||
});
|
||||
|
||||
it('should identify broken tests', () => {
|
||||
const currentResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'failed'},
|
||||
{library: 'lib2', platform: 'Android', status: 'success'},
|
||||
];
|
||||
|
||||
const previousResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'success'},
|
||||
{library: 'lib2', platform: 'Android', status: 'success'},
|
||||
];
|
||||
|
||||
const result = compareResults(currentResults, previousResults);
|
||||
|
||||
expect(result.broken).toEqual([
|
||||
{
|
||||
library: 'lib1',
|
||||
platform: 'iOS',
|
||||
previousStatus: 'success',
|
||||
currentStatus: 'failed',
|
||||
},
|
||||
]);
|
||||
expect(result.recovered).toEqual([]);
|
||||
});
|
||||
|
||||
it('should identify recovered tests', () => {
|
||||
const currentResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'success'},
|
||||
{library: 'lib2', platform: 'Android', status: 'success'},
|
||||
];
|
||||
|
||||
const previousResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'failed'},
|
||||
{library: 'lib2', platform: 'Android', status: 'success'},
|
||||
];
|
||||
|
||||
const result = compareResults(currentResults, previousResults);
|
||||
|
||||
expect(result.broken).toEqual([]);
|
||||
expect(result.recovered).toEqual([
|
||||
{
|
||||
library: 'lib1',
|
||||
platform: 'iOS',
|
||||
previousStatus: 'failed',
|
||||
currentStatus: 'success',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should identify both broken and recovered tests', () => {
|
||||
const currentResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'failed'},
|
||||
{library: 'lib2', platform: 'Android', status: 'success'},
|
||||
{library: 'lib3', platform: 'iOS', status: 'success'},
|
||||
];
|
||||
|
||||
const previousResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'success'},
|
||||
{library: 'lib2', platform: 'Android', status: 'failed'},
|
||||
{library: 'lib3', platform: 'iOS', status: 'success'},
|
||||
];
|
||||
|
||||
const result = compareResults(currentResults, previousResults);
|
||||
|
||||
expect(result.broken).toEqual([
|
||||
{
|
||||
library: 'lib1',
|
||||
platform: 'iOS',
|
||||
previousStatus: 'success',
|
||||
currentStatus: 'failed',
|
||||
},
|
||||
]);
|
||||
expect(result.recovered).toEqual([
|
||||
{
|
||||
library: 'lib2',
|
||||
platform: 'Android',
|
||||
previousStatus: 'failed',
|
||||
currentStatus: 'success',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should handle tests that are not in previous results', () => {
|
||||
const currentResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'failed'},
|
||||
{library: 'lib2', platform: 'Android', status: 'success'},
|
||||
];
|
||||
|
||||
const previousResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'success'},
|
||||
];
|
||||
|
||||
const result = compareResults(currentResults, previousResults);
|
||||
|
||||
expect(result.broken).toEqual([
|
||||
{
|
||||
library: 'lib1',
|
||||
platform: 'iOS',
|
||||
previousStatus: 'success',
|
||||
currentStatus: 'failed',
|
||||
},
|
||||
]);
|
||||
expect(result.recovered).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle empty current results', () => {
|
||||
const currentResults = [];
|
||||
const previousResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'success'},
|
||||
];
|
||||
|
||||
const result = compareResults(currentResults, previousResults);
|
||||
|
||||
expect(result.broken).toEqual([]);
|
||||
expect(result.recovered).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle empty previous results', () => {
|
||||
const currentResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'failed'},
|
||||
];
|
||||
const previousResults = [];
|
||||
|
||||
const result = compareResults(currentResults, previousResults);
|
||||
|
||||
expect(result.broken).toEqual([]);
|
||||
expect(result.recovered).toEqual([]);
|
||||
// When previousResults is an empty array (not null/undefined),
|
||||
// the function doesn't return newFailures property
|
||||
expect(result.newFailures).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should handle different status values', () => {
|
||||
const currentResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'timeout'},
|
||||
{library: 'lib2', platform: 'Android', status: 'success'},
|
||||
];
|
||||
|
||||
const previousResults = [
|
||||
{library: 'lib1', platform: 'iOS', status: 'success'},
|
||||
{library: 'lib2', platform: 'Android', status: 'error'},
|
||||
];
|
||||
|
||||
const result = compareResults(currentResults, previousResults);
|
||||
|
||||
expect(result.broken).toEqual([
|
||||
{
|
||||
library: 'lib1',
|
||||
platform: 'iOS',
|
||||
previousStatus: 'success',
|
||||
currentStatus: 'timeout',
|
||||
},
|
||||
]);
|
||||
expect(result.recovered).toEqual([
|
||||
{
|
||||
library: 'lib2',
|
||||
platform: 'Android',
|
||||
previousStatus: 'error',
|
||||
currentStatus: 'success',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getYesterdayDate', () => {
|
||||
it("should return yesterday's date in YYYY-MM-DD format", () => {
|
||||
const mockDate = new Date('2023-12-15T10:30:00Z');
|
||||
jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
|
||||
|
||||
const result = getYesterdayDate();
|
||||
|
||||
expect(result).toBe('2023-12-14');
|
||||
|
||||
global.Date.mockRestore();
|
||||
});
|
||||
|
||||
it('should handle month boundary correctly', () => {
|
||||
const mockDate = new Date('2023-12-01T10:30:00Z');
|
||||
jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
|
||||
|
||||
const result = getYesterdayDate();
|
||||
|
||||
expect(result).toBe('2023-11-30');
|
||||
|
||||
global.Date.mockRestore();
|
||||
});
|
||||
|
||||
it('should handle year boundary correctly', () => {
|
||||
const mockDate = new Date('2024-01-01T10:30:00Z');
|
||||
jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
|
||||
|
||||
const result = getYesterdayDate();
|
||||
|
||||
expect(result).toBe('2023-12-31');
|
||||
|
||||
global.Date.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTodayDate', () => {
|
||||
it("should return today's date in YYYY-MM-DD format", () => {
|
||||
const mockDate = new Date('2023-12-15T10:30:00Z');
|
||||
jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
|
||||
|
||||
const result = getTodayDate();
|
||||
|
||||
expect(result).toBe('2023-12-15');
|
||||
|
||||
global.Date.mockRestore();
|
||||
});
|
||||
|
||||
it('should handle different times of day correctly', () => {
|
||||
const mockDate = new Date('2023-12-15T23:59:59Z');
|
||||
jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
|
||||
|
||||
const result = getTodayDate();
|
||||
|
||||
expect(result).toBe('2023-12-15');
|
||||
|
||||
global.Date.mockRestore();
|
||||
});
|
||||
});
|
||||
@@ -1,189 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
prepareFailurePayload,
|
||||
sendMessageToDiscord,
|
||||
} = require('../notifyDiscord');
|
||||
|
||||
describe('prepareFailurePayload', () => {
|
||||
it('should handle undefined failures', () => {
|
||||
const message = prepareFailurePayload(undefined);
|
||||
expect(message).toEqual({
|
||||
content:
|
||||
'⚠️ **React Native Nightly Integration Failures** ⚠️\n\nNo failures to report.',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle empty failures array', () => {
|
||||
const message = prepareFailurePayload([]);
|
||||
expect(message).toEqual({
|
||||
content:
|
||||
'⚠️ **React Native Nightly Integration Failures** ⚠️\n\nNo failures to report.',
|
||||
});
|
||||
});
|
||||
|
||||
it('should format a single failure correctly', () => {
|
||||
const failures = [
|
||||
{
|
||||
library: 'react-native-reanimated',
|
||||
platform: 'iOS',
|
||||
},
|
||||
];
|
||||
|
||||
const message = prepareFailurePayload(failures);
|
||||
expect(message).toEqual({
|
||||
content:
|
||||
'⚠️ **React Native Nightly Integration Failures** ⚠️\n\nThe integration of libraries with React Native nightly failed for the following libraries:\n\n❌ [iOS] react-native-reanimated',
|
||||
});
|
||||
});
|
||||
|
||||
it('should sort multiple failures by platform and library name', () => {
|
||||
const failures = [
|
||||
{
|
||||
library: 'react-native-reanimated',
|
||||
platform: 'iOS',
|
||||
},
|
||||
{
|
||||
library: 'react-native-gesture-handler',
|
||||
platform: 'Android',
|
||||
},
|
||||
{
|
||||
library: 'react-native-screens',
|
||||
platform: 'iOS',
|
||||
},
|
||||
{
|
||||
library: 'react-native-svg',
|
||||
platform: 'Android',
|
||||
},
|
||||
];
|
||||
|
||||
const message = prepareFailurePayload(failures);
|
||||
|
||||
// The failures should be sorted: first Android (alphabetically), then iOS
|
||||
// Within each platform, libraries should be sorted alphabetically
|
||||
expect(message).toEqual({
|
||||
content:
|
||||
'⚠️ **React Native Nightly Integration Failures** ⚠️\n\nThe integration of libraries with React Native nightly failed for the following libraries:\n\n❌ [Android] react-native-gesture-handler\n❌ [Android] react-native-svg\n❌ [iOS] react-native-reanimated\n❌ [iOS] react-native-screens',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle failures with missing properties', () => {
|
||||
const failures = [
|
||||
{
|
||||
// Missing library
|
||||
platform: 'iOS',
|
||||
},
|
||||
{
|
||||
library: 'react-native-gesture-handler',
|
||||
// Missing platform
|
||||
},
|
||||
{
|
||||
// Both missing
|
||||
},
|
||||
];
|
||||
|
||||
const message = prepareFailurePayload(failures);
|
||||
|
||||
expect(message).toEqual({
|
||||
content:
|
||||
'⚠️ **React Native Nightly Integration Failures** ⚠️\n\nThe integration of libraries with React Native nightly failed for the following libraries:\n\n❌ [iOS] Unknown\n❌ [Unknown] react-native-gesture-handler\n❌ [Unknown] Unknown',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sendMessageToDiscord', () => {
|
||||
// Store the original fetch function
|
||||
const originalFetch = global.fetch;
|
||||
|
||||
// Setup and teardown for each test
|
||||
beforeEach(() => {
|
||||
// Mock the global fetch function
|
||||
global.fetch = jest.fn();
|
||||
// Silence console logs during tests
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Restore the original fetch function
|
||||
global.fetch = originalFetch;
|
||||
// Restore console functions
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('should throw an error if webhook URL is missing', async () => {
|
||||
await expect(sendMessageToDiscord(null, {})).rejects.toThrow(
|
||||
'Discord webhook URL is missing',
|
||||
);
|
||||
});
|
||||
|
||||
it('should send a message successfully', async () => {
|
||||
// Mock a successful response
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
status: 200,
|
||||
});
|
||||
|
||||
const webhook = 'https://discord.com/api/webhooks/123/abc';
|
||||
const message = {content: 'Test message'};
|
||||
|
||||
await expect(sendMessageToDiscord(webhook, message)).resolves.not.toThrow();
|
||||
|
||||
// Verify fetch was called with the right arguments
|
||||
expect(global.fetch).toHaveBeenCalledWith(webhook, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(message),
|
||||
});
|
||||
|
||||
// Verify console.log was called
|
||||
expect(console.log).toHaveBeenCalledWith(
|
||||
'Successfully sent message to Discord',
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw an error if the response is not ok', async () => {
|
||||
// Mock a failed response
|
||||
global.fetch.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 400,
|
||||
text: jest.fn().mockResolvedValueOnce('Bad Request'),
|
||||
});
|
||||
|
||||
const webhook = 'https://discord.com/api/webhooks/123/abc';
|
||||
const message = {content: 'Test message'};
|
||||
|
||||
await expect(sendMessageToDiscord(webhook, message)).rejects.toThrow(
|
||||
'HTTP status code: 400',
|
||||
);
|
||||
|
||||
// Verify console.error was called
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
'Failed to send message to Discord: 400 Bad Request',
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw an error if fetch fails', async () => {
|
||||
// Mock a network error
|
||||
const networkError = new Error('Network error');
|
||||
global.fetch.mockRejectedValueOnce(networkError);
|
||||
|
||||
const webhook = 'https://discord.com/api/webhooks/123/abc';
|
||||
const message = {content: 'Test message'};
|
||||
|
||||
await expect(sendMessageToDiscord(webhook, message)).rejects.toThrow(
|
||||
'Network error',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,174 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const {
|
||||
prepareFailurePayload,
|
||||
prepareComparisonPayload,
|
||||
sendMessageToDiscord,
|
||||
} = require('./notifyDiscord');
|
||||
const {
|
||||
FirebaseClient,
|
||||
compareResults,
|
||||
getYesterdayDate,
|
||||
getTodayDate,
|
||||
} = require('./firebaseUtils');
|
||||
|
||||
function readOutcomes() {
|
||||
const baseDir = '/tmp';
|
||||
let outcomes = [];
|
||||
fs.readdirSync(baseDir).forEach(file => {
|
||||
const fullPath = path.join(baseDir, file);
|
||||
if (fullPath.endsWith('outcome') && fs.statSync(fullPath).isDirectory) {
|
||||
fs.readdirSync(fullPath).forEach(subFile => {
|
||||
const subFullPath = path.join(fullPath, subFile);
|
||||
if (subFullPath.endsWith('outcome')) {
|
||||
const [library, status] = String(fs.readFileSync(subFullPath, 'utf8'))
|
||||
.trim()
|
||||
.split(':');
|
||||
const platform = subFile.includes('android') ? 'Android' : 'iOS';
|
||||
console.log(
|
||||
`[${platform}] ${library} completed with status ${status}`,
|
||||
);
|
||||
outcomes.push({
|
||||
library: library.trim(),
|
||||
platform,
|
||||
status: status.trim(),
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (fullPath.endsWith('outcome')) {
|
||||
const [library, status] = String(fs.readFileSync(fullPath, 'utf8'))
|
||||
.trim()
|
||||
.split(':');
|
||||
const platform = file.includes('android') ? 'Android' : 'iOS';
|
||||
console.log(`[${platform}] ${library} completed with status ${status}`);
|
||||
outcomes.push({
|
||||
library: library.trim(),
|
||||
platform,
|
||||
status: status.trim(),
|
||||
});
|
||||
}
|
||||
});
|
||||
return outcomes;
|
||||
}
|
||||
|
||||
function printFailures(outcomes) {
|
||||
console.log('Printing failures...');
|
||||
let failedLibraries = [];
|
||||
outcomes.forEach(entry => {
|
||||
if (entry.status !== 'success') {
|
||||
console.log(
|
||||
`❌ [${entry.platform}] ${entry.library} failed with status ${entry.status}`,
|
||||
);
|
||||
failedLibraries.push({
|
||||
library: entry.library,
|
||||
platform: entry.platform,
|
||||
});
|
||||
}
|
||||
});
|
||||
return failedLibraries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to Discord with the list of failures.
|
||||
* @param {string} webHook - The Discord webhook URL
|
||||
* @param {Array<Object>} failures - List of failures to report
|
||||
* @returns {Promise<void>} - A promise that resolves when the message is sent
|
||||
*/
|
||||
async function notifyDiscord(webHook, failures) {
|
||||
if (!webHook) {
|
||||
console.error('Discord webhook URL is missing');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!failures || failures.length === 0) {
|
||||
console.log('No failures to report to Discord');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Use the prepareFailurePayload function to format the message
|
||||
const message = prepareFailurePayload(failures);
|
||||
|
||||
// Use the sendMessageToDiscord function to send the message
|
||||
await sendMessageToDiscord(webHook, message);
|
||||
} catch (error) {
|
||||
console.error('Error in notifyDiscord function:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function collectResults(discordWebHook) {
|
||||
const outcomes = readOutcomes();
|
||||
const failures = printFailures(outcomes);
|
||||
|
||||
// Send failure notification if there are current failures
|
||||
if (failures.length > 0) {
|
||||
if (discordWebHook) {
|
||||
console.log('Sending current failures to Discord...');
|
||||
await notifyDiscord(discordWebHook, failures);
|
||||
} else {
|
||||
console.log('Discord webhook not set');
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize Firebase client
|
||||
const firebaseClient = new FirebaseClient();
|
||||
const today = getTodayDate();
|
||||
|
||||
try {
|
||||
// Store today's results in Firebase
|
||||
console.log(`Storing results for ${today} in Firebase...`);
|
||||
await firebaseClient.storeResults(today, outcomes);
|
||||
|
||||
// Get the most recent previous results for comparison
|
||||
console.log(`Looking for most recent previous results before ${today}...`);
|
||||
const {results: previousResults, date: previousDate} =
|
||||
await firebaseClient.getLatestResults(today);
|
||||
|
||||
let broken = [];
|
||||
let recovered = [];
|
||||
|
||||
if (previousResults) {
|
||||
console.log(`Comparing with results from ${previousDate}`);
|
||||
// Compare results and identify broken/recovered jobs
|
||||
const comparison = compareResults(outcomes, previousResults);
|
||||
broken = comparison.broken;
|
||||
recovered = comparison.recovered;
|
||||
|
||||
console.log(
|
||||
`Found ${broken.length} newly broken jobs and ${recovered.length} recovered jobs compared to ${previousDate}`,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
'No previous results found for comparison - this might be the first run or no recent data available',
|
||||
);
|
||||
}
|
||||
|
||||
// Send comparison message to Discord if there are changes
|
||||
if (discordWebHook && (broken.length > 0 || recovered.length > 0)) {
|
||||
console.log('Sending comparison results to Discord...');
|
||||
const comparisonMessage = prepareComparisonPayload(broken, recovered);
|
||||
await sendMessageToDiscord(discordWebHook, comparisonMessage);
|
||||
}
|
||||
|
||||
console.log('✅ All tests passed!');
|
||||
} catch (error) {
|
||||
console.error('Error in collectResults:', error);
|
||||
// If Firebase fails but there are no test failures, don't fail the workflow
|
||||
console.log('⚠️ Firebase operations failed, but all tests passed');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
collectResults,
|
||||
notifyDiscord,
|
||||
};
|
||||
@@ -1,261 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
// We connect to firebase using a plain HTTP request because we don't want to
|
||||
// add yet another devDependency to the react-native monorepo.
|
||||
class FirebaseClient {
|
||||
constructor() {
|
||||
this.email = process.env.FIREBASE_APP_EMAIL;
|
||||
this.password = process.env.FIREBASE_APP_PASS;
|
||||
this.apiKey = process.env.FIREBASE_APP_APIKEY;
|
||||
this.projectId = process.env.FIREBASE_APP_PROJECTNAME;
|
||||
this.databaseUrl = `${this.projectId}-default-rtdb.firebaseio.com`;
|
||||
this.idToken = null;
|
||||
}
|
||||
|
||||
async authenticate() {
|
||||
if (!this.email || !this.password) {
|
||||
throw new Error(
|
||||
'Firebase credentials not found in environment variables',
|
||||
);
|
||||
}
|
||||
|
||||
const authData = {
|
||||
email: this.email,
|
||||
password: this.password,
|
||||
returnSecureToken: true,
|
||||
};
|
||||
|
||||
const response = await this.makeRequest(
|
||||
'identitytoolkit.googleapis.com',
|
||||
`/v1/accounts:signInWithPassword?key=${this.apiKey}`,
|
||||
'POST',
|
||||
authData,
|
||||
);
|
||||
|
||||
this.idToken = response.idToken;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a database request for a specific date
|
||||
* @param {string} date - Date in YYYY-MM-DD format
|
||||
* @param {string} method - HTTP method
|
||||
* @param {*} data - Data to send (optional)
|
||||
* @returns {Promise<*>} - Response data
|
||||
*/
|
||||
async makeDatabaseRequest(date, method, data = null) {
|
||||
if (!this.idToken) {
|
||||
await this.authenticate();
|
||||
}
|
||||
|
||||
const path = `/nightly-results/${date}.json?auth=${this.idToken}`;
|
||||
return this.makeRequest(this.databaseUrl, path, method, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store test results for a specific date
|
||||
* @param {string} date - Date in YYYY-MM-DD format
|
||||
* @param {Array<Object>} results - Array of test results
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async storeResults(date, results) {
|
||||
await this.makeDatabaseRequest(date, 'PUT', results);
|
||||
console.log(`Successfully stored results for ${date}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve test results for a specific date
|
||||
* @param {string} date - Date in YYYY-MM-DD format
|
||||
* @returns {Promise<Array<Object>|null>} - Array of test results or null if not found
|
||||
*/
|
||||
async getResults(date) {
|
||||
try {
|
||||
return await this.makeDatabaseRequest(date, 'GET');
|
||||
} catch (error) {
|
||||
if (error.message.includes('404')) {
|
||||
return null; // No results found for this specific date.
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the most recent available job results before the given date
|
||||
* @param {string} currentDate - Current date in YYYY-MM-DD format
|
||||
* @param {number} maxDaysBack - Maximum number of days to look back (default: 7)
|
||||
* @returns {Promise<{results: Array<Object>|null, date: string|null}>} - Most recent results and their date
|
||||
*/
|
||||
async getLatestResults(currentDate, maxDaysBack = 7) {
|
||||
if (!this.idToken) {
|
||||
await this.authenticate();
|
||||
}
|
||||
|
||||
const currentDateObj = new Date(currentDate);
|
||||
|
||||
for (let daysBack = 1; daysBack <= maxDaysBack; daysBack++) {
|
||||
const checkDate = new Date(currentDateObj);
|
||||
checkDate.setDate(checkDate.getDate() - daysBack);
|
||||
const checkDateStr = checkDate.toISOString().split('T')[0];
|
||||
|
||||
console.log(
|
||||
`Checking for results on ${checkDateStr} (${daysBack} days back)...`,
|
||||
);
|
||||
|
||||
try {
|
||||
const results = await this.getResults(checkDateStr);
|
||||
if (results && results.length > 0) {
|
||||
console.log(
|
||||
`Found results from ${checkDateStr} (${daysBack} days back)`,
|
||||
);
|
||||
return {results, date: checkDateStr};
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`No results found for ${checkDateStr}: ${error.message}`);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`No previous results found within the last ${maxDaysBack} days`,
|
||||
);
|
||||
return {results: null, date: null};
|
||||
}
|
||||
|
||||
async makeRequest(hostname, path, method, data = null) {
|
||||
const url = `https://${hostname}${path}`;
|
||||
const options = {
|
||||
method,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
};
|
||||
|
||||
if (data) {
|
||||
options.body = JSON.stringify(data);
|
||||
}
|
||||
|
||||
const response = await fetch(url, options);
|
||||
const responseText = await response.text();
|
||||
|
||||
if (!response.ok) {
|
||||
let errorMessage;
|
||||
try {
|
||||
const parsedError = JSON.parse(responseText);
|
||||
errorMessage = parsedError.error?.message || responseText;
|
||||
} catch {
|
||||
errorMessage = responseText;
|
||||
}
|
||||
throw new Error(`HTTP ${response.status}: ${errorMessage}`);
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(responseText);
|
||||
} catch {
|
||||
return responseText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare current results with previous day's results
|
||||
* @param {Array<Object>} currentResults - Today's test results
|
||||
* @param {Array<Object>} previousResults - Yesterday's test results
|
||||
* @returns {Object} - Object containing broken and recovered tests
|
||||
*/
|
||||
function compareResults(currentResults, previousResults) {
|
||||
if (!previousResults) {
|
||||
return {
|
||||
broken: [],
|
||||
recovered: [],
|
||||
newFailures: currentResults.filter(result => result.status !== 'success'),
|
||||
};
|
||||
}
|
||||
|
||||
// Create maps for easier lookup
|
||||
const currentMap = new Map();
|
||||
const previousMap = new Map();
|
||||
|
||||
currentResults.forEach(result => {
|
||||
const key = `${result.library}-${result.platform}`;
|
||||
currentMap.set(key, result);
|
||||
});
|
||||
|
||||
previousResults.forEach(result => {
|
||||
const key = `${result.library}-${result.platform}`;
|
||||
previousMap.set(key, result);
|
||||
});
|
||||
|
||||
const broken = [];
|
||||
const recovered = [];
|
||||
|
||||
// Check for broken tests (was success, now failed)
|
||||
for (const [key, currentResult] of currentMap) {
|
||||
const previousResult = previousMap.get(key);
|
||||
if (previousResult) {
|
||||
if (
|
||||
previousResult.status === 'success' &&
|
||||
currentResult.status !== 'success'
|
||||
) {
|
||||
broken.push({
|
||||
library: currentResult.library,
|
||||
platform: currentResult.platform,
|
||||
previousStatus: previousResult.status,
|
||||
currentStatus: currentResult.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for recovered tests (was failed, now success)
|
||||
for (const [key, currentResult] of currentMap) {
|
||||
const previousResult = previousMap.get(key);
|
||||
if (previousResult) {
|
||||
if (
|
||||
previousResult.status !== 'success' &&
|
||||
currentResult.status === 'success'
|
||||
) {
|
||||
recovered.push({
|
||||
library: currentResult.library,
|
||||
platform: currentResult.platform,
|
||||
previousStatus: previousResult.status,
|
||||
currentStatus: currentResult.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {broken, recovered};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get yesterday's date in YYYY-MM-DD format
|
||||
* @returns {string} - Yesterday's date
|
||||
*/
|
||||
function getYesterdayDate() {
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
return yesterday.toISOString().split('T')[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get today's date in YYYY-MM-DD format
|
||||
* @returns {string} - Today's date
|
||||
*/
|
||||
function getTodayDate() {
|
||||
const today = new Date();
|
||||
return today.toISOString().split('T')[0];
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
FirebaseClient,
|
||||
compareResults,
|
||||
getYesterdayDate,
|
||||
getTodayDate,
|
||||
};
|
||||
@@ -87,11 +87,11 @@ async function launchAppOnSimulator(appId, udid, isDebug) {
|
||||
|
||||
function startVideoRecording(jsengine, currentAttempt) {
|
||||
console.log(
|
||||
`Start video record using pid: video_record_${jsengine}_${currentAttempt}.pid`,
|
||||
`Start video record using pid: video_record_${currentAttempt}.pid`,
|
||||
);
|
||||
|
||||
const recordingArgs =
|
||||
`simctl io booted recordVideo video_record_${jsengine}_${currentAttempt}.mov`.split(
|
||||
`simctl io booted recordVideo video_record_${currentAttempt}.mov`.split(
|
||||
' ',
|
||||
);
|
||||
const recordingProcess = childProcess.spawn('xcrun', recordingArgs, {
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sends a message to Discord using the webhook URL.
|
||||
* @param {string} webHook - The Discord webhook URL
|
||||
* @param {Object} message - The message to send
|
||||
* @returns {Promise<void>} - A promise that resolves when the message is sent
|
||||
*/
|
||||
async function sendMessageToDiscord(webHook, message) {
|
||||
if (!webHook) {
|
||||
throw new Error('Discord webhook URL is missing');
|
||||
}
|
||||
|
||||
// Send the request using fetch
|
||||
const response = await fetch(webHook, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(message),
|
||||
});
|
||||
|
||||
// Handle the response
|
||||
if (response.ok) {
|
||||
console.log('Successfully sent message to Discord');
|
||||
return;
|
||||
} else {
|
||||
const errorText = await response.text();
|
||||
console.error(
|
||||
`Failed to send message to Discord: ${response.status} ${errorText}`,
|
||||
);
|
||||
throw new Error(`HTTP status code: ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts jobs by platform first, then by library name.
|
||||
* @param {Array<Object>} jobs - Array of jobs with platform and library properties
|
||||
* @returns {Array<Object>} - Sorted array of jobs
|
||||
*/
|
||||
function sortResultsByPlatformAndLibrary(jobs) {
|
||||
return [...jobs].sort((a, b) => {
|
||||
// First sort by platform
|
||||
const platformA = a.platform || 'Unknown';
|
||||
const platformB = b.platform || 'Unknown';
|
||||
|
||||
if (platformA !== platformB) {
|
||||
return platformA.localeCompare(platformB);
|
||||
}
|
||||
|
||||
// Then sort by library name
|
||||
const libraryA = a.library || 'Unknown';
|
||||
const libraryB = b.library || 'Unknown';
|
||||
return libraryA.localeCompare(libraryB);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a formatted Discord message payload from a list of failures.
|
||||
* @param {Array<Object>} failures - List of failures to format
|
||||
* @returns {Object} - The formatted Discord message payload
|
||||
*/
|
||||
function prepareFailurePayload(failures) {
|
||||
if (!failures || failures.length === 0) {
|
||||
return {
|
||||
content:
|
||||
'⚠️ **React Native Nightly Integration Failures** ⚠️\n\nNo failures to report.',
|
||||
};
|
||||
}
|
||||
|
||||
// Sort failures by platform and then by library name
|
||||
const sortedFailures = sortResultsByPlatformAndLibrary(failures);
|
||||
|
||||
// Format the failures into a message
|
||||
const formattedFailures = sortedFailures
|
||||
.map(failure => {
|
||||
const library = failure.library || 'Unknown';
|
||||
const platform = failure.platform || 'Unknown';
|
||||
return `❌ [${platform}] ${library}`;
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
return {
|
||||
content: `⚠️ **React Native Nightly Integration Failures** ⚠️\n\nThe integration of libraries with React Native nightly failed for the following libraries:\n\n${formattedFailures}`,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a formatted Discord message payload for broken and recovered nightly jobs.
|
||||
* @param {Array<Object>} broken - List of newly broken jobs
|
||||
* @param {Array<Object>} recovered - List of recovered jobs
|
||||
* @returns {Object} - The formatted Discord message payload
|
||||
*/
|
||||
function prepareComparisonPayload(broken, recovered) {
|
||||
let content = '📊 **React Native Nightly Integration Status Update** 📊\n\n';
|
||||
|
||||
if (broken.length === 0 && recovered.length === 0) {
|
||||
content +=
|
||||
'No changes from yesterday - all nightly jobs maintained their previous status.';
|
||||
} else {
|
||||
if (broken.length > 0) {
|
||||
content += '🔴 **Newly Broken Jobs:**\n';
|
||||
const sortedBroken = sortResultsByPlatformAndLibrary(broken);
|
||||
|
||||
sortedBroken.forEach(job => {
|
||||
content += `❌ [${job.platform}] ${job.library} (was ${job.previousStatus}, now ${job.currentStatus})\n`;
|
||||
});
|
||||
content += '\n';
|
||||
}
|
||||
|
||||
if (recovered.length > 0) {
|
||||
content += '🟢 **Recovered Jobs:**\n';
|
||||
const sortedRecovered = sortResultsByPlatformAndLibrary(recovered);
|
||||
|
||||
sortedRecovered.forEach(job => {
|
||||
content += `✅ [${job.platform}] ${job.library} (was ${job.previousStatus}, now ${job.currentStatus})\n`;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {content};
|
||||
}
|
||||
|
||||
// Export the functions using CommonJS syntax
|
||||
module.exports = {
|
||||
prepareFailurePayload,
|
||||
prepareComparisonPayload,
|
||||
sendMessageToDiscord,
|
||||
};
|
||||
@@ -1,38 +0,0 @@
|
||||
# This jobs runs every day 2 hours after the nightly job and its purpose is to report
|
||||
# a failure in case the nightly failed to be published. We are going to hook this to an internal automation.
|
||||
name: Check Nightlies
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
# nightly build @ 4:15 AM UTC
|
||||
schedule:
|
||||
- cron: '15 4 * * *'
|
||||
|
||||
jobs:
|
||||
check-nightly:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Check nightly
|
||||
run: |
|
||||
TODAY=$(date "+%Y%m%d")
|
||||
echo "Checking nightly for $TODAY"
|
||||
NIGHTLY="$(npm view react-native | grep $TODAY)"
|
||||
if [[ -z $NIGHTLY ]]; then
|
||||
echo 'Nightly job failed.'
|
||||
exit 1
|
||||
else
|
||||
echo 'Nightly Worked, All Good!'
|
||||
fi
|
||||
|
||||
test-libraries:
|
||||
uses: ./.github/workflows/test-libraries-on-nightlies.yml
|
||||
needs: check-nightly
|
||||
secrets:
|
||||
discord_webhook_url: ${{ secrets.NIGHTLY_DISCORD_WEBHOOK }}
|
||||
firebase_app_email: ${{ secrets.FIREBASE_APP_EMAIL }}
|
||||
firebase_app_pass: ${{ secrets.FIREBASE_APP_PASS }}
|
||||
firebase_app_projectname: ${{ secrets.FIREBASE_APP_PROJECTNAME }}
|
||||
firebase_app_apikey: ${{ secrets.FIREBASE_APP_APIKEY }}
|
||||
@@ -246,6 +246,11 @@ jobs:
|
||||
- name: Print ReactCore folder
|
||||
shell: bash
|
||||
run: ls -lR /tmp/ReactCore
|
||||
- name: Configure git
|
||||
shell: bash
|
||||
run: |
|
||||
git config --global user.email "react-native-bot@meta.com"
|
||||
git config --global user.name "React Native Bot"
|
||||
- name: Prepare artifacts
|
||||
run: |
|
||||
REACT_NATIVE_PKG=$(find /tmp/react-native-tmp -type f -name "*.tgz")
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
name: Test Libraries on Nightlies
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
secrets:
|
||||
discord_webhook_url:
|
||||
required: true
|
||||
firebase_app_email:
|
||||
required: true
|
||||
firebase_app_pass:
|
||||
required: true
|
||||
firebase_app_apikey:
|
||||
required: true
|
||||
firebase_app_projectname:
|
||||
required: true
|
||||
|
||||
|
||||
# We use the matrix.library entry to specify the dependency we want to use
|
||||
# The key is used directly as the <pkg> in the `yarn add <pkg>` command.
|
||||
jobs:
|
||||
runner-setup:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
runners: '{"ios":"macos-14-large", "android": "ubuntu-latest"}'
|
||||
steps:
|
||||
- run: echo no-op
|
||||
|
||||
test-library-on-nightly:
|
||||
name: "[${{ matrix.platform }}] ${{ matrix.library }}"
|
||||
needs: runner-setup
|
||||
runs-on: ${{ fromJSON(needs.runner-setup.outputs.runners)[matrix.platform] }}
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
library: [
|
||||
"react-native-async-storage",
|
||||
"react-native-blob-util",
|
||||
"@react-native-clipboard/clipboard",
|
||||
"@react-native-community/datetimepicker",
|
||||
"react-native-gesture-handler",
|
||||
"react-native-image-picker",
|
||||
"react-native-linear-gradient",
|
||||
"@react-native-masked-view/masked-view",
|
||||
# "react-native-maps", React Native Maps with the New Arch support has a complex cocoapods setup for iOS. It needs a dedicated workflow.
|
||||
"@react-native-community/netinfo",
|
||||
"react-native-reanimated@nightly react-native-worklets@nightly", #reanimated requires worklet to be explicitly installed as a separate package
|
||||
"react-native-svg",
|
||||
"react-native-video",
|
||||
"react-native-webview",
|
||||
"react-native-mmkv",
|
||||
"react-native-screens",
|
||||
"react-native-pager-view",
|
||||
"@react-native-community/slider",
|
||||
# additional OSS libs used internally
|
||||
"scandit-react-native-datacapture-barcode scandit-react-native-datacapture-core",
|
||||
"react-native-contacts",
|
||||
"react-native-device-info",
|
||||
"react-native-email-link",
|
||||
"@dr.pogodin/react-native-fs",
|
||||
"react-native-permissions",
|
||||
"react-native-vector-icons",
|
||||
"react-native-masked-view",
|
||||
"@react-native-community/image-editor",
|
||||
]
|
||||
platform: [ios, android]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
- name: Test ${{ matrix.library }}
|
||||
id: run-test
|
||||
uses: ./.github/actions/test-library-on-nightly
|
||||
with:
|
||||
library-npm-package: ${{ matrix.library }}
|
||||
platform: ${{ matrix.platform}}
|
||||
- name: Save outcome
|
||||
id: save-outcome
|
||||
if: always()
|
||||
run: |
|
||||
LIB_FOLDER=$(echo "${{matrix.library}}" | tr ' ' '_' | tr '/' '_')
|
||||
echo "${{matrix.library}}: ${{steps.run-test.outcome}}" > "/tmp/$LIB_FOLDER-${{ matrix.platform }}-outcome"
|
||||
echo "lib_folder=$LIB_FOLDER" >> $GITHUB_OUTPUT
|
||||
- name: Upload Artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.save-outcome.outputs.lib_folder }}-${{ matrix.platform }}-outcome
|
||||
path: /tmp/${{ steps.save-outcome.outputs.lib_folder }}-${{ matrix.platform }}-outcome
|
||||
|
||||
|
||||
collect-results:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test-library-on-nightly]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Restore outcomes
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: '*-outcome'
|
||||
path: /tmp
|
||||
- name: Collect failures
|
||||
uses: actions/github-script@v6
|
||||
env:
|
||||
FIREBASE_APP_EMAIL: ${{ secrets.firebase_app_email }}
|
||||
FIREBASE_APP_PASS: ${{ secrets.firebase_app_pass }}
|
||||
FIREBASE_APP_APIKEY: ${{ secrets.firebase_app_apikey }}
|
||||
FIREBASE_APP_PROJECTNAME: ${{ secrets.firebase_app_projectname }}
|
||||
with:
|
||||
script: |
|
||||
const {collectResults} = require('./.github/workflow-scripts/collectNightlyOutcomes.js');
|
||||
await collectResults('${{secrets.discord_webhook_url}}');
|
||||
@@ -1,5 +1,27 @@
|
||||
# Changelog (pre 0.80)
|
||||
|
||||
## v0.79.6
|
||||
|
||||
### Added
|
||||
|
||||
#### Android specific
|
||||
|
||||
- **RNGP** Add support for `exclusiveEnterpriseRepository` ([df5ac988ce](https://github.com/facebook/react-native/commit/df5ac988cec936c430d41b0fcc15181dc06e46a1) by [@cortinico](https://github.com/cortinico))
|
||||
|
||||
#### iOS specific
|
||||
|
||||
- **Cocoapods:** Add the ENTERPRISE_REPOSITORY env var to let user consume artifacts from their personal maven mirror ([a74d930c93](https://github.com/facebook/react-native/commit/a74d930c93ffae8c02142e8cc016a4c390a5f784) by [@cipolleschi](https://github.com/cipolleschi))
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Codegen:** Add missing Babel dependencies ([bf2c3af93b](https://github.com/facebook/react-native/commit/bf2c3af93b146943cb35866fa9badcd188e63f5b) by [@tido64](https://github.com/tido64))
|
||||
|
||||
#### Android specific
|
||||
|
||||
- **Legacy Arch:** Fix Legacy arch crashing or freezing upon reload ([db600b2e9e](https://github.com/facebook/react-native/commit/db600b2e9e87863cad6dd5ce262dc1f793bcaeb0) by [@robhogan](https://github.com/robhogan))
|
||||
- **Modal:** Fix Modal first frame being rendered on top-left corner ([5a315f8d6b](https://github.com/facebook/react-native/commit/5a315f8d6b0ea54442c7ef94b7346b0c73fd0b4c) by [@cortinico](https://github.com/cortinico))
|
||||
- **TurboModule:** Fix emitting event from turbo module crashes on 32bit android ([43bc43e5e8](https://github.com/facebook/react-native/commit/43bc43e5e85519d2924c4fc80765e66d0c48b1a9) by [@vladimirivanoviliev](https://github.com/vladimirivanoviliev))
|
||||
|
||||
## v0.79.5
|
||||
|
||||
### Fixed
|
||||
|
||||
+24
-73
@@ -1,71 +1,6 @@
|
||||
# Changelog
|
||||
|
||||
## v0.81.0-rc.5
|
||||
|
||||
### Fixed
|
||||
|
||||
#### Android specific
|
||||
- **Runtime:** Fixed `ReactHostImpl.nativeModules` always returning an empty list ([2f46a49](https://github.com/facebook/react-native/commit/2f46a49b8d8a11d5cf4342eee83c469b545c6779) by [@lukmccall](https://github.com/lukmccall))
|
||||
|
||||
## v0.81.0-rc.4 - Burned
|
||||
|
||||
## v0.81.0-rc.3
|
||||
|
||||
### Changed
|
||||
|
||||
- **Metro:** Metro to ^0.83.1 ([e247be793c](https://github.com/facebook/react-native/commit/e247be793c70a374955d798d8cbbc6eba58080ec) by [@motiz88](https://github.com/motiz88))
|
||||
|
||||
### Fixed
|
||||
|
||||
#### Android specific
|
||||
|
||||
- **rngp:** Fix a race condition with codegen libraries missing sources ([9013a9e666](https://github.com/facebook/react-native/commit/9013a9e66629677c47e1b69703f9fc8f4cbc1c2c) by [@cortinico](https://github.com/cortinico))
|
||||
- **API:** Make accessors inside HeadlessJsTaskService open again ([7ef57163cb](https://github.com/facebook/react-native/commit/7ef57163cb016317e43e563da7ea181989f6abca) by [@cortinico](https://github.com/cortinico))
|
||||
|
||||
## v0.81.0-rc.2
|
||||
|
||||
### Changed
|
||||
|
||||
- **API:** `NewAppScreen` no longer internally handles device safe area, use optional `safeAreaInsets` prop (aligned in 0.81 template) ([732bd12dc2](https://github.com/facebook/react-native/commit/732bd12dc21460641ef01b23f2eb722f26b060d5) by [@huntie](https://github.com/huntie))
|
||||
- **Babel:** Added support to `react-native/babel-preset` for a `hermesParserOptions` option, that expects an object that enables overriding `hermes-parser` options. ([0508eddfe6](https://github.com/facebook/react-native/commit/0508eddfe60df60cb3bfa4074ae199bd0e492d5f) by [@yungsters](https://github.com/yungsters))
|
||||
|
||||
### Fixed
|
||||
|
||||
#### iOS specific
|
||||
|
||||
- **Podspec:** Fixed issue with RNDeps release/debug switch failing ([4ee2b60a1e](https://github.com/facebook/react-native/commit/4ee2b60a1eacca744d58a7ad336ca9d3714289f6) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Podspec:** Fixed missing script for resolving prebuilt xcframework when switching between release/debug ([2e55241a90](https://github.com/facebook/react-native/commit/2e55241a901b4cd95917de68ce9078928820a208) by [@chrfalch](https://github.com/chrfalch))
|
||||
|
||||
## v0.81.0-rc.1
|
||||
|
||||
### Added
|
||||
|
||||
#### iOS specific
|
||||
|
||||
- **CocoaPods** Add the `ENTERPRISE_REPOSITORY` env variable to cocoapods infra ([23f3bf9239](https://github.com/facebook/react-native/commit/23f3bf9239a849590f1c72b25732d0090780128c) by [@cipolleschi](https://github.com/cipolleschi))
|
||||
- **Prebuild:** Add release/debug switch script for React-Core-prebuilt ([42d1a7934c](https://github.com/facebook/react-native/commit/42d1a7934cad4b2c92653e3fa7781c2af8f44df4) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Prebuild:** Added support for using USE_FRAMEWORKS with prebuilt React Native Core ([40e45f5366](https://github.com/facebook/react-native/commit/40e45f53661ce80c3a6fbbf07f52dc900afcad52) by [@chrfalch](https://github.com/chrfalch))
|
||||
|
||||
### Changed
|
||||
|
||||
- **Metro:** Bump Metro to 0.83.0 ([6b9f5d622f](https://github.com/facebook/react-native/commit/6b9f5d622ffbe79da8f4e7b7d8094504a480425e) by [@robhogan](https://github.com/robhogan))
|
||||
|
||||
#### Android specific
|
||||
|
||||
- **Gradle:** Gradle to 8.14.3 ([6892dde363](https://github.com/facebook/react-native/commit/6892dde36373bbef2d0afe535ae818b1a7164f08) by [@cortinico](https://github.com/cortinico))
|
||||
- **Gradle:** Expose `react_renderer_bridging` headers via prefab ([d1730ff960](https://github.com/facebook/react-native/commit/d1730ff960fcb9a01ee94b9e46e5a9fbb7d73f4a) by [@tomekzaw](https://github.com/tomekzaw))
|
||||
- **Legacy Arch:** Introduce more deprecation warnings for Legacy Arch classes ([625f69f284](https://github.com/facebook/react-native/commit/625f69f284ddfd9c6beecaa4052a871d092053ef) by [@cortinico](https://github.com/cortinico))
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Yoga:** Fixed nodes with `display: contents` set being cloned with the wrong owner ([d4b36b0300](https://github.com/facebook/react-native/commit/d4b36b03003eb2de9eaf5b57bb639bae8cc12f20) by [@j-piasecki](https://github.com/j-piasecki))
|
||||
|
||||
#### iOS specific
|
||||
|
||||
- **Podspec:** Fixed premature return in header file generation from podspec globs ([f2b064c2d4](https://github.com/facebook/react-native/commit/f2b064c2d40c39017ac2a31bf3caf8acef23038c) by [@chrfalch](https://github.com/chrfalch))
|
||||
|
||||
|
||||
## v0.81.0-rc.0
|
||||
## v0.81.0
|
||||
|
||||
### Breaking
|
||||
|
||||
@@ -126,6 +61,7 @@
|
||||
#### iOS specific
|
||||
|
||||
- **borderWidth:** Add support for different `borderWidth`s ([70962ef3ed](https://github.com/facebook/react-native/commit/70962ef3ed06a76a96cb2e72c374dc028628c829) by [@a-klotz-p8](https://github.com/a-klotz-p8))
|
||||
- **CocoaPods:** Add the `ENTERPRISE_REPOSITORY` env variable to cocoapods infra ([23f3bf9239](https://github.com/facebook/react-native/commit/23f3bf9239a849590f1c72b25732d0090780128c) by [@cipolleschi](https://github.com/cipolleschi))
|
||||
- **Modal:** Allow to interactively swipe down `Modal`s. ([28986a7599](https://github.com/facebook/react-native/commit/28986a7599952a77b8b8e433f72ca837afde310e) by [@okwasniewski](https://github.com/okwasniewski))
|
||||
- **Package.swift:** Added missing search path to `Package.swift` ([592b09781b](https://github.com/facebook/react-native/commit/592b09781bb94fe6dc00ba49c7a86649980fed5d) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Prebuild:** Add more logging around `computeNightlyTarballURL` in ios pre-build ([1a6887bd70](https://github.com/facebook/react-native/commit/1a6887bd70cdefb8fbc421467de841ece74d5c6b) by [@cortinico](https://github.com/cortinico))
|
||||
@@ -136,13 +72,17 @@
|
||||
- **Prebuild:** Added building `XCFframework` from the prebuild script ([55534f518a](https://github.com/facebook/react-native/commit/55534f518aab53bcdc3fe12d987ab7ef6e620c77) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Prebuild:** Added building swift package from the prebuild script ([3c01b1b6f0](https://github.com/facebook/react-native/commit/3c01b1b6f04d285c97bb182131135903b0c1cdd5) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Prebuild:** Added downloading of hermes artifacts when pre-building for iOS. ([41d2b5de0a](https://github.com/facebook/react-native/commit/41d2b5de0af21c72227ef030dcddf208e2eb221a) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Prebuild:** Add release/debug switch script for React-Core-prebuilt ([42d1a7934c](https://github.com/facebook/react-native/commit/42d1a7934cad4b2c92653e3fa7781c2af8f44df4) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Prebuild:** Added support for using USE_FRAMEWORKS with prebuilt React Native Core ([40e45f5366](https://github.com/facebook/react-native/commit/40e45f53661ce80c3a6fbbf07f52dc900afcad52) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **runtime:** Added `HERMES_ENABLE_DEBUGGER` to debug configuration for the `reactRuntime` target. ([560ac23001](https://github.com/facebook/react-native/commit/560ac23001b02f19d4c6ca4ea493c17060cfaf5f) by [@chrfalch](https://github.com/chrfalch))
|
||||
|
||||
### Changed
|
||||
|
||||
- **API:** `NewAppScreen` no longer internally handles device safe area, use optional `safeAreaInsets` prop (aligned in 0.81 template) ([732bd12dc2](https://github.com/facebook/react-native/commit/732bd12dc21460641ef01b23f2eb722f26b060d5) by [@huntie](https://github.com/huntie))
|
||||
- **Animated:** Animated now always flattens `props.style`, which fixes an error that results from `props.style` objects in which `AnimatedNode` instances are shadowed (i.e. flattened to not exist in the resulting `props.style` object). ([da520848c9](https://github.com/facebook/react-native/commit/da520848c931f356d013623c412af11dce7ff114) by [@yungsters](https://github.com/yungsters))
|
||||
- **Animated:** Creates a feature flag that changes `Animated` to no longer produce invalid `props.style` if every `AnimatedNode` instance is shadowed via style flattening. ([5c8c5388fc](https://github.com/facebook/react-native/commit/5c8c5388fc53ef2430b0bb6bbbc628479819e23d) by [@yungsters](https://github.com/yungsters))
|
||||
- **Animated:** Enabled a feature flag that optimizes `Animated` to reduce memory usage. ([2a13d20085](https://github.com/facebook/react-native/commit/2a13d200850e4f161a29b252a0ccedc158e53937) by [@yungsters](https://github.com/yungsters))
|
||||
- **Babel:** Added support to `react-native/babel-preset` for a `hermesParserOptions` option, that expects an object that enables overriding `hermes-parser` options. ([0508eddfe6](https://github.com/facebook/react-native/commit/0508eddfe60df60cb3bfa4074ae199bd0e492d5f) by [@yungsters](https://github.com/yungsters))
|
||||
- **Error handling:** Errors will no longer have the "js engine" suffix. ([a293925280](https://github.com/facebook/react-native/commit/a2939252803d5cd4b68340da08820174c30a53e6) by [@yungsters](https://github.com/yungsters))
|
||||
- **Fibers:** Reduces memory usage, by improving memory management of parent alternate fibers. (Previously, a parent fiber might retain memory associated with shadow nodes from a previous commit.) ([0411c43b3a](https://github.com/facebook/react-native/commit/0411c43b3a239384c778baad22c7b4c501008449) by [@yungsters](https://github.com/yungsters))
|
||||
- **infoLog:** Removed `infoLog` from `react-native` package ([8a0cfec815](https://github.com/facebook/react-native/commit/8a0cfec81584e966c9e6ea0f5e438022e0129bcd) by [@coado](https://github.com/coado))
|
||||
@@ -150,24 +90,26 @@
|
||||
- **Jest:** Improved default mocking for Jest unit tests. ([1fd9508ecc](https://github.com/facebook/react-native/commit/1fd9508ecc499df89b086e0c46035f43f6f78ad9) by [@yungsters](https://github.com/yungsters))
|
||||
- **LegacyArchitecture:** Raise loglevel for assertion of `LegacyArchitecture` classes ([38a4b62211](https://github.com/facebook/react-native/commit/38a4b6221164d36eb4ac95c9f3bc7f7e7235e383) by [@mdvacca](https://github.com/mdvacca))
|
||||
- **LegacyArchitecture:** Raise logLevel of `LegacyArchitecture` classes when minimizing of legacy architecture is enabled ([0d1cde7f36](https://github.com/facebook/react-native/commit/0d1cde7f36e9de72c997fc812bba023694c2a369) by [@mdvacca](https://github.com/mdvacca))
|
||||
- **Metro:** Bump Metro to `^0.82.5` ([083644647e](https://github.com/facebook/react-native/commit/083644647eff502f484b3ba24f9d361d5df56546) by [@robhogan](https://github.com/robhogan))
|
||||
- **Metro:** Metro to ^0.83.1 ([e247be793c](https://github.com/facebook/react-native/commit/e247be793c70a374955d798d8cbbc6eba58080ec) by [@motiz88](https://github.com/motiz88))
|
||||
- **React DevTools:** Bumped React DevTools to `6.1.5` ([c302902b1d](https://github.com/facebook/react-native/commit/c302902b1db7e8f8ac5b61472c095dc0755d6d1c) by [@hoxyq](https://github.com/hoxyq))
|
||||
- **RuntimeExecutor:** `RuntimeExecutor`: Remove noexcept from sync ui thread utils ([7ef278af50](https://github.com/facebook/react-native/commit/7ef278af505deba6b8a47876c6824f9a7fefa427) by [@RSNara](https://github.com/RSNara))
|
||||
- **Typescript:** Bump `types/react` to `19.1` ([3ae9328571](https://github.com/facebook/react-native/commit/3ae932857174e9c39cd5d9c53922f849aa1401b1) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
||||
|
||||
#### Android specific
|
||||
|
||||
- **Android SDK:** Updated targetSdk to 36 in Android. ([477d8df312](https://github.com/facebook/react-native/commit/477d8df3126b325b8cc9b410f1eaeb56b727d4d9) by [@kikoso](https://github.com/kikoso))
|
||||
- **APIs:** Deprecate `DefaultNewArchitectureEntryPoint.load(Boolean, Boolean, Boolean)` ([efdf73983c](https://github.com/facebook/react-native/commit/efdf73983cef1f371511b6e1efa5e01835ebcabb) by [@cortinico](https://github.com/cortinico))
|
||||
- **APIs:** Make `com.facebook.react.views.common.ContextUtils` internal ([d1ef8f1fa3](https://github.com/facebook/react-native/commit/d1ef8f1fa36cbfc34d05c409abf693e4e1cac3de) by [@cortinico](https://github.com/cortinico))
|
||||
- **deps:** Bump `AGP` to `8.11.0` ([04858ecbab](https://github.com/facebook/react-native/commit/04858ecbab808ddca80e20e76f1359619bb5e865) by [@cortinico](https://github.com/cortinico))
|
||||
- **deps:** Bump `Gradle` to `8.14.2` ([e20bb56f3b](https://github.com/facebook/react-native/commit/e20bb56f3b4db0d3e69154b95b952b1fe8e29959) by [@cortinico](https://github.com/cortinico))
|
||||
- **deps:** Bump `Gradle` to 8.14.3 ([6892dde363](https://github.com/facebook/react-native/commit/6892dde36373bbef2d0afe535ae818b1a7164f08) by [@cortinico](https://github.com/cortinico))
|
||||
- **Gradle:** Expose `react_renderer_bridging` headers via prefab ([d1730ff960](https://github.com/facebook/react-native/commit/d1730ff960fcb9a01ee94b9e46e5a9fbb7d73f4a) by [@tomekzaw](https://github.com/tomekzaw))
|
||||
- **JS FPS:** Hide JS FPS on performance overlay as not accurate ([feec8d0148](https://github.com/facebook/react-native/commit/feec8d014877b2177f1c7dded7eb9664f53ee471) by [@cortinico](https://github.com/cortinico))
|
||||
- Updated targetSdk to 36 in Android. ([477d8df312](https://github.com/facebook/react-native/commit/477d8df3126b325b8cc9b410f1eaeb56b727d4d9) by [@kikoso](https://github.com/kikoso))
|
||||
- **Kotlin:** Convert `UIManagerModuleConstantsHelper` to Kotlin ([45fd7feb9f](https://github.com/facebook/react-native/commit/45fd7feb9f083e5c8afc916732aed9795d344e09) by [@cortinico](https://github.com/cortinico))
|
||||
- **Kotlin:** Migrate `ThemedReactContext` to Kotlin ([78c9671c24](https://github.com/facebook/react-native/commit/78c9671c241a86bedb17862e549842b7e36d77ea) by [@cortinico](https://github.com/cortinico))
|
||||
- **Kotlin:** Convert `ReactViewGroup` to Kotlin ([48395d346b](https://github.com/facebook/react-native/commit/48395d346bc89f63d38889e58508304df0088e4f) by [@cortinico](https://github.com/cortinico))
|
||||
- **Kotlin:** Migrate `com.facebook.react.LazyReactPackage` to Kotlin. ([b4ae5c1de1](https://github.com/facebook/react-native/commit/b4ae5c1de1003c343d43c3be1b59ee2b800b9258) by [@Xintre](https://github.com/Xintre))
|
||||
- **Kotlin:** Apply Collections Kotlin DSL helpers in `ReactAndroid` package ([b2ffd34a39](https://github.com/facebook/react-native/commit/b2ffd34a392de2bddba5ee13248796ccc2db6039) by [@l2hyunwoo](https://github.com/l2hyunwoo))
|
||||
- **Legacy Arch:** Introduce more deprecation warnings for Legacy Arch classes ([625f69f284](https://github.com/facebook/react-native/commit/625f69f284ddfd9c6beecaa4052a871d092053ef) by [@cortinico](https://github.com/cortinico))
|
||||
|
||||
#### iOS specific
|
||||
|
||||
@@ -223,19 +165,21 @@
|
||||
- **Typescript:** Add `ImageSource` type to TypeScript ([42ca46b95c](https://github.com/facebook/react-native/commit/42ca46b95cf9938de00b76dc61948a4ae7116e2b) by [@okwasniewski](https://github.com/okwasniewski))
|
||||
- **Typescript:** Devtools TS Types ([8f189fce03](https://github.com/facebook/react-native/commit/8f189fce03db367abdceca6ad57ae28b613fdd7d) by [@krystofwoldrich](https://github.com/krystofwoldrich))
|
||||
- **Yoga:** Fix possible invalid measurements with width or height is zero pixels ([5cc4d0a086](https://github.com/facebook/react-native/commit/5cc4d0a086d450e0f9d8ab6194013348f9de1f58) by [@NickGerleman](https://github.com/NickGerleman))
|
||||
- **Yoga:** Fixed nodes with `display: contents` set being cloned with the wrong owner ([d4b36b0300](https://github.com/facebook/react-native/commit/d4b36b03003eb2de9eaf5b57bb639bae8cc12f20) by [@j-piasecki](https://github.com/j-piasecki))
|
||||
|
||||
#### Android specific
|
||||
|
||||
- **API:** Make accessors inside HeadlessJsTaskService open again ([7ef57163cb](https://github.com/facebook/react-native/commit/7ef57163cb016317e43e563da7ea181989f6abca) by [@cortinico](https://github.com/cortinico))
|
||||
- **BaseViewManager:** Remove focus change listener when dropping/recycling view instances ([94cbf206d6](https://github.com/facebook/react-native/commit/94cbf206d607477257c65039d97565a79e94c7dd) by [@Abbondanzo](https://github.com/Abbondanzo))
|
||||
- **BoringLayout:** Include fallback line spacing in `BoringLayout` ([2fe6c1a947](https://github.com/facebook/react-native/commit/2fe6c1a94758223a5342fdfa90163971eb588e6a) by [@NickGerleman](https://github.com/NickGerleman))
|
||||
- **Bridgeless:** Adding `shouldForwardToReactInstance` check in `ReactDelegate` for Bridgeless ([0f7bf66bba](https://github.com/facebook/react-native/commit/0f7bf66bba8498c89384e96ad9219cdad0107b0c) by [@arushikesarwani94](https://github.com/arushikesarwani94))
|
||||
- **Codegen:** Fix combining schema in Codegen process to exclude platforms correctly ([6104ccdc6e](https://github.com/facebook/react-native/commit/6104ccdc6ef89c2d4da25e60dcc55d73038e023f) by [@arushikesarwani94](https://github.com/arushikesarwani94))
|
||||
- **Edge To Edge:** Fix `Dimensions` `window` values on Android < 15 when edge-to-edge is enabled ([85d10ed904](https://github.com/facebook/react-native/commit/85d10ed90401a13de1f74aeddd773736195da285) by [@zoontek](https://github.com/zoontek))
|
||||
- **FBReactNativeSpec:** Extract out `FBReactNativeSpec`'s core components including Unimplemented from auto-generated registry ([b417b0c2d5](https://github.com/facebook/react-native/commit/b417b0c2d56dc37f824c0e77e98d1014d21cd8f8) by [@arushikesarwani94](https://github.com/arushikesarwani94))
|
||||
- **Gradle:** Fix Gradle v8.0 builds by using .set() for Property ([777397667c](https://github.com/facebook/react-native/commit/777397667c2625aab3fc907b9ef4bd564963d8bb) by [@meghancampbel9](https://github.com/meghancampbel9))
|
||||
- **ImageFetcher:** Change `free` to `delete` to call destructor of `ImageFetcher` and release `contextContainer`. ([90da666691](https://github.com/facebook/react-native/commit/90da666691745ab9bf3930dc3347d8e51683099f) by [@WoLewicki](https://github.com/WoLewicki))
|
||||
- **Modal:** Fix `Modal` first frame being rendered on top-left corner ([b950fa2afb](https://github.com/facebook/react-native/commit/b950fa2afb20e2213ff6c733cb1c2465b90406ef) by [@cortinico](https://github.com/cortinico))
|
||||
- **onTextLayout:** Fix `onTextLayout` metrics not incorporating `ReactTextViewManagerCallback` ([a6a2884d63](https://github.com/facebook/react-native/commit/a6a2884d63717a42ac2bafd2054991ce8b32a2e9) by [@NickGerleman](https://github.com/NickGerleman))
|
||||
- **RNGP:** Fix a race condition with codegen libraries missing sources ([9013a9e666](https://github.com/facebook/react-native/commit/9013a9e66629677c47e1b69703f9fc8f4cbc1c2c) by [@cortinico](https://github.com/cortinico))
|
||||
- **Runtime:** Fixed `ReactHostImpl.nativeModules` always returning an empty list ([2f46a49](https://github.com/facebook/react-native/commit/2f46a49b8d8a11d5cf4342eee83c469b545c6779) by [@lukmccall](https://github.com/lukmccall))
|
||||
- **Text:** Fix more text rounding bugs ([1fe3ff86c3](https://github.com/facebook/react-native/commit/1fe3ff86c364fad023ad1e426f26608699314339) by [@NickGerleman](https://github.com/NickGerleman))
|
||||
- **Text:** Fix `TextLayoutManager` `MeasureMode` Regression ([99119a2104](https://github.com/facebook/react-native/commit/99119a210487af18983145fd374ff7ebc88931f3) by [@NickGerleman](https://github.com/NickGerleman))
|
||||
- **TextInput:** Fix bug where focus would jump to top text input upon clearing a separate text input. ([79c47987b7](https://github.com/facebook/react-native/commit/79c47987b74ab044574fc542fd4b13a9f11aa491) by [@joevilches](https://github.com/joevilches))
|
||||
@@ -243,10 +187,13 @@
|
||||
#### iOS specific
|
||||
|
||||
- **Gradient**: Gradient interpolation for transparent colors ([097d482446](https://github.com/facebook/react-native/commit/097d482446b7a03ca0f8c7e0254f4d770e05c79c) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway))
|
||||
- **Prebuild:** Fixed wrong path in prebuild hermes check ([be11f2ee77](https://github.com/facebook/react-native/commit/be11f2ee77fd793efe0a1aa225897a1924163925) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Prebuild:** Fixed resolving build type when downloading hermes artifacts ([9371e20192](https://github.com/facebook/react-native/commit/9371e201927fd105e797bf06e43943dd21e04381) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Package.swift:** Add missing `React-RCTSettings` to `Package.swift` ([e40c1d265a](https://github.com/facebook/react-native/commit/e40c1d265a2045730dcf751eed4ebf32e099f0c7) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Package.swift:** Fixed defines in `Package.swift` ([e2f6ce4ddf](https://github.com/facebook/react-native/commit/e2f6ce4ddfbea5814fc5d8632df14daeae3636d1) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Podspec:** Fixed premature return in header file generation from podspec globs ([f2b064c2d4](https://github.com/facebook/react-native/commit/f2b064c2d40c39017ac2a31bf3caf8acef23038c) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Podspec:** Fixed issue with RNDeps release/debug switch failing ([4ee2b60a1e](https://github.com/facebook/react-native/commit/4ee2b60a1eacca744d58a7ad336ca9d3714289f6) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Podspec:** Fixed missing script for resolving prebuilt xcframework when switching between release/debug ([2e55241a90](https://github.com/facebook/react-native/commit/2e55241a901b4cd95917de68ce9078928820a208) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Prebuild:** Fixed wrong path in prebuild hermes check ([be11f2ee77](https://github.com/facebook/react-native/commit/be11f2ee77fd793efe0a1aa225897a1924163925) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **Prebuild:** Fixed resolving build type when downloading hermes artifacts ([9371e20192](https://github.com/facebook/react-native/commit/9371e201927fd105e797bf06e43943dd21e04381) by [@chrfalch](https://github.com/chrfalch))
|
||||
- **RCTImage:** Allow for consuming `RCTImage` in Swift codebase by enabling "Defines Module" option ([1d80586730](https://github.com/facebook/react-native/commit/1d8058673085580f402ec3a320fce810db7ad2ef) by [@kkafar](https://github.com/kkafar))
|
||||
- **RCTImageComponentView:** Fix `RCTImageComponentView` image loading after source props change with no layout invalidation ([cd5d74518b](https://github.com/facebook/react-native/commit/cd5d74518becb3355519373211d2f54ff7dbd208) by Nick Lefever)
|
||||
- **RCTScreenSize:** Make `RCTScreenSize` take horizontal orientation into account ([50ce8c77a7](https://github.com/facebook/react-native/commit/50ce8c77a74f2f2574030db04dc88c6092e68ba8) by [@okwasniewski](https://github.com/okwasniewski))
|
||||
@@ -607,6 +554,10 @@
|
||||
- **Text:** Selection range not respected when changing text or selection when selection is forced ([d32ea66e6a](https://github.com/facebook/react-native/commit/d32ea66e6a945dd84092532401b265b12d482668) by Olivier Bouillet)
|
||||
- **TextInput:** Fix TextInput `onContentSizeChange` event being dispatched only once on iOS on the new architecture ([5fd5188172](https://github.com/facebook/react-native/commit/5fd51881727b2d86f87abf04db032940ac0ec8c4) by [@j-piasecki](https://github.com/j-piasecki))
|
||||
|
||||
## v0.79.6
|
||||
|
||||
See [CHANGELOG-0.7x](./CHANGELOG-0.7x.md#v0796)
|
||||
|
||||
## v0.79.5
|
||||
|
||||
See [CHANGELOG-0.7x](./CHANGELOG-0.7x.md#v0795)
|
||||
|
||||
+28
-12
@@ -26,10 +26,12 @@ fun getListReactAndroidProperty(name: String) = reactAndroidProperties.getProper
|
||||
|
||||
apiValidation {
|
||||
ignoredPackages.addAll(
|
||||
getListReactAndroidProperty("binaryCompatibilityValidator.ignoredPackages"))
|
||||
getListReactAndroidProperty("binaryCompatibilityValidator.ignoredPackages")
|
||||
)
|
||||
ignoredClasses.addAll(getListReactAndroidProperty("binaryCompatibilityValidator.ignoredClasses"))
|
||||
nonPublicMarkers.addAll(
|
||||
getListReactAndroidProperty("binaryCompatibilityValidator.nonPublicMarkers"))
|
||||
getListReactAndroidProperty("binaryCompatibilityValidator.nonPublicMarkers")
|
||||
)
|
||||
validationDisabled =
|
||||
reactAndroidProperties
|
||||
.getProperty("binaryCompatibilityValidator.validationDisabled")
|
||||
@@ -37,8 +39,9 @@ apiValidation {
|
||||
}
|
||||
|
||||
version =
|
||||
if (project.hasProperty("isSnapshot") &&
|
||||
(project.property("isSnapshot") as? String).toBoolean()) {
|
||||
if (
|
||||
project.hasProperty("isSnapshot") && (project.property("isSnapshot") as? String).toBoolean()
|
||||
) {
|
||||
"${reactAndroidProperties.getProperty("VERSION_NAME")}-SNAPSHOT"
|
||||
} else {
|
||||
reactAndroidProperties.getProperty("VERSION_NAME")
|
||||
@@ -66,8 +69,10 @@ tasks.register("clean", Delete::class.java) {
|
||||
description = "Remove all the build files and intermediate build outputs"
|
||||
dependsOn(gradle.includedBuild("gradle-plugin").task(":clean"))
|
||||
subprojects.forEach {
|
||||
if (it.project.plugins.hasPlugin("com.android.library") ||
|
||||
it.project.plugins.hasPlugin("com.android.application")) {
|
||||
if (
|
||||
it.project.plugins.hasPlugin("com.android.library") ||
|
||||
it.project.plugins.hasPlugin("com.android.application")
|
||||
) {
|
||||
dependsOn(it.tasks.named("clean"))
|
||||
}
|
||||
}
|
||||
@@ -77,10 +82,13 @@ tasks.register("clean", Delete::class.java) {
|
||||
delete(rootProject.file("./packages/react-native/sdks/download/"))
|
||||
delete(rootProject.file("./packages/react-native/sdks/hermes/"))
|
||||
delete(
|
||||
rootProject.file("./packages/react-native/ReactAndroid/src/main/jni/prebuilt/lib/arm64-v8a/"))
|
||||
rootProject.file("./packages/react-native/ReactAndroid/src/main/jni/prebuilt/lib/arm64-v8a/")
|
||||
)
|
||||
delete(
|
||||
rootProject.file(
|
||||
"./packages/react-native/ReactAndroid/src/main/jni/prebuilt/lib/armeabi-v7a/"))
|
||||
"./packages/react-native/ReactAndroid/src/main/jni/prebuilt/lib/armeabi-v7a/"
|
||||
)
|
||||
)
|
||||
delete(rootProject.file("./packages/react-native/ReactAndroid/src/main/jni/prebuilt/lib/x86/"))
|
||||
delete(rootProject.file("./packages/react-native/ReactAndroid/src/main/jni/prebuilt/lib/x86_64/"))
|
||||
delete(rootProject.file("./packages/react-native-codegen/lib"))
|
||||
@@ -98,7 +106,8 @@ tasks.register("publishAllToMavenTempLocal") {
|
||||
dependsOn(":packages:react-native:ReactAndroid:publishAllPublicationsToMavenTempLocalRepository")
|
||||
// We don't publish the external-artifacts to Maven Local as ci is using it via workspace.
|
||||
dependsOn(
|
||||
":packages:react-native:ReactAndroid:hermes-engine:publishAllPublicationsToMavenTempLocalRepository")
|
||||
":packages:react-native:ReactAndroid:hermes-engine:publishAllPublicationsToMavenTempLocalRepository"
|
||||
)
|
||||
}
|
||||
|
||||
tasks.register("publishAndroidToSonatype") {
|
||||
@@ -120,7 +129,8 @@ if (project.findProperty("react.internal.useHermesNightly")?.toString()?.toBoole
|
||||
That's fine for local development, but you should not commit this change.
|
||||
********************************************************************************
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
allprojects {
|
||||
configurations.all {
|
||||
resolutionStrategy.dependencySubstitution {
|
||||
@@ -152,10 +162,12 @@ allprojects {
|
||||
"**/build/**",
|
||||
"**/hermes-engine/**",
|
||||
"**/internal/featureflags/**",
|
||||
"**/systeminfo/ReactNativeVersion.kt")
|
||||
"**/systeminfo/ReactNativeVersion.kt",
|
||||
)
|
||||
listOf(
|
||||
com.ncorti.ktfmt.gradle.tasks.KtfmtCheckTask::class,
|
||||
com.ncorti.ktfmt.gradle.tasks.KtfmtFormatTask::class)
|
||||
com.ncorti.ktfmt.gradle.tasks.KtfmtFormatTask::class,
|
||||
)
|
||||
.forEach { tasks.withType(it) { exclude(excludePatterns) } }
|
||||
|
||||
// Disable the problematic ktfmt script tasks due to symbolic link issues in subprojects
|
||||
@@ -165,3 +177,7 @@ allprojects {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We intentionally disable the `ktfmtCheck` tasks as the formatting is primarly handled inside
|
||||
// fbsource
|
||||
allprojects { tasks.withType<com.ncorti.ktfmt.gradle.tasks.KtfmtCheckTask>() { enabled = false } }
|
||||
|
||||
@@ -91,7 +91,19 @@ declare module 'tinybench' {
|
||||
beforeEach?: (this: Task) => void | Promise<void>,
|
||||
};
|
||||
|
||||
export type Fn = () => Promise<mixed> | mixed;
|
||||
// This is defined as an interface in tinybench but we define it as an object
|
||||
// to catch problems like `overriddenDuration` being misspelled.
|
||||
export type FnReturnedObject = {
|
||||
overriddenDuration?: number,
|
||||
};
|
||||
|
||||
// This type is defined as returning `unknown` instead of `void` in tinybench,
|
||||
// but we type it this way to avoid mistakes (we can make breaking changes
|
||||
// in our definition that they can't).
|
||||
export type Fn = () =>
|
||||
| Promise<void | FnReturnedObject>
|
||||
| void
|
||||
| FnReturnedObject;
|
||||
|
||||
declare export class Bench extends EventTarget {
|
||||
concurrency: null | 'task' | 'bench';
|
||||
Vendored
+2
-2
@@ -21,7 +21,7 @@ declare type ws$PerMessageDeflateOptions = {
|
||||
maxPayload?: number,
|
||||
};
|
||||
|
||||
/* $FlowFixMe[incompatible-extend] - Found with Flow v0.143.1 upgrade
|
||||
/* $FlowFixMe[incompatible-type] - Found with Flow v0.143.1 upgrade
|
||||
* "on" definition failing with string is incompatible with string literal */
|
||||
declare class ws$WebSocketServer extends events$EventEmitter {
|
||||
/**
|
||||
@@ -141,7 +141,7 @@ declare type ws$UnexpectedResponseListener = (
|
||||
) => mixed;
|
||||
declare type ws$UpgradeListener = (response: http$IncomingMessage<>) => mixed;
|
||||
|
||||
/* $FlowFixMe[incompatible-extend] - Found with Flow v0.143.1 upgrade
|
||||
/* $FlowFixMe[incompatible-type] - Found with Flow v0.143.1 upgrade
|
||||
* "on" definition failing with string is incompatible with string literal */
|
||||
declare class ws$WebSocket extends events$EventEmitter {
|
||||
static Server: typeof ws$WebSocketServer;
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -86,7 +86,7 @@ module.exports = {
|
||||
globalPrefix: '',
|
||||
hermesParser: true,
|
||||
hot: false,
|
||||
// $FlowFixMe[incompatible-call] TODO: Remove when `inlineRequires` has been removed from metro-babel-transformer in OSS
|
||||
// $FlowFixMe[incompatible-type] TODO: Remove when `inlineRequires` has been removed from metro-babel-transformer in OSS
|
||||
inlineRequires: true,
|
||||
minify: false,
|
||||
platform: '',
|
||||
@@ -111,7 +111,7 @@ module.exports = {
|
||||
|
||||
return generate(
|
||||
ast,
|
||||
// $FlowFixMe[prop-missing] Error found when improving flow typing for libs
|
||||
// $FlowFixMe[incompatible-type] Error found when improving flow typing for libs
|
||||
{
|
||||
code: true,
|
||||
comments: false,
|
||||
|
||||
+8
-8
@@ -63,7 +63,7 @@
|
||||
"@typescript-eslint/parser": "^8.36.0",
|
||||
"ansi-styles": "^4.2.1",
|
||||
"babel-plugin-minify-dead-code-elimination": "^0.5.2",
|
||||
"babel-plugin-syntax-hermes-parser": "0.30.0",
|
||||
"babel-plugin-syntax-hermes-parser": "0.32.0",
|
||||
"babel-plugin-transform-define": "^2.1.4",
|
||||
"babel-plugin-transform-flow-enums": "^0.0.2",
|
||||
"clang-format": "^1.8.0",
|
||||
@@ -75,17 +75,17 @@
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-ft-flow": "^2.0.1",
|
||||
"eslint-plugin-jest": "^27.9.0",
|
||||
"eslint-plugin-jest": "^29.0.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.6.0",
|
||||
"eslint-plugin-react": "^7.30.1",
|
||||
"eslint-plugin-react-native": "^4.0.0",
|
||||
"eslint-plugin-redundant-undefined": "^0.4.0",
|
||||
"eslint-plugin-relay": "^1.8.3",
|
||||
"flow-api-translator": "0.30.0",
|
||||
"flow-bin": "^0.278.0",
|
||||
"flow-api-translator": "0.32.0",
|
||||
"flow-bin": "^0.279.0",
|
||||
"glob": "^7.1.1",
|
||||
"hermes-eslint": "0.30.0",
|
||||
"hermes-transform": "0.30.0",
|
||||
"hermes-eslint": "0.32.0",
|
||||
"hermes-transform": "0.32.0",
|
||||
"ini": "^5.0.0",
|
||||
"inquirer": "^7.1.0",
|
||||
"jest": "^29.7.0",
|
||||
@@ -102,7 +102,7 @@
|
||||
"node-fetch": "^2.2.0",
|
||||
"nullthrows": "^1.1.1",
|
||||
"prettier": "3.6.2",
|
||||
"prettier-plugin-hermes-parser": "0.31.1",
|
||||
"prettier-plugin-hermes-parser": "0.32.0",
|
||||
"react": "19.1.1",
|
||||
"react-test-renderer": "19.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
@@ -110,7 +110,7 @@
|
||||
"signedsource": "^1.0.0",
|
||||
"supports-color": "^7.1.0",
|
||||
"temp-dir": "^2.0.0",
|
||||
"tinybench": "^3.1.0",
|
||||
"tinybench": "^4.1.0",
|
||||
"typescript": "5.8.3",
|
||||
"ws": "^6.2.3"
|
||||
},
|
||||
|
||||
@@ -116,7 +116,7 @@ function copyAll(filesToCopy: CopiedFiles) {
|
||||
const src = queue.shift();
|
||||
// $FlowFixMe[incompatible-type]
|
||||
const dest = filesToCopy[src];
|
||||
// $FlowFixMe[incompatible-call]
|
||||
// $FlowFixMe[incompatible-type]
|
||||
copy(src, dest, copyNext);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -153,7 +153,7 @@ function buildDiffUrl(oldVersion: string, newVersion: string) {
|
||||
* Returns the most recent React Native version available to upgrade to.
|
||||
*/
|
||||
async function getLatestRnDiffPurgeVersion(): Promise<LatestVersions | void> {
|
||||
const options = {
|
||||
const options: RequestOptions = {
|
||||
// https://developer.github.com/v3/#user-agent-required
|
||||
headers: {'User-Agent': '@react-native/community-cli-plugin'} as Headers,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@generated SignedSource<<9252db36d4b1db907a38c08935ceeb38>>
|
||||
Git revision: 921566790e9e16d0ecace6e49b3cfaace205958c
|
||||
@generated SignedSource<<b6a779e724ecce5e727ee674dc20f809>>
|
||||
Git revision: e87564a24cf233c60aaebee8c418ec85724f7214
|
||||
Built with --nohooks: false
|
||||
Is local checkout: false
|
||||
Remote URL: https://github.com/facebook/react-native-devtools-frontend
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,58 +1,58 @@
|
||||
#!/usr/bin/env dotslash
|
||||
|
||||
// @generated SignedSource<<686df5695b32a90cd465412d979a1a3f>>
|
||||
// @generated SignedSource<<14de73ea0ed751d80c7c687c6aeb123f>>
|
||||
|
||||
|
||||
{
|
||||
"name": "React Native DevTools",
|
||||
"platforms": {
|
||||
"linux-aarch64": {
|
||||
"size": 113511487,
|
||||
"size": 116120331,
|
||||
"hash": "sha256",
|
||||
"digest": "c22f7d5e029357f05055ce7c56cc284a0d441d558e103a7b7ebae118c67d0b95",
|
||||
"digest": "5a1747bdb50f8140d96e99b31f9a603ceaf52e777e5dd59f65edacd87f8c6348",
|
||||
"providers": [
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQPRilWDJV8xyKEv9lqYn7Hf2kyZg6nqW8KctGZCXsU95lS_MTFyAmEULrB3J6hGCjqBY2Zl-uq_FjERAIgzbZFWX2eceacTbutBSOKEj6QTZzkVN_L1zPh2lGh24x29MHpkwUzw4E-kAXV43f-11QxqD7orI1QicyOnsmUqeRNKE_QjM9rNRsw6iE8"
|
||||
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQMRq1ou56GjpsIRFHpozEYiPfCuVvgWQVwiMMPBbwKyBnebit8HDGKof5XgDHbAKCqAZSgC8L22eJETnqIUM3kEAMYNXcHviIGy41rsXKVDYDgyWlGFB1zP2WzHrjWagfD062Pt4q5GqvCG5RVlhz656BOsutU7B4pDXGFCIdry7FveKn0PXGxvd1E"
|
||||
}
|
||||
],
|
||||
"format": "tar.gz",
|
||||
"path": "React Native DevTools-linux-arm64/React Native DevTools"
|
||||
},
|
||||
"linux-x86_64": {
|
||||
"size": 113244728,
|
||||
"size": 116056146,
|
||||
"hash": "sha256",
|
||||
"digest": "d749aee18d6c969f033511ed631b439c578068cc20786974bc0ee707c6c2f177",
|
||||
"digest": "b48a3e392ac482de8058917879cf07fd5934dcb84aa901d4fe0d29273b503f54",
|
||||
"providers": [
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQP8NAAXjHJ-9NJThip1nnmVim4yiS1tdYAXmWl2Remiluq5f13nXA8YEadsmGRLWxXz2WJouHXSK47ea4a30fxewyKeTt0niFn3T-lr_91m3Ve5ZS-FOZ_9CRVCkv5zC-Z1FlXJGOnphfWetIU10Pw9tho3IzjdSNlXle0XTrkJ2AyKSl4cKPaX"
|
||||
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQOyyb_LXrME2ubBGSkEi1vDw-2hwuHgHwnR-kAGQyhJK7lnELQDXKX1xW_u0joDwbTOhmiptwenq07G2NFkrY3t_AXefb_xTu2qHzpmrsX2YcwJlewbprgbuX7Uvdhqncb_IRAnJ4ogYKHUg6CZBNmLCQsyDsoqmkXtJ9ikJcQeDu2aiqbb-RWJ"
|
||||
}
|
||||
],
|
||||
"format": "tar.gz",
|
||||
"path": "React Native DevTools-linux-x64/React Native DevTools"
|
||||
},
|
||||
"macos-aarch64": {
|
||||
"size": 108805847,
|
||||
"size": 110957864,
|
||||
"hash": "sha256",
|
||||
"digest": "dc4a6cfa3d2d8646db8793ef497e43ad72be54bb14ed96345d059880ff72ce1e",
|
||||
"digest": "7964d83c857f12bb741abf4377771f3f3697b81df6283dd88d75ae43991afb73",
|
||||
"providers": [
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQPuZx9G4h30mUDM0hZ8y74LbzAi7-S6jnOqq8uyfDdIptLwIgpb8CKB8F2tduvaBFMGd7obwXd2NVy01r6XKVdgAK5-QTp8PYUPUE7VSCi6QAqobXcQ2uq_lY-jgyj8XkV4Ua4gA6KR609Bmh-beSTOrSqMymqVodaGqoGjB_9jVwfD99_PfFlex-Ta"
|
||||
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQM7USVzavWxZkjOO6CasnSfPIfE08jJAkwfVO0qWiYBli136vpzA_HS89ZqsIsAC_GXeT7K-K9BxdON7z5qBoRMUygAay7z4DGT5OZ9YSf9MDCd0JOzah5_6s3ijw2j4eeRu8ZNYzI3aTutDXtPMJAb2KfBHGx2lEiSW5YK9idcB5Y2boAWeDXXX5nb"
|
||||
}
|
||||
],
|
||||
"format": "tar.gz",
|
||||
"path": "React Native DevTools.app/Contents/MacOS/React Native DevTools"
|
||||
},
|
||||
"macos-x86_64": {
|
||||
"size": 113766610,
|
||||
"size": 117827315,
|
||||
"hash": "sha256",
|
||||
"digest": "74178859ce6a1c26c32055e192b1b123822c76c827ea86a6dfdb5463b89b1ace",
|
||||
"digest": "bab2fac43def4a82fb88300aac05180eeda24f31cc00402a3ff7ca2e612bd532",
|
||||
"providers": [
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQN6DjGhr8_L7N_cwrh8pi3cfNcbn9dot_QQpgwe3Vv-780FDgi6JUeMvbo_wbFoT2rogxfHZ0-NbXbKdWYwhGUoGeQuikT57QnVMOYuPUTjlQUgYy0Ng9XPhq3iSEYwlMV1XsUJuPFRUg-hIHcgaaA55JoTLXZ1fLYydhHnmgRxGHc4pxaHvSpTtQ"
|
||||
"url": "https://scontent.xx.fbcdn.net/mci_ab/uap/?ab_b=m&ab_page=react_native_devtools_binaries&ab_entry=AQPYS0ZRQ7RV1S-yy3tut6pRqcKdPcOiKfekrA5AXdd_M-HDaXLwJS57iAFU2K2X-EA_cyg25C3L-5L7O3eyNKPMToZHbV282GiojnNSKFNjsjj9_B737lOwHI_XqbDQEIiNJZ7NjbkZ8_iMKK-LNL-Ydha2ORWWqytuzP4sWQ6sm0XIxsdyQ6bOLw"
|
||||
}
|
||||
],
|
||||
"format": "tar.gz",
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.4",
|
||||
"electron": ">=36.3.0"
|
||||
"electron": ">=37.2.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.6",
|
||||
"electron": "36.3.0"
|
||||
"electron": "37.2.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"semver": "^7.1.3"
|
||||
|
||||
@@ -105,8 +105,9 @@ export class DebuggerMock extends DebuggerAgent {
|
||||
: this.handle.mock.calls;
|
||||
// $FlowFixMe[incompatible-use]
|
||||
// $FlowFixMe[prop-missing]
|
||||
// $FlowFixMe[incompatible-type]
|
||||
const [response] = newHandleCalls.find(args => args[0].id === message.id);
|
||||
// $FlowFixMe[incompatible-return]
|
||||
// $FlowFixMe[incompatible-type]
|
||||
// $FlowFixMe[incompatible-indexer]
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -152,12 +152,12 @@ export class DeviceMock extends DeviceAgent {
|
||||
if (!payload) {
|
||||
return;
|
||||
}
|
||||
// $FlowFixMe[incompatible-call] TODO(moti) Figure out the right way to type maybePayload generically
|
||||
// $FlowFixMe[incompatible-type] TODO(moti) Figure out the right way to type maybePayload generically
|
||||
this.send({event, payload});
|
||||
});
|
||||
return;
|
||||
}
|
||||
// $FlowFixMe[incompatible-call] TODO(moti) Figure out the right way to type maybePayload generically
|
||||
// $FlowFixMe[incompatible-type] TODO(moti) Figure out the right way to type maybePayload generically
|
||||
this.send({event, payload: maybePayload});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ export async function sendFromTargetToDebugger<Message: CdpMessageFromTarget>(
|
||||
: debugger_.handle.mock.calls;
|
||||
// $FlowFixMe[incompatible-type]
|
||||
const [receivedMessage]: [Message] = newHandleCalls.find(
|
||||
// $FlowFixMe[incompatible-call]
|
||||
// $FlowFixMe[incompatible-type]
|
||||
(call: [Message]) => call[0].method === message.method,
|
||||
);
|
||||
return receivedMessage;
|
||||
@@ -103,7 +103,7 @@ export async function sendFromDebuggerToTarget<Message: CdpMessageToTarget>(
|
||||
// $FlowFixMe[incompatible-use]
|
||||
call => call[0].wrappedEvent.id === message.id,
|
||||
);
|
||||
// $FlowFixMe[incompatible-return]
|
||||
// $FlowFixMe[incompatible-type]
|
||||
return receivedMessage.wrappedEvent;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ export async function createServer(options: CreateServerOptions): Promise<{
|
||||
);
|
||||
httpServer = https.createServer(
|
||||
{cert, key},
|
||||
// $FlowFixMe[incompatible-call] The types for `connect` and `https` are subtly incompatible as written.
|
||||
// $FlowFixMe[incompatible-type] The types for `connect` and `https` are subtly incompatible as written.
|
||||
app,
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -40,7 +40,7 @@ function makeRequest(
|
||||
host: ?string,
|
||||
encrypted: boolean,
|
||||
): http$IncomingMessage<> | http$IncomingMessage<tls$TLSSocket> {
|
||||
// $FlowFixMe[incompatible-return] Partial mock of request
|
||||
// $FlowFixMe[incompatible-type] Partial mock of request
|
||||
return {
|
||||
socket: encrypted ? {encrypted: true} : {},
|
||||
headers: host != null ? {host} : {},
|
||||
|
||||
@@ -81,7 +81,7 @@ export default function createDevMiddleware({
|
||||
projectRoot,
|
||||
serverBaseUrl,
|
||||
logger,
|
||||
// $FlowFixMe[prop-missing]
|
||||
// $FlowFixMe[incompatible-type]
|
||||
unstable_browserLauncher = DefaultBrowserLauncher,
|
||||
unstable_eventReporter,
|
||||
unstable_experiments: experimentConfig = {},
|
||||
|
||||
@@ -179,7 +179,7 @@ export default class Device {
|
||||
this.#deviceEventReporter?.logProfilingTargetRegistered();
|
||||
}
|
||||
|
||||
// $FlowFixMe[incompatible-call]
|
||||
// $FlowFixMe[incompatible-type]
|
||||
this.#deviceSocket.on('message', (message: string) => {
|
||||
try {
|
||||
const parsedMessage = JSON.parse(message);
|
||||
@@ -346,7 +346,7 @@ export default class Device {
|
||||
frontendUserAgent: userAgent,
|
||||
});
|
||||
|
||||
const debuggerInfo = {
|
||||
const debuggerInfo: ?DebuggerConnection & DebuggerConnection = {
|
||||
socket,
|
||||
prependedFilePrefix: false,
|
||||
pageId,
|
||||
@@ -408,7 +408,7 @@ export default class Device {
|
||||
|
||||
this.#sendConnectEventToDevice(this.#mapToDevicePageId(pageId));
|
||||
|
||||
// $FlowFixMe[incompatible-call]
|
||||
// $FlowFixMe[incompatible-type]
|
||||
socket.on('message', (message: string) => {
|
||||
this.#cdpDebugLogging.log('DebuggerToProxy', message);
|
||||
const debuggerRequest = JSON.parse(message);
|
||||
@@ -809,6 +809,8 @@ export default class Device {
|
||||
}
|
||||
|
||||
if (
|
||||
/* $FlowFixMe[invalid-compare] Error discovered during Constant Condition
|
||||
* roll out. See https://fburl.com/workplace/4oq3zi07. */
|
||||
payload.method === 'Runtime.executionContextCreated' &&
|
||||
this.#isLegacyPageReloading
|
||||
) {
|
||||
|
||||
@@ -57,7 +57,8 @@ export default function openDebuggerMiddleware({
|
||||
req.method === 'POST' ||
|
||||
(experiments.enableOpenDebuggerRedirect && req.method === 'GET')
|
||||
) {
|
||||
const paresedUrl = url.parse(req.url, true);
|
||||
const parsedUrl = url.parse(req.url, true);
|
||||
|
||||
const query: {
|
||||
/** @deprecated Will only match legacy Hermes targets */
|
||||
appId?: string,
|
||||
@@ -66,8 +67,9 @@ export default function openDebuggerMiddleware({
|
||||
launchId?: string,
|
||||
telemetryInfo?: string,
|
||||
target?: string,
|
||||
landingView?: string,
|
||||
...
|
||||
} = paresedUrl.query;
|
||||
} = parsedUrl.query;
|
||||
|
||||
const targets = inspectorProxy
|
||||
.getPageDescriptions({requestorRelativeBaseUrl: new URL(serverBaseUrl)})
|
||||
@@ -150,6 +152,7 @@ export default function openDebuggerMiddleware({
|
||||
telemetryInfo: query.telemetryInfo,
|
||||
appId: target.appId,
|
||||
useFuseboxEntryPoint,
|
||||
landingView: query.landingView,
|
||||
},
|
||||
);
|
||||
if (
|
||||
|
||||
@@ -24,6 +24,7 @@ export default function getDevToolsFrontendUrl(
|
||||
/** Whether to use the modern `rn_fusebox.html` entry point. */
|
||||
useFuseboxEntryPoint?: boolean,
|
||||
appId?: string,
|
||||
landingView?: string,
|
||||
}>,
|
||||
): string {
|
||||
const wsParam = getWsParam({
|
||||
@@ -54,6 +55,9 @@ export default function getDevToolsFrontendUrl(
|
||||
if (options?.telemetryInfo != null && options.telemetryInfo !== '') {
|
||||
searchParams.append('telemetryInfo', options.telemetryInfo);
|
||||
}
|
||||
if (options?.landingView != null && options.landingView !== '') {
|
||||
searchParams.append('landingView', options.landingView);
|
||||
}
|
||||
|
||||
return appUrl + '?' + searchParams.toString();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-ft-flow": "^2.0.1",
|
||||
"eslint-plugin-jest": "^27.9.0",
|
||||
"eslint-plugin-jest": "^29.0.1",
|
||||
"eslint-plugin-react": "^7.30.1",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-native": "^4.0.0"
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"main": "index.js",
|
||||
"devDependencies": {
|
||||
"babel-plugin-syntax-hermes-parser": "0.30.0",
|
||||
"hermes-eslint": "0.30.0"
|
||||
"babel-plugin-syntax-hermes-parser": "0.32.0",
|
||||
"hermes-eslint": "0.32.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
"source-map-support": "0.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-syntax-hermes-parser": "0.30.0",
|
||||
"hermes-eslint": "0.30.0"
|
||||
"babel-plugin-syntax-hermes-parser": "0.32.0",
|
||||
"hermes-eslint": "0.32.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.4"
|
||||
|
||||
@@ -45,3 +45,7 @@ tasks.named("ktfmtFormat") {
|
||||
":shared:ktfmtFormat",
|
||||
)
|
||||
}
|
||||
|
||||
// We intentionally disable the `ktfmtCheck` tasks as the formatting is primarly handled inside
|
||||
// fbsource
|
||||
allprojects { tasks.withType<com.ncorti.ktfmt.gradle.tasks.KtfmtCheckTask>() { enabled = false } }
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -68,7 +68,8 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
// See comment above on JDK 11 support
|
||||
jvmTarget.set(JvmTarget.JVM_11)
|
||||
allWarningsAsErrors.set(
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false)
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -208,7 +208,8 @@ abstract class ReactExtension @Inject constructor(val project: Project) {
|
||||
} else {
|
||||
buildTypes.forEach { buildType ->
|
||||
result.add(
|
||||
(dependencyConfiguration ?: "${buildType}Implementation") to ":$nameCleansed")
|
||||
(dependencyConfiguration ?: "${buildType}Implementation") to ":$nameCleansed"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+83
-97
@@ -29,7 +29,6 @@ import com.facebook.react.utils.JdkConfiguratorUtils.configureJavaToolChains
|
||||
import com.facebook.react.utils.JsonUtils
|
||||
import com.facebook.react.utils.NdkConfiguratorUtils.configureReactNativeNdk
|
||||
import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson
|
||||
import com.facebook.react.utils.PropertyUtils
|
||||
import com.facebook.react.utils.findPackageJsonFile
|
||||
import java.io.File
|
||||
import kotlin.system.exitProcess
|
||||
@@ -43,7 +42,6 @@ import org.gradle.internal.jvm.Jvm
|
||||
class ReactPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
checkJvmVersion(project)
|
||||
checkLegacyArchProperty(project)
|
||||
val extension = project.extensions.create("react", ReactExtension::class.java, project)
|
||||
|
||||
// We register a private extension on the rootProject so that project wide configs
|
||||
@@ -51,7 +49,10 @@ class ReactPlugin : Plugin<Project> {
|
||||
val rootExtension =
|
||||
project.rootProject.extensions.findByType(PrivateReactExtension::class.java)
|
||||
?: project.rootProject.extensions.create(
|
||||
"privateReact", PrivateReactExtension::class.java, project)
|
||||
"privateReact",
|
||||
PrivateReactExtension::class.java,
|
||||
project,
|
||||
)
|
||||
|
||||
// App Only Configuration
|
||||
project.pluginManager.withPlugin("com.android.application") {
|
||||
@@ -111,35 +112,12 @@ class ReactPlugin : Plugin<Project> {
|
||||
********************************************************************************
|
||||
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
exitProcess(1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkLegacyArchProperty(project: Project) {
|
||||
if ((project.hasProperty(PropertyUtils.NEW_ARCH_ENABLED) &&
|
||||
!project.property(PropertyUtils.NEW_ARCH_ENABLED).toString().toBoolean()) ||
|
||||
(project.hasProperty(PropertyUtils.SCOPED_NEW_ARCH_ENABLED) &&
|
||||
!project.property(PropertyUtils.SCOPED_NEW_ARCH_ENABLED).toString().toBoolean())) {
|
||||
project.logger.error(
|
||||
"""
|
||||
|
||||
********************************************************************************
|
||||
|
||||
WARNING: Setting `newArchEnabled=false` in your `gradle.properties` file is not
|
||||
supported anymore since React Native 0.82.
|
||||
|
||||
You can remove the line from your `gradle.properties` file.
|
||||
|
||||
The application will run with the New Architecture enabled by default.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
"""
|
||||
.trimIndent())
|
||||
}
|
||||
}
|
||||
|
||||
/** This function configures Android resources - in this case just the bundle */
|
||||
private fun configureResources(project: Project, reactExtension: ReactExtension) {
|
||||
project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java).finalizeDsl {
|
||||
@@ -157,7 +135,7 @@ class ReactPlugin : Plugin<Project> {
|
||||
project: Project,
|
||||
localExtension: ReactExtension,
|
||||
rootExtension: PrivateReactExtension,
|
||||
isLibrary: Boolean
|
||||
isLibrary: Boolean,
|
||||
) {
|
||||
// First, we set up the output dir for the codegen.
|
||||
val generatedSrcDir: Provider<Directory> =
|
||||
@@ -175,70 +153,72 @@ class ReactPlugin : Plugin<Project> {
|
||||
// We create the task to produce schema from JS files.
|
||||
val generateCodegenSchemaTask =
|
||||
project.tasks.register(
|
||||
"generateCodegenSchemaFromJavaScript", GenerateCodegenSchemaTask::class.java) { it ->
|
||||
it.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
|
||||
it.codegenDir.set(rootExtension.codegenDir)
|
||||
it.generatedSrcDir.set(generatedSrcDir)
|
||||
it.nodeWorkingDir.set(project.layout.projectDirectory.asFile.absolutePath)
|
||||
"generateCodegenSchemaFromJavaScript",
|
||||
GenerateCodegenSchemaTask::class.java,
|
||||
) { it ->
|
||||
it.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
|
||||
it.codegenDir.set(rootExtension.codegenDir)
|
||||
it.generatedSrcDir.set(generatedSrcDir)
|
||||
it.nodeWorkingDir.set(project.layout.projectDirectory.asFile.absolutePath)
|
||||
|
||||
// We're reading the package.json at configuration time to properly feed
|
||||
// the `jsRootDir` @Input property of this task & the onlyIf. Therefore, the
|
||||
// parsePackageJson should be invoked inside this lambda.
|
||||
val packageJson = findPackageJsonFile(project, rootExtension.root)
|
||||
val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }
|
||||
// We're reading the package.json at configuration time to properly feed
|
||||
// the `jsRootDir` @Input property of this task & the onlyIf. Therefore, the
|
||||
// parsePackageJson should be invoked inside this lambda.
|
||||
val packageJson = findPackageJsonFile(project, rootExtension.root)
|
||||
val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }
|
||||
|
||||
val jsSrcsDirInPackageJson = parsedPackageJson?.codegenConfig?.jsSrcsDir
|
||||
val includesGeneratedCode =
|
||||
parsedPackageJson?.codegenConfig?.includesGeneratedCode ?: false
|
||||
if (jsSrcsDirInPackageJson != null) {
|
||||
it.jsRootDir.set(File(packageJson.parentFile, jsSrcsDirInPackageJson))
|
||||
} else {
|
||||
it.jsRootDir.set(localExtension.jsRootDir)
|
||||
val jsSrcsDirInPackageJson = parsedPackageJson?.codegenConfig?.jsSrcsDir
|
||||
val includesGeneratedCode =
|
||||
parsedPackageJson?.codegenConfig?.includesGeneratedCode ?: false
|
||||
if (jsSrcsDirInPackageJson != null) {
|
||||
it.jsRootDir.set(File(packageJson.parentFile, jsSrcsDirInPackageJson))
|
||||
} else {
|
||||
it.jsRootDir.set(localExtension.jsRootDir)
|
||||
}
|
||||
it.jsInputFiles.set(
|
||||
project.fileTree(it.jsRootDir) { tree ->
|
||||
tree.include("**/*.js")
|
||||
tree.include("**/*.jsx")
|
||||
tree.include("**/*.ts")
|
||||
tree.include("**/*.tsx")
|
||||
|
||||
tree.exclude("node_modules/**/*")
|
||||
tree.exclude("**/*.d.ts")
|
||||
// We want to exclude the build directory, to don't pick them up for execution
|
||||
// avoidance.
|
||||
tree.exclude("**/build/**/*")
|
||||
}
|
||||
it.jsInputFiles.set(
|
||||
project.fileTree(it.jsRootDir) { tree ->
|
||||
tree.include("**/*.js")
|
||||
tree.include("**/*.jsx")
|
||||
tree.include("**/*.ts")
|
||||
tree.include("**/*.tsx")
|
||||
)
|
||||
|
||||
tree.exclude("node_modules/**/*")
|
||||
tree.exclude("**/*.d.ts")
|
||||
// We want to exclude the build directory, to don't pick them up for execution
|
||||
// avoidance.
|
||||
tree.exclude("**/build/**/*")
|
||||
})
|
||||
|
||||
val needsCodegenFromPackageJson =
|
||||
project.needsCodegenFromPackageJson(rootExtension.root)
|
||||
it.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
|
||||
}
|
||||
val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(rootExtension.root)
|
||||
it.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
|
||||
}
|
||||
|
||||
// We create the task to generate Java code from schema.
|
||||
val generateCodegenArtifactsTask =
|
||||
project.tasks.register(
|
||||
"generateCodegenArtifactsFromSchema", GenerateCodegenArtifactsTask::class.java) { task
|
||||
->
|
||||
task.dependsOn(generateCodegenSchemaTask)
|
||||
task.reactNativeDir.set(rootExtension.reactNativeDir)
|
||||
task.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
|
||||
task.generatedSrcDir.set(generatedSrcDir)
|
||||
task.packageJsonFile.set(findPackageJsonFile(project, rootExtension.root))
|
||||
task.codegenJavaPackageName.set(localExtension.codegenJavaPackageName)
|
||||
task.libraryName.set(localExtension.libraryName)
|
||||
task.nodeWorkingDir.set(project.layout.projectDirectory.asFile.absolutePath)
|
||||
"generateCodegenArtifactsFromSchema",
|
||||
GenerateCodegenArtifactsTask::class.java,
|
||||
) { task ->
|
||||
task.dependsOn(generateCodegenSchemaTask)
|
||||
task.reactNativeDir.set(rootExtension.reactNativeDir)
|
||||
task.nodeExecutableAndArgs.set(rootExtension.nodeExecutableAndArgs)
|
||||
task.generatedSrcDir.set(generatedSrcDir)
|
||||
task.packageJsonFile.set(findPackageJsonFile(project, rootExtension.root))
|
||||
task.codegenJavaPackageName.set(localExtension.codegenJavaPackageName)
|
||||
task.libraryName.set(localExtension.libraryName)
|
||||
task.nodeWorkingDir.set(project.layout.projectDirectory.asFile.absolutePath)
|
||||
|
||||
// Please note that appNeedsCodegen is triggering a read of the package.json at
|
||||
// configuration time as we need to feed the onlyIf condition of this task.
|
||||
// Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
|
||||
val needsCodegenFromPackageJson =
|
||||
project.needsCodegenFromPackageJson(rootExtension.root)
|
||||
val packageJson = findPackageJsonFile(project, rootExtension.root)
|
||||
val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }
|
||||
val includesGeneratedCode =
|
||||
parsedPackageJson?.codegenConfig?.includesGeneratedCode ?: false
|
||||
task.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
|
||||
}
|
||||
// Please note that appNeedsCodegen is triggering a read of the package.json at
|
||||
// configuration time as we need to feed the onlyIf condition of this task.
|
||||
// Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
|
||||
val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(rootExtension.root)
|
||||
val packageJson = findPackageJsonFile(project, rootExtension.root)
|
||||
val parsedPackageJson = packageJson?.let { JsonUtils.fromPackageJson(it) }
|
||||
val includesGeneratedCode =
|
||||
parsedPackageJson?.codegenConfig?.includesGeneratedCode ?: false
|
||||
task.onlyIf { (isLibrary || needsCodegenFromPackageJson) && !includesGeneratedCode }
|
||||
}
|
||||
|
||||
// We update the android configuration to include the generated sources.
|
||||
// This equivalent to this DSL:
|
||||
@@ -281,29 +261,34 @@ class ReactPlugin : Plugin<Project> {
|
||||
// dependency.
|
||||
val generatePackageListTask =
|
||||
project.tasks.register(
|
||||
"generateAutolinkingPackageList", GeneratePackageListTask::class.java) { task ->
|
||||
task.autolinkInputFile.set(rootGeneratedAutolinkingFile)
|
||||
task.generatedOutputDirectory.set(generatedAutolinkingJavaDir)
|
||||
}
|
||||
"generateAutolinkingPackageList",
|
||||
GeneratePackageListTask::class.java,
|
||||
) { task ->
|
||||
task.autolinkInputFile.set(rootGeneratedAutolinkingFile)
|
||||
task.generatedOutputDirectory.set(generatedAutolinkingJavaDir)
|
||||
}
|
||||
|
||||
// We add a task called generateAutolinkingPackageList to do not clash with the existing task
|
||||
// called generatePackageList. This can to be renamed once we unlink the rn <-> cli
|
||||
// dependency.
|
||||
val generateEntryPointTask =
|
||||
project.tasks.register(
|
||||
"generateReactNativeEntryPoint", GenerateEntryPointTask::class.java) { task ->
|
||||
task.autolinkInputFile.set(rootGeneratedAutolinkingFile)
|
||||
task.generatedOutputDirectory.set(generatedAutolinkingJavaDir)
|
||||
}
|
||||
"generateReactNativeEntryPoint",
|
||||
GenerateEntryPointTask::class.java,
|
||||
) { task ->
|
||||
task.autolinkInputFile.set(rootGeneratedAutolinkingFile)
|
||||
task.generatedOutputDirectory.set(generatedAutolinkingJavaDir)
|
||||
}
|
||||
|
||||
// We also need to generate code for C++ Autolinking
|
||||
val generateAutolinkingNewArchitectureFilesTask =
|
||||
project.tasks.register(
|
||||
"generateAutolinkingNewArchitectureFiles",
|
||||
GenerateAutolinkingNewArchitecturesFileTask::class.java) { task ->
|
||||
task.autolinkInputFile.set(rootGeneratedAutolinkingFile)
|
||||
task.generatedOutputDirectory.set(generatedAutolinkingJniDir)
|
||||
}
|
||||
GenerateAutolinkingNewArchitecturesFileTask::class.java,
|
||||
) { task ->
|
||||
task.autolinkInputFile.set(rootGeneratedAutolinkingFile)
|
||||
task.generatedOutputDirectory.set(generatedAutolinkingJniDir)
|
||||
}
|
||||
project.tasks
|
||||
.named("preBuild", Task::class.java)
|
||||
.dependsOn(generateAutolinkingNewArchitectureFilesTask)
|
||||
@@ -320,7 +305,8 @@ class ReactPlugin : Plugin<Project> {
|
||||
project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java).apply {
|
||||
onVariants(selector().all()) { variant ->
|
||||
variant.sources.java?.addStaticSourceDirectory(
|
||||
generatedAutolinkingJavaDir.get().asFile.absolutePath)
|
||||
generatedAutolinkingJavaDir.get().asFile.absolutePath
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+43
-3
@@ -7,8 +7,10 @@
|
||||
|
||||
package com.facebook.react
|
||||
|
||||
import com.facebook.react.utils.PropertyUtils
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.plugin.extraProperties
|
||||
|
||||
/**
|
||||
* Gradle plugin applied to the `android/build.gradle` file.
|
||||
@@ -18,13 +20,25 @@ import org.gradle.api.Project
|
||||
*/
|
||||
class ReactRootProjectPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.subprojects {
|
||||
checkLegacyArchProperty(project)
|
||||
project.subprojects { subproject ->
|
||||
// As the :app project (i.e. ReactPlugin) configures both namespaces and JVM toolchains
|
||||
// for libraries, its evaluation must happen before the libraries' evaluation.
|
||||
// Eventually the configuration of namespace/JVM toolchain can be moved inside this plugin.
|
||||
if (it.path != ":app") {
|
||||
it.evaluationDependsOn(":app")
|
||||
if (subproject.path != ":app") {
|
||||
subproject.evaluationDependsOn(":app")
|
||||
}
|
||||
// We set the New Architecture properties to true for all subprojects. So that
|
||||
// libraries don't need to be modified and can keep on using the isNewArchEnabled()
|
||||
// function to check if property is set.
|
||||
if (subproject.hasProperty(PropertyUtils.SCOPED_NEW_ARCH_ENABLED)) {
|
||||
subproject.setProperty(PropertyUtils.SCOPED_NEW_ARCH_ENABLED, "true")
|
||||
}
|
||||
if (subproject.hasProperty(PropertyUtils.NEW_ARCH_ENABLED)) {
|
||||
subproject.setProperty(PropertyUtils.NEW_ARCH_ENABLED, "true")
|
||||
}
|
||||
subproject.extraProperties.set(PropertyUtils.NEW_ARCH_ENABLED, "true")
|
||||
subproject.extraProperties.set(PropertyUtils.SCOPED_NEW_ARCH_ENABLED, "true")
|
||||
}
|
||||
// We need to make sure that `:app:preBuild` task depends on all other subprojects' preBuild
|
||||
// tasks. This is necessary in order to have all the codegen generated code before the CMake
|
||||
@@ -43,4 +57,30 @@ class ReactRootProjectPlugin : Plugin<Project> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkLegacyArchProperty(project: Project) {
|
||||
if (
|
||||
(project.hasProperty(PropertyUtils.NEW_ARCH_ENABLED) &&
|
||||
!project.property(PropertyUtils.NEW_ARCH_ENABLED).toString().toBoolean()) ||
|
||||
(project.hasProperty(PropertyUtils.SCOPED_NEW_ARCH_ENABLED) &&
|
||||
!project.property(PropertyUtils.SCOPED_NEW_ARCH_ENABLED).toString().toBoolean())
|
||||
) {
|
||||
project.logger.error(
|
||||
"""
|
||||
********************************************************************************
|
||||
|
||||
WARNING: Setting `newArchEnabled=false` in your `gradle.properties` file is not
|
||||
supported anymore since React Native 0.82.
|
||||
|
||||
You can remove the line from your `gradle.properties` file.
|
||||
|
||||
The application will run with the New Architecture enabled by default.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -54,9 +54,11 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
|
||||
|
||||
configureNewArchPackagingOptions(project, config, variant)
|
||||
configureJsEnginePackagingOptions(config, variant, isHermesEnabledInThisVariant, useThirdPartyJSC)
|
||||
if (!isHermesEnabledInThisVariant &&
|
||||
!useThirdPartyJSC &&
|
||||
rootProject.name != "react-native-github") {
|
||||
if (
|
||||
!isHermesEnabledInThisVariant &&
|
||||
!useThirdPartyJSC &&
|
||||
rootProject.name != "react-native-github"
|
||||
) {
|
||||
showJSCRemovalMessage(project)
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -39,12 +39,15 @@ abstract class PrivateReactExtension @Inject constructor(project: Project) {
|
||||
// - We're inside a user project, so inside the ./android folder. Default should be
|
||||
// ../
|
||||
// User can always override this default by setting a `root =` inside the template.
|
||||
if (project.rootProject.name == "react-native-github" ||
|
||||
project.rootProject.name == "react-native-build-from-source") {
|
||||
if (
|
||||
project.rootProject.name == "react-native-github" ||
|
||||
project.rootProject.name == "react-native-build-from-source"
|
||||
) {
|
||||
project.rootProject.layout.projectDirectory.dir("../../")
|
||||
} else {
|
||||
project.rootProject.layout.projectDirectory.dir("../")
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
val reactNativeDir: DirectoryProperty =
|
||||
objects.directoryProperty().convention(root.dir("node_modules/react-native"))
|
||||
|
||||
+11
-5
@@ -111,7 +111,11 @@ abstract class BundleHermesCTask : DefaultTask() {
|
||||
val composeScriptFile = File(reactNativeDir, "scripts/compose-source-maps.js")
|
||||
val composeSourceMapsCommand =
|
||||
getComposeSourceMapsCommand(
|
||||
composeScriptFile, packagerSourceMap, compilerSourceMap, outputSourceMap)
|
||||
composeScriptFile,
|
||||
packagerSourceMap,
|
||||
compilerSourceMap,
|
||||
outputSourceMap,
|
||||
)
|
||||
runCommand(composeSourceMapsCommand)
|
||||
}
|
||||
}
|
||||
@@ -172,7 +176,7 @@ abstract class BundleHermesCTask : DefaultTask() {
|
||||
internal fun getHermescCommand(
|
||||
hermesCommand: String,
|
||||
bytecodeFile: File,
|
||||
bundleFile: File
|
||||
bundleFile: File,
|
||||
): List<Any> {
|
||||
val rootFile = root.get().asFile
|
||||
return windowsAwareCommandLine(
|
||||
@@ -183,14 +187,15 @@ abstract class BundleHermesCTask : DefaultTask() {
|
||||
"-out",
|
||||
bytecodeFile.cliPath(rootFile),
|
||||
bundleFile.cliPath(rootFile),
|
||||
*hermesFlags.get().toTypedArray())
|
||||
*hermesFlags.get().toTypedArray(),
|
||||
)
|
||||
}
|
||||
|
||||
internal fun getComposeSourceMapsCommand(
|
||||
composeScript: File,
|
||||
packagerSourceMap: File,
|
||||
compilerSourceMap: File,
|
||||
outputSourceMap: File
|
||||
outputSourceMap: File,
|
||||
): List<Any> {
|
||||
val rootFile = root.get().asFile
|
||||
return windowsAwareCommandLine(
|
||||
@@ -199,6 +204,7 @@ abstract class BundleHermesCTask : DefaultTask() {
|
||||
packagerSourceMap.cliPath(rootFile),
|
||||
compilerSourceMap.cliPath(rootFile),
|
||||
"-o",
|
||||
outputSourceMap.cliPath(rootFile))
|
||||
outputSourceMap.cliPath(rootFile),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+72
-72
@@ -165,88 +165,88 @@ abstract class GenerateAutolinkingNewArchitecturesFileTask : DefaultTask() {
|
||||
// language=cmake
|
||||
val CMAKE_TEMPLATE =
|
||||
"""
|
||||
# This code was generated by [React Native](https://www.npmjs.com/package/@react-native/gradle-plugin)
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
# We set REACTNATIVE_MERGED_SO so libraries/apps can selectively decide to depend on either libreactnative.so
|
||||
# or link against a old prefab target (this is needed for React Native 0.76 on).
|
||||
set(REACTNATIVE_MERGED_SO true)
|
||||
|
||||
{{ libraryIncludes }}
|
||||
|
||||
set(AUTOLINKED_LIBRARIES
|
||||
{{ libraryModules }}
|
||||
)
|
||||
"""
|
||||
# This code was generated by [React Native](https://www.npmjs.com/package/@react-native/gradle-plugin)
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
# We set REACTNATIVE_MERGED_SO so libraries/apps can selectively decide to depend on either libreactnative.so
|
||||
# or link against a old prefab target (this is needed for React Native 0.76 on).
|
||||
set(REACTNATIVE_MERGED_SO true)
|
||||
|
||||
{{ libraryIncludes }}
|
||||
|
||||
set(AUTOLINKED_LIBRARIES
|
||||
{{ libraryModules }}
|
||||
)
|
||||
"""
|
||||
.trimIndent()
|
||||
|
||||
// language=cpp
|
||||
val CPP_TEMPLATE =
|
||||
"""
|
||||
/**
|
||||
* This code was generated by [React Native](https://www.npmjs.com/package/@react-native/gradle-plugin).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "autolinking.h"
|
||||
{{ autolinkingCppIncludes }}
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> autolinking_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
{{ autolinkingCppTurboModuleJavaProviders }}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> autolinking_cxxModuleProvider(const std::string moduleName, const std::shared_ptr<CallInvoker>& jsInvoker) {
|
||||
{{ autolinkingCppTurboModuleCxxProviders }}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void autolinking_registerProviders(std::shared_ptr<ComponentDescriptorProviderRegistry const> providerRegistry) {
|
||||
{{ autolinkingCppComponentDescriptors }}
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
"""
|
||||
/**
|
||||
* This code was generated by [React Native](https://www.npmjs.com/package/@react-native/gradle-plugin).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "autolinking.h"
|
||||
{{ autolinkingCppIncludes }}
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> autolinking_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
{{ autolinkingCppTurboModuleJavaProviders }}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> autolinking_cxxModuleProvider(const std::string moduleName, const std::shared_ptr<CallInvoker>& jsInvoker) {
|
||||
{{ autolinkingCppTurboModuleCxxProviders }}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void autolinking_registerProviders(std::shared_ptr<ComponentDescriptorProviderRegistry const> providerRegistry) {
|
||||
{{ autolinkingCppComponentDescriptors }}
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
"""
|
||||
.trimIndent()
|
||||
|
||||
// language=cpp
|
||||
val hTemplate =
|
||||
"""
|
||||
/**
|
||||
* This code was generated by [React Native](https://www.npmjs.com/package/@react-native/gradle-plugin).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ReactCommon/CallInvoker.h>
|
||||
#include <ReactCommon/JavaTurboModule.h>
|
||||
#include <ReactCommon/TurboModule.h>
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> autolinking_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
std::shared_ptr<TurboModule> autolinking_cxxModuleProvider(const std::string moduleName, const std::shared_ptr<CallInvoker>& jsInvoker);
|
||||
void autolinking_registerProviders(std::shared_ptr<ComponentDescriptorProviderRegistry const> providerRegistry);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
"""
|
||||
/**
|
||||
* This code was generated by [React Native](https://www.npmjs.com/package/@react-native/gradle-plugin).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ReactCommon/CallInvoker.h>
|
||||
#include <ReactCommon/JavaTurboModule.h>
|
||||
#include <ReactCommon/TurboModule.h>
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::shared_ptr<TurboModule> autolinking_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
std::shared_ptr<TurboModule> autolinking_cxxModuleProvider(const std::string moduleName, const std::shared_ptr<CallInvoker>& jsInvoker);
|
||||
void autolinking_registerProviders(std::shared_ptr<ComponentDescriptorProviderRegistry const> providerRegistry);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
"""
|
||||
.trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -81,6 +81,8 @@ abstract class GenerateCodegenArtifactsTask : Exec() {
|
||||
"--libraryName",
|
||||
libraryName,
|
||||
"--javaPackageName",
|
||||
codegenJavaPackageName))
|
||||
codegenJavaPackageName,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -69,6 +69,7 @@ abstract class GenerateCodegenSchemaTask : Exec() {
|
||||
"NativeSampleTurboModule",
|
||||
generatedSchemaFile.get().asFile.cliPath(workingDir),
|
||||
jsRootDir.asFile.get().cliPath(workingDir),
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+46
-44
@@ -32,17 +32,19 @@ abstract class GenerateEntryPointTask : DefaultTask() {
|
||||
JsonUtils.fromAutolinkingConfigJson(autolinkInputFile.get().asFile)
|
||||
?: error(
|
||||
"""
|
||||
RNGP - Autolinking: Could not parse autolinking config file:
|
||||
${autolinkInputFile.get().asFile.absolutePath}
|
||||
|
||||
The file is either missing or not containing valid JSON so the build won't succeed.
|
||||
"""
|
||||
.trimIndent())
|
||||
RNGP - Autolinking: Could not parse autolinking config file:
|
||||
${autolinkInputFile.get().asFile.absolutePath}
|
||||
|
||||
The file is either missing or not containing valid JSON so the build won't succeed.
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val packageName =
|
||||
model.project?.android?.packageName
|
||||
?: error(
|
||||
"RNGP - Autolinking: Could not find project.android.packageName in react-native config output! Could not autolink packages without this field.")
|
||||
"RNGP - Autolinking: Could not find project.android.packageName in react-native config output! Could not autolink packages without this field."
|
||||
)
|
||||
val generatedFileContents = composeFileContent(packageName)
|
||||
|
||||
val outputDir = generatedOutputDirectory.get().asFile
|
||||
@@ -62,45 +64,45 @@ abstract class GenerateEntryPointTask : DefaultTask() {
|
||||
// language=java
|
||||
val generatedFileContentsTemplate =
|
||||
"""
|
||||
package com.facebook.react;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
||||
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger;
|
||||
import com.facebook.react.views.view.WindowUtilKt;
|
||||
import com.facebook.react.soloader.OpenSourceMergedSoMapping;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class is the entry point for loading React Native using the configuration
|
||||
* that the users specifies in their .gradle files.
|
||||
*
|
||||
* The `loadReactNative(this)` method invocation should be called inside the
|
||||
* application onCreate otherwise the app won't load correctly.
|
||||
*/
|
||||
public class ReactNativeApplicationEntryPoint {
|
||||
public static void loadReactNative(Context context) {
|
||||
try {
|
||||
SoLoader.init(context, OpenSourceMergedSoMapping.INSTANCE);
|
||||
} catch (IOException error) {
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
|
||||
if ({{packageName}}.BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
DefaultNewArchitectureEntryPoint.load();
|
||||
}
|
||||
|
||||
if ({{packageName}}.BuildConfig.IS_EDGE_TO_EDGE_ENABLED) {
|
||||
WindowUtilKt.setEdgeToEdgeFeatureFlagOn();
|
||||
package com.facebook.react;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
||||
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger;
|
||||
import com.facebook.react.views.view.WindowUtilKt;
|
||||
import com.facebook.react.soloader.OpenSourceMergedSoMapping;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class is the entry point for loading React Native using the configuration
|
||||
* that the users specifies in their .gradle files.
|
||||
*
|
||||
* The `loadReactNative(this)` method invocation should be called inside the
|
||||
* application onCreate otherwise the app won't load correctly.
|
||||
*/
|
||||
public class ReactNativeApplicationEntryPoint {
|
||||
public static void loadReactNative(Context context) {
|
||||
try {
|
||||
SoLoader.init(context, OpenSourceMergedSoMapping.INSTANCE);
|
||||
} catch (IOException error) {
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
|
||||
if ({{packageName}}.BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
DefaultNewArchitectureEntryPoint.load();
|
||||
}
|
||||
|
||||
if ({{packageName}}.BuildConfig.IS_EDGE_TO_EDGE_ENABLED) {
|
||||
WindowUtilKt.setEdgeToEdgeFeatureFlagOn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
"""
|
||||
.trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
+74
-72
@@ -34,17 +34,19 @@ abstract class GeneratePackageListTask : DefaultTask() {
|
||||
JsonUtils.fromAutolinkingConfigJson(autolinkInputFile.get().asFile)
|
||||
?: error(
|
||||
"""
|
||||
RNGP - Autolinking: Could not parse autolinking config file:
|
||||
${autolinkInputFile.get().asFile.absolutePath}
|
||||
|
||||
The file is either missing or not containing valid JSON so the build won't succeed.
|
||||
"""
|
||||
.trimIndent())
|
||||
RNGP - Autolinking: Could not parse autolinking config file:
|
||||
${autolinkInputFile.get().asFile.absolutePath}
|
||||
|
||||
The file is either missing or not containing valid JSON so the build won't succeed.
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val packageName =
|
||||
model.project?.android?.packageName
|
||||
?: error(
|
||||
"RNGP - Autolinking: Could not find project.android.packageName in react-native config output! Could not autolink packages without this field.")
|
||||
"RNGP - Autolinking: Could not find project.android.packageName in react-native config output! Could not autolink packages without this field."
|
||||
)
|
||||
|
||||
val androidPackages = filterAndroidPackages(model)
|
||||
val packageImports = composePackageImports(packageName, androidPackages)
|
||||
@@ -61,7 +63,7 @@ abstract class GeneratePackageListTask : DefaultTask() {
|
||||
|
||||
internal fun composePackageImports(
|
||||
packageName: String,
|
||||
packages: Map<String, ModelAutolinkingDependenciesPlatformAndroidJson>
|
||||
packages: Map<String, ModelAutolinkingDependenciesPlatformAndroidJson>,
|
||||
) =
|
||||
packages.entries.joinToString("\n") { (name, dep) ->
|
||||
val packageImportPath =
|
||||
@@ -73,7 +75,7 @@ abstract class GeneratePackageListTask : DefaultTask() {
|
||||
|
||||
internal fun composePackageInstance(
|
||||
packageName: String,
|
||||
packages: Map<String, ModelAutolinkingDependenciesPlatformAndroidJson>
|
||||
packages: Map<String, ModelAutolinkingDependenciesPlatformAndroidJson>,
|
||||
) =
|
||||
if (packages.isEmpty()) {
|
||||
""
|
||||
@@ -134,69 +136,69 @@ abstract class GeneratePackageListTask : DefaultTask() {
|
||||
// language=java
|
||||
val generatedFileContentsTemplate =
|
||||
"""
|
||||
package com.facebook.react;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.shell.MainPackageConfig;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
|
||||
{{ packageImports }}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PackageList {
|
||||
private Application application;
|
||||
private ReactNativeHost reactNativeHost;
|
||||
private MainPackageConfig mConfig;
|
||||
|
||||
public PackageList(ReactNativeHost reactNativeHost) {
|
||||
this(reactNativeHost, null);
|
||||
}
|
||||
|
||||
public PackageList(Application application) {
|
||||
this(application, null);
|
||||
}
|
||||
|
||||
public PackageList(ReactNativeHost reactNativeHost, MainPackageConfig config) {
|
||||
this.reactNativeHost = reactNativeHost;
|
||||
mConfig = config;
|
||||
}
|
||||
|
||||
public PackageList(Application application, MainPackageConfig config) {
|
||||
this.reactNativeHost = null;
|
||||
this.application = application;
|
||||
mConfig = config;
|
||||
}
|
||||
|
||||
private ReactNativeHost getReactNativeHost() {
|
||||
return this.reactNativeHost;
|
||||
}
|
||||
|
||||
private Resources getResources() {
|
||||
return this.getApplication().getResources();
|
||||
}
|
||||
|
||||
private Application getApplication() {
|
||||
if (this.reactNativeHost == null) return this.application;
|
||||
return this.reactNativeHost.getApplication();
|
||||
}
|
||||
|
||||
private Context getApplicationContext() {
|
||||
return this.getApplication().getApplicationContext();
|
||||
}
|
||||
|
||||
public ArrayList<ReactPackage> getPackages() {
|
||||
return new ArrayList<>(Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage(mConfig){{ packageClassInstances }}
|
||||
));
|
||||
}
|
||||
}
|
||||
"""
|
||||
package com.facebook.react;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.shell.MainPackageConfig;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
|
||||
{{ packageImports }}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PackageList {
|
||||
private Application application;
|
||||
private ReactNativeHost reactNativeHost;
|
||||
private MainPackageConfig mConfig;
|
||||
|
||||
public PackageList(ReactNativeHost reactNativeHost) {
|
||||
this(reactNativeHost, null);
|
||||
}
|
||||
|
||||
public PackageList(Application application) {
|
||||
this(application, null);
|
||||
}
|
||||
|
||||
public PackageList(ReactNativeHost reactNativeHost, MainPackageConfig config) {
|
||||
this.reactNativeHost = reactNativeHost;
|
||||
mConfig = config;
|
||||
}
|
||||
|
||||
public PackageList(Application application, MainPackageConfig config) {
|
||||
this.reactNativeHost = null;
|
||||
this.application = application;
|
||||
mConfig = config;
|
||||
}
|
||||
|
||||
private ReactNativeHost getReactNativeHost() {
|
||||
return this.reactNativeHost;
|
||||
}
|
||||
|
||||
private Resources getResources() {
|
||||
return this.getApplication().getResources();
|
||||
}
|
||||
|
||||
private Application getApplication() {
|
||||
if (this.reactNativeHost == null) return this.application;
|
||||
return this.reactNativeHost.getApplication();
|
||||
}
|
||||
|
||||
private Context getApplicationContext() {
|
||||
return this.getApplication().getApplicationContext();
|
||||
}
|
||||
|
||||
public ArrayList<ReactPackage> getPackages() {
|
||||
return new ArrayList<>(Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage(mConfig){{ packageClassInstances }}
|
||||
));
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -54,7 +54,8 @@ abstract class BuildCodegenCLITask : Exec() {
|
||||
windowsAwareBashCommandLine(
|
||||
codegenDir.asFile.get().canonicalPath.unixifyPath().plus(BUILD_SCRIPT_PATH),
|
||||
bashWindowsHome = bashWindowsHome.orNull,
|
||||
))
|
||||
)
|
||||
)
|
||||
super.exec()
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -29,8 +29,10 @@ abstract class CustomExecTask : Exec() {
|
||||
@get:Input @get:Optional abstract val onlyIfProvidedPathDoesNotExists: Property<String>
|
||||
|
||||
override fun exec() {
|
||||
if (onlyIfProvidedPathDoesNotExists.isPresent &&
|
||||
File(onlyIfProvidedPathDoesNotExists.get()).exists()) {
|
||||
if (
|
||||
onlyIfProvidedPathDoesNotExists.isPresent &&
|
||||
File(onlyIfProvidedPathDoesNotExists.get()).exists()
|
||||
) {
|
||||
return
|
||||
}
|
||||
if (standardOutputFile.isPresent) {
|
||||
|
||||
+2
-1
@@ -40,7 +40,8 @@ abstract class PrepareBoostTask : DefaultTask() {
|
||||
"CMakeLists.txt",
|
||||
"boost_${boostVersion.get()}/boost/**/*.hpp",
|
||||
"boost/boost/**/*.hpp",
|
||||
"asm/**/*.S")
|
||||
"asm/**/*.S",
|
||||
)
|
||||
it.includeEmptyDirs = false
|
||||
it.into(outputDir)
|
||||
}
|
||||
|
||||
+6
-3
@@ -46,7 +46,8 @@ abstract class PrepareGflagsTask : DefaultTask() {
|
||||
action.include(
|
||||
"gflags-${gflagsVersion.get()}/src/*.h",
|
||||
"gflags-${gflagsVersion.get()}/src/*.cc",
|
||||
"CMakeLists.txt")
|
||||
"CMakeLists.txt",
|
||||
)
|
||||
action.filesMatching("*/src/*") { matchedFile ->
|
||||
matchedFile.path = "gflags/${matchedFile.name}"
|
||||
}
|
||||
@@ -63,8 +64,10 @@ abstract class PrepareGflagsTask : DefaultTask() {
|
||||
.replace(Regex("@GFLAGS_NAMESPACE@"), "gflags")
|
||||
.replace(
|
||||
Regex(
|
||||
"@(HAVE_STDINT_H|HAVE_SYS_TYPES_H|HAVE_INTTYPES_H|GFLAGS_INTTYPES_FORMAT_C99)@"),
|
||||
"1")
|
||||
"@(HAVE_STDINT_H|HAVE_SYS_TYPES_H|HAVE_INTTYPES_H|GFLAGS_INTTYPES_FORMAT_C99)@"
|
||||
),
|
||||
"1",
|
||||
)
|
||||
.replace(Regex("@([A-Z0-9_]+)@"), "1")
|
||||
}
|
||||
matchedFile.path = "gflags/${matchedFile.name.removeSuffix(".in")}"
|
||||
|
||||
+7
-3
@@ -60,8 +60,11 @@ abstract class PrepareGlogTask : DefaultTask() {
|
||||
"ac_cv___attribute___noinline" to "__attribute__ ((noinline))",
|
||||
"ac_cv___attribute___noreturn" to "__attribute__ ((noreturn))",
|
||||
"ac_cv___attribute___printf_4_5" to
|
||||
"__attribute__((__format__ (__printf__, 4, 5)))")),
|
||||
ReplaceTokens::class.java)
|
||||
"__attribute__((__format__ (__printf__, 4, 5)))",
|
||||
)
|
||||
),
|
||||
ReplaceTokens::class.java,
|
||||
)
|
||||
matchedFile.path = (matchedFile.name.removeSuffix(".in"))
|
||||
}
|
||||
action.into(outputDir)
|
||||
@@ -74,7 +77,8 @@ abstract class PrepareGlogTask : DefaultTask() {
|
||||
"logging.h",
|
||||
"raw_logging.h",
|
||||
"vlog_is_on.h",
|
||||
"**/src/glog/log_severity.h")
|
||||
"**/src/glog/log_severity.h",
|
||||
)
|
||||
action.eachFile { file -> file.path = file.name }
|
||||
action.includeEmptyDirs = false
|
||||
action.into(exportedDir)
|
||||
|
||||
+1
-1
@@ -23,6 +23,6 @@ data class PrefabPreprocessingEntry(
|
||||
) : Serializable {
|
||||
constructor(
|
||||
libraryName: String,
|
||||
pathToPrefixCouple: Pair<String, String>
|
||||
pathToPrefixCouple: Pair<String, String>,
|
||||
) : this(libraryName, listOf(pathToPrefixCouple))
|
||||
}
|
||||
|
||||
+12
-3
@@ -66,9 +66,15 @@ internal object AgpConfiguratorUtils {
|
||||
ext.buildFeatures.buildConfig = true
|
||||
ext.defaultConfig.buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", "true")
|
||||
ext.defaultConfig.buildConfigField(
|
||||
"boolean", "IS_HERMES_ENABLED", project.isHermesEnabled.toString())
|
||||
"boolean",
|
||||
"IS_HERMES_ENABLED",
|
||||
project.isHermesEnabled.toString(),
|
||||
)
|
||||
ext.defaultConfig.buildConfigField(
|
||||
"boolean", "IS_EDGE_TO_EDGE_ENABLED", project.isEdgeToEdgeEnabled.toString())
|
||||
"boolean",
|
||||
"IS_EDGE_TO_EDGE_ENABLED",
|
||||
project.isEdgeToEdgeEnabled.toString(),
|
||||
)
|
||||
}
|
||||
}
|
||||
project.pluginManager.withPlugin("com.android.application", action)
|
||||
@@ -95,7 +101,10 @@ internal object AgpConfiguratorUtils {
|
||||
.getByType(ApplicationAndroidComponentsExtension::class.java)
|
||||
.finalizeDsl { ext ->
|
||||
ext.defaultConfig.resValue(
|
||||
"string", "react_native_dev_server_ip", getHostIpAddress())
|
||||
"string",
|
||||
"react_native_dev_server_ip",
|
||||
getHostIpAddress(),
|
||||
)
|
||||
ext.defaultConfig.resValue("integer", "react_native_dev_server_port", devServerPort)
|
||||
}
|
||||
}
|
||||
|
||||
+9
-8
@@ -39,7 +39,8 @@ internal object BackwardCompatUtils {
|
||||
|
||||
********************************************************************************
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,14 +56,14 @@ internal object BackwardCompatUtils {
|
||||
val message =
|
||||
"""
|
||||
|
||||
=============== JavaScriptCore is being moved ===============
|
||||
JavaScriptCore has been extracted from react-native core
|
||||
and will be removed in a future release. It can now be
|
||||
installed from `@react-native-community/javascriptcore`
|
||||
See: https://github.com/react-native-community/javascriptcore
|
||||
=============================================================
|
||||
=============== JavaScriptCore is being moved ===============
|
||||
JavaScriptCore has been extracted from react-native core
|
||||
and will be removed in a future release. It can now be
|
||||
installed from `@react-native-community/javascriptcore`
|
||||
See: https://github.com/react-native-community/javascriptcore
|
||||
=============================================================
|
||||
|
||||
"""
|
||||
"""
|
||||
.trimIndent()
|
||||
project.logger.warn(message)
|
||||
hasShownJSCRemovalMessage = true
|
||||
|
||||
+18
-9
@@ -33,7 +33,8 @@ internal object DependencyUtils {
|
||||
val exclusiveEnterpriseRepository = project.rootProject.exclusiveEnterpriseRepository()
|
||||
if (exclusiveEnterpriseRepository != null) {
|
||||
project.logger.lifecycle(
|
||||
"Replacing ALL Maven Repositories with: $exclusiveEnterpriseRepository")
|
||||
"Replacing ALL Maven Repositories with: $exclusiveEnterpriseRepository"
|
||||
)
|
||||
}
|
||||
|
||||
project.rootProject.allprojects { eachProject ->
|
||||
@@ -99,7 +100,7 @@ internal object DependencyUtils {
|
||||
fun configureDependencies(
|
||||
project: Project,
|
||||
versionString: String,
|
||||
groupString: String = DEFAULT_INTERNAL_PUBLISHING_GROUP
|
||||
groupString: String = DEFAULT_INTERNAL_PUBLISHING_GROUP,
|
||||
) {
|
||||
if (versionString.isBlank()) return
|
||||
project.rootProject.allprojects { eachProject ->
|
||||
@@ -127,30 +128,38 @@ internal object DependencyUtils {
|
||||
|
||||
internal fun getDependencySubstitutions(
|
||||
versionString: String,
|
||||
groupString: String = DEFAULT_INTERNAL_PUBLISHING_GROUP
|
||||
groupString: String = DEFAULT_INTERNAL_PUBLISHING_GROUP,
|
||||
): List<Triple<String, String, String>> {
|
||||
val dependencySubstitution = mutableListOf<Triple<String, String, String>>()
|
||||
dependencySubstitution.add(
|
||||
Triple(
|
||||
"com.facebook.react:react-native",
|
||||
"${groupString}:react-android:${versionString}",
|
||||
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210."))
|
||||
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.",
|
||||
)
|
||||
)
|
||||
dependencySubstitution.add(
|
||||
Triple(
|
||||
"com.facebook.react:hermes-engine",
|
||||
"${groupString}:hermes-android:${versionString}",
|
||||
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210."))
|
||||
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.",
|
||||
)
|
||||
)
|
||||
if (groupString != DEFAULT_INTERNAL_PUBLISHING_GROUP) {
|
||||
dependencySubstitution.add(
|
||||
Triple(
|
||||
"com.facebook.react:react-android",
|
||||
"${groupString}:react-android:${versionString}",
|
||||
"The react-android dependency was modified to use the correct Maven group."))
|
||||
"The react-android dependency was modified to use the correct Maven group.",
|
||||
)
|
||||
)
|
||||
dependencySubstitution.add(
|
||||
Triple(
|
||||
"com.facebook.react:hermes-android",
|
||||
"${groupString}:hermes-android:${versionString}",
|
||||
"The hermes-android dependency was modified to use the correct Maven group."))
|
||||
"The hermes-android dependency was modified to use the correct Maven group.",
|
||||
)
|
||||
)
|
||||
}
|
||||
return dependencySubstitution
|
||||
}
|
||||
@@ -175,7 +184,7 @@ internal object DependencyUtils {
|
||||
|
||||
fun Project.mavenRepoFromUrl(
|
||||
url: String,
|
||||
action: (MavenArtifactRepository) -> Unit = {}
|
||||
action: (MavenArtifactRepository) -> Unit = {},
|
||||
): MavenArtifactRepository =
|
||||
project.repositories.maven {
|
||||
it.url = URI.create(url)
|
||||
@@ -184,7 +193,7 @@ internal object DependencyUtils {
|
||||
|
||||
fun Project.mavenRepoFromURI(
|
||||
uri: URI,
|
||||
action: (MavenArtifactRepository) -> Unit = {}
|
||||
action: (MavenArtifactRepository) -> Unit = {},
|
||||
): MavenArtifactRepository =
|
||||
project.repositories.maven {
|
||||
it.url = uri
|
||||
|
||||
+8
-5
@@ -30,7 +30,8 @@ internal object NdkConfiguratorUtils {
|
||||
ext.externalNativeBuild.cmake.path =
|
||||
File(
|
||||
extension.reactNativeDir.get().asFile,
|
||||
"ReactAndroid/cmake-utils/default-app-setup/CMakeLists.txt")
|
||||
"ReactAndroid/cmake-utils/default-app-setup/CMakeLists.txt",
|
||||
)
|
||||
}
|
||||
|
||||
// Parameters should be provided in an additive manner (do not override what
|
||||
@@ -44,7 +45,8 @@ internal object NdkConfiguratorUtils {
|
||||
}
|
||||
if (cmakeArgs.none { it.startsWith("-DREACT_ANDROID_DIR") }) {
|
||||
cmakeArgs.add(
|
||||
"-DREACT_ANDROID_DIR=${extension.reactNativeDir.file("ReactAndroid").get().asFile}")
|
||||
"-DREACT_ANDROID_DIR=${extension.reactNativeDir.file("ReactAndroid").get().asFile}"
|
||||
)
|
||||
}
|
||||
if (cmakeArgs.none { it.startsWith("-DANDROID_STL") }) {
|
||||
cmakeArgs.add("-DANDROID_STL=c++_shared")
|
||||
@@ -71,7 +73,7 @@ internal object NdkConfiguratorUtils {
|
||||
fun configureNewArchPackagingOptions(
|
||||
project: Project,
|
||||
extension: ReactExtension,
|
||||
variant: Variant
|
||||
variant: Variant,
|
||||
) {
|
||||
// We set some packagingOptions { pickFirst ... } for our users for libraries we own.
|
||||
variant.packaging.jniLibs.pickFirsts.addAll(
|
||||
@@ -85,7 +87,8 @@ internal object NdkConfiguratorUtils {
|
||||
"**/libjsi.so",
|
||||
// AGP will give priority of libc++_shared coming from App modules.
|
||||
"**/libc++_shared.so",
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +110,7 @@ internal object NdkConfiguratorUtils {
|
||||
|
||||
fun getPackagingOptionsForVariant(
|
||||
hermesEnabled: Boolean,
|
||||
useThirdPartyJSC: Boolean
|
||||
useThirdPartyJSC: Boolean,
|
||||
): Pair<List<String>, List<String>> {
|
||||
val excludes = mutableListOf<String>()
|
||||
val includes = mutableListOf<String>()
|
||||
|
||||
+19
-13
@@ -30,7 +30,8 @@ internal fun detectedEntryFile(config: ReactExtension, envVariableOverride: Stri
|
||||
detectEntryFile(
|
||||
entryFile = config.entryFile.orNull?.asFile,
|
||||
reactRoot = config.root.get().asFile,
|
||||
envVariableOverride = envVariableOverride)
|
||||
envVariableOverride = envVariableOverride,
|
||||
)
|
||||
|
||||
/**
|
||||
* Computes the CLI file for React Native. The Algo follows this order:
|
||||
@@ -42,7 +43,8 @@ internal fun detectedEntryFile(config: ReactExtension, envVariableOverride: Stri
|
||||
internal fun detectedCliFile(config: ReactExtension): File =
|
||||
detectCliFile(
|
||||
reactNativeRoot = config.root.get().asFile,
|
||||
preconfiguredCliFile = config.cliFile.asFile.orNull)
|
||||
preconfiguredCliFile = config.cliFile.asFile.orNull,
|
||||
)
|
||||
|
||||
/**
|
||||
* Computes the `hermesc` command location. The Algo follows this order:
|
||||
@@ -60,7 +62,7 @@ internal fun detectedHermesCommand(config: ReactExtension): String =
|
||||
private fun detectEntryFile(
|
||||
entryFile: File?,
|
||||
reactRoot: File,
|
||||
envVariableOverride: String? = null
|
||||
envVariableOverride: String? = null,
|
||||
): File =
|
||||
when {
|
||||
envVariableOverride != null -> File(reactRoot, envVariableOverride)
|
||||
@@ -83,7 +85,8 @@ private fun detectCliFile(reactNativeRoot: File, preconfiguredCliFile: File?): F
|
||||
.exec(
|
||||
arrayOf("node", "--print", "require.resolve('react-native/cli');"),
|
||||
emptyArray(),
|
||||
reactNativeRoot)
|
||||
reactNativeRoot,
|
||||
)
|
||||
|
||||
val nodeProcessOutput = nodeProcess.inputStream.use { it.bufferedReader().readText().trim() }
|
||||
|
||||
@@ -102,13 +105,14 @@ private fun detectCliFile(reactNativeRoot: File, preconfiguredCliFile: File?): F
|
||||
|
||||
error(
|
||||
"""
|
||||
Couldn't determine CLI location!
|
||||
Couldn't determine CLI location!
|
||||
|
||||
Please set `react { cliFile = file(...) }` inside your
|
||||
build.gradle to the path of the react-native cli.js file.
|
||||
This file typically resides in `node_modules/react-native/cli.js`
|
||||
"""
|
||||
.trimIndent())
|
||||
Please set `react { cliFile = file(...) }` inside your
|
||||
build.gradle to the path of the react-native cli.js file.
|
||||
This file typically resides in `node_modules/react-native/cli.js`
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,7 +161,8 @@ internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String
|
||||
error(
|
||||
"Couldn't determine Hermesc location. " +
|
||||
"Please set `react.hermesCommand` to the path of the hermesc binary file. " +
|
||||
"node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc")
|
||||
"node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,7 +188,8 @@ internal fun getHermesOSBin(): String {
|
||||
if (Os.isLinuxAmd64()) return "linux64-bin"
|
||||
error(
|
||||
"OS not recognized. Please set project.react.hermesCommand " +
|
||||
"to the path of a working Hermes compiler.")
|
||||
"to the path of a working Hermes compiler."
|
||||
)
|
||||
}
|
||||
|
||||
internal fun projectPathToLibraryName(projectPath: String): String =
|
||||
@@ -221,7 +227,7 @@ internal fun findPackageJsonFile(project: Project, rootProperty: DirectoryProper
|
||||
*/
|
||||
internal fun readPackageJsonFile(
|
||||
project: Project,
|
||||
rootProperty: DirectoryProperty
|
||||
rootProperty: DirectoryProperty,
|
||||
): ModelPackageJson? {
|
||||
val packageJson = findPackageJsonFile(project, rootProperty)
|
||||
return packageJson?.let { JsonUtils.fromPackageJson(it) }
|
||||
|
||||
+133
-124
@@ -23,11 +23,12 @@ class ReactExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val deps = getGradleDependenciesToApply(validJsonFile)
|
||||
assertThat(deps).isEmpty()
|
||||
@@ -38,23 +39,24 @@ class ReactExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react"
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val deps = getGradleDependenciesToApply(validJsonFile)
|
||||
assertThat(deps).containsExactly("implementation" to ":react-native_oss-library-example")
|
||||
@@ -65,24 +67,25 @@ class ReactExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react",
|
||||
"dependencyConfiguration": "compileOnly"
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react",
|
||||
"dependencyConfiguration": "compileOnly"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val deps = getGradleDependenciesToApply(validJsonFile)
|
||||
assertThat(deps).containsExactly("compileOnly" to ":react-native_oss-library-example")
|
||||
@@ -93,30 +96,32 @@ class ReactExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react",
|
||||
"buildTypes": ["debug", "release"]
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react",
|
||||
"buildTypes": ["debug", "release"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val deps = getGradleDependenciesToApply(validJsonFile)
|
||||
assertThat(deps)
|
||||
.containsExactly(
|
||||
"debugImplementation" to ":react-native_oss-library-example",
|
||||
"releaseImplementation" to ":react-native_oss-library-example")
|
||||
"releaseImplementation" to ":react-native_oss-library-example",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -124,39 +129,41 @@ class ReactExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react"
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@react-native/another-library-for-testing": {
|
||||
"root": "./node_modules/@react-native/another-library-for-testing",
|
||||
"name": "@react-native/another-library-for-testing",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@react-native/another-library-for-testing": {
|
||||
"root": "./node_modules/@react-native/another-library-for-testing",
|
||||
"name": "@react-native/another-library-for-testing",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val deps = getGradleDependenciesToApply(validJsonFile)
|
||||
assertThat(deps)
|
||||
.containsExactly(
|
||||
"implementation" to ":react-native_oss-library-example",
|
||||
"implementation" to ":react-native_another-library-for-testing")
|
||||
"implementation" to ":react-native_another-library-for-testing",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -164,26 +171,27 @@ class ReactExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/oss-library-example.podspec",
|
||||
"version": "0.0.0",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
},
|
||||
"android": null
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/oss-library-example.podspec",
|
||||
"version": "0.0.0",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
},
|
||||
"android": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val deps = getGradleDependenciesToApply(validJsonFile)
|
||||
assertThat(deps).isEmpty()
|
||||
@@ -194,34 +202,35 @@ class ReactExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/android-example",
|
||||
"name": "@react-native/android-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react"
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/android-example",
|
||||
"name": "@react-native/android-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@react-native/another-library-for-testing": {
|
||||
"root": "./node_modules/@react-native/cxx-testing",
|
||||
"name": "@react-native/cxx-testing",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react",
|
||||
"isPureCxxDependency": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@react-native/another-library-for-testing": {
|
||||
"root": "./node_modules/@react-native/cxx-testing",
|
||||
"name": "@react-native/cxx-testing",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react",
|
||||
"isPureCxxDependency": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val deps = getGradleDependenciesToApply(validJsonFile)
|
||||
assertThat(deps).containsExactly("implementation" to ":react-native_android-example")
|
||||
|
||||
+6
-2
@@ -37,8 +37,12 @@ class ModelAutolinkingDependenciesJsonTest {
|
||||
.isEqualTo("react-native_package")
|
||||
assertThat(
|
||||
ModelAutolinkingDependenciesJson(
|
||||
"", "@this*is~a(more)complicated/example!of~weird)packages", null)
|
||||
.nameCleansed)
|
||||
"",
|
||||
"@this*is~a(more)complicated/example!of~weird)packages",
|
||||
null,
|
||||
)
|
||||
.nameCleansed
|
||||
)
|
||||
.isEqualTo("this_is_a_more_complicated_example_of_weird_packages")
|
||||
}
|
||||
}
|
||||
|
||||
+19
-8
@@ -47,7 +47,8 @@ class BundleHermesCTaskTest {
|
||||
File(rootDir, "file.js"),
|
||||
File(rootDir, "file.jsx"),
|
||||
File(rootDir, "file.ts"),
|
||||
File(rootDir, "file.tsx"))
|
||||
File(rootDir, "file.tsx"),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,7 +72,11 @@ class BundleHermesCTaskTest {
|
||||
|
||||
assertThat(task.sources.excludes)
|
||||
.containsExactlyInAnyOrder(
|
||||
"**/android/**/*", "**/ios/**/*", "**/build/**/*", "**/node_modules/**/*")
|
||||
"**/android/**/*",
|
||||
"**/ios/**/*",
|
||||
"**/build/**/*",
|
||||
"**/node_modules/**/*",
|
||||
)
|
||||
assertThat(task.sources.files.size).isEqualTo(1)
|
||||
assertThat(task.sources.files).containsExactly(File(rootDir, "afolder/includedfile.js"))
|
||||
}
|
||||
@@ -236,7 +241,8 @@ class BundleHermesCTaskTest {
|
||||
"--minify",
|
||||
"true",
|
||||
"--read-global-cache",
|
||||
"--verbose")
|
||||
"--verbose",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -291,7 +297,8 @@ class BundleHermesCTaskTest {
|
||||
"--minify",
|
||||
"true",
|
||||
"--read-global-cache",
|
||||
"--verbose")
|
||||
"--verbose",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -341,7 +348,8 @@ class BundleHermesCTaskTest {
|
||||
"-out",
|
||||
bytecodeFile.absolutePath,
|
||||
bundleFile.absolutePath,
|
||||
"my-custom-hermes-flag")
|
||||
"my-custom-hermes-flag",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -369,7 +377,8 @@ class BundleHermesCTaskTest {
|
||||
"-out",
|
||||
bytecodeFile.relativeTo(tempFolder.root).path,
|
||||
bundleFile.relativeTo(tempFolder.root).path,
|
||||
"my-custom-hermes-flag")
|
||||
"my-custom-hermes-flag",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -397,7 +406,8 @@ class BundleHermesCTaskTest {
|
||||
packagerMap.absolutePath,
|
||||
compilerMap.absolutePath,
|
||||
"-o",
|
||||
outputMap.absolutePath)
|
||||
outputMap.absolutePath,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -428,6 +438,7 @@ class BundleHermesCTaskTest {
|
||||
packagerMap.relativeTo(tempFolder.root).path,
|
||||
compilerMap.relativeTo(tempFolder.root).path,
|
||||
"-o",
|
||||
outputMap.relativeTo(tempFolder.root).path)
|
||||
outputMap.relativeTo(tempFolder.root).path,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+22
-9
@@ -71,8 +71,12 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
root = "./a/directory",
|
||||
name = "a-dependency",
|
||||
platforms =
|
||||
ModelAutolinkingDependenciesPlatformJson(android = null))),
|
||||
project = null))
|
||||
ModelAutolinkingDependenciesPlatformJson(android = null),
|
||||
)
|
||||
),
|
||||
project = null,
|
||||
)
|
||||
)
|
||||
assertThat(result).isEmpty()
|
||||
}
|
||||
|
||||
@@ -98,8 +102,12 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
root = "./a/directory",
|
||||
name = "a-dependency",
|
||||
platforms =
|
||||
ModelAutolinkingDependenciesPlatformJson(android = android))),
|
||||
project = null))
|
||||
ModelAutolinkingDependenciesPlatformJson(android = android),
|
||||
)
|
||||
),
|
||||
project = null,
|
||||
)
|
||||
)
|
||||
assertThat(result).containsExactly(android)
|
||||
}
|
||||
|
||||
@@ -126,7 +134,8 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
|
||||
)
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -156,7 +165,8 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
another_cxxModule
|
||||
)
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -200,7 +210,8 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -256,7 +267,8 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -299,5 +311,6 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
cxxModuleCMakeListsPath = "./another/directory/cxx/CMakeLists.txt",
|
||||
cxxModuleHeaderName = "AnotherCxxModule",
|
||||
cxxModuleCMakeListsModuleName = "another_cxxModule",
|
||||
))
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
+4
-2
@@ -148,7 +148,8 @@ class GenerateCodegenArtifactsTaskTest {
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val task =
|
||||
@@ -177,7 +178,8 @@ class GenerateCodegenArtifactsTaskTest {
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val task =
|
||||
|
||||
+2
-1
@@ -86,6 +86,7 @@ class GenerateEntryPointTaskTest {
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+30
-12
@@ -64,7 +64,8 @@ class GeneratePackageListTaskTest {
|
||||
// @react-native/another-package
|
||||
import com.facebook.react.anotherPackage;
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -88,7 +89,8 @@ class GeneratePackageListTaskTest {
|
||||
new APackage(),
|
||||
new AnotherPackage()
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,8 +148,12 @@ class GeneratePackageListTaskTest {
|
||||
root = "./a/directory",
|
||||
name = "a-dependency",
|
||||
platforms =
|
||||
ModelAutolinkingDependenciesPlatformJson(android = null))),
|
||||
project = null))
|
||||
ModelAutolinkingDependenciesPlatformJson(android = null),
|
||||
)
|
||||
),
|
||||
project = null,
|
||||
)
|
||||
)
|
||||
assertThat(result)
|
||||
.isEqualTo(emptyMap<String, ModelAutolinkingDependenciesPlatformAndroidJson>())
|
||||
}
|
||||
@@ -174,8 +180,12 @@ class GeneratePackageListTaskTest {
|
||||
root = "./a/directory",
|
||||
name = "a-dependency",
|
||||
platforms =
|
||||
ModelAutolinkingDependenciesPlatformJson(android = android))),
|
||||
project = null))
|
||||
ModelAutolinkingDependenciesPlatformJson(android = android),
|
||||
)
|
||||
),
|
||||
project = null,
|
||||
)
|
||||
)
|
||||
assertThat(result.entries.size).isEqualTo(1)
|
||||
assertThat(result["a-dependency"]).isEqualTo(android)
|
||||
}
|
||||
@@ -189,7 +199,8 @@ class GeneratePackageListTaskTest {
|
||||
packageImportPath = "import com.facebook.react.aPackage;",
|
||||
packageInstance = "new APackage()",
|
||||
buildTypes = emptyList(),
|
||||
isPureCxxDependency = true)
|
||||
isPureCxxDependency = true,
|
||||
)
|
||||
|
||||
val result =
|
||||
task.filterAndroidPackages(
|
||||
@@ -202,8 +213,12 @@ class GeneratePackageListTaskTest {
|
||||
root = "./a/directory",
|
||||
name = "a-pure-cxx-dependency",
|
||||
platforms =
|
||||
ModelAutolinkingDependenciesPlatformJson(android = android))),
|
||||
project = null))
|
||||
ModelAutolinkingDependenciesPlatformJson(android = android),
|
||||
)
|
||||
),
|
||||
project = null,
|
||||
)
|
||||
)
|
||||
assertThat(result)
|
||||
.isEqualTo(emptyMap<String, ModelAutolinkingDependenciesPlatformAndroidJson>())
|
||||
}
|
||||
@@ -282,7 +297,8 @@ class GeneratePackageListTaskTest {
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -364,7 +380,8 @@ class GeneratePackageListTaskTest {
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private val testDependencies =
|
||||
@@ -388,5 +405,6 @@ class GeneratePackageListTaskTest {
|
||||
libraryName = "anotherPackage",
|
||||
componentDescriptors = emptyList(),
|
||||
cmakeListsPath = "./another/directory/CMakeLists.txt",
|
||||
))
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
+2
-1
@@ -26,7 +26,8 @@ class PrepareBoostTaskTest {
|
||||
assertThatThrownBy { task.taskAction() }
|
||||
.isInstanceOf(IllegalStateException::class.java)
|
||||
.hasMessage(
|
||||
"Cannot query the value of task ':PrepareBoostTask' property 'boostVersion' because it has no value available.")
|
||||
"Cannot query the value of task ':PrepareBoostTask' property 'boostVersion' because it has no value available."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+4
-2
@@ -125,7 +125,8 @@ typedef unsigned __int64 uint64;
|
||||
#endif
|
||||
|
||||
} // namespace GFLAGS_NAMESPACE
|
||||
""")
|
||||
"""
|
||||
)
|
||||
}
|
||||
File(gflagspath, "gflags-1.0.0/src/config.h.in").apply {
|
||||
parentFile.mkdirs()
|
||||
@@ -188,7 +189,8 @@ typedef unsigned __int64 uint64;
|
||||
#endif
|
||||
|
||||
} // namespace GFLAGS_NAMESPACE
|
||||
""")
|
||||
""",
|
||||
)
|
||||
|
||||
val configFile = File(output, "gflags/config.h")
|
||||
assertThat(configFile.exists()).isTrue()
|
||||
|
||||
+19
-8
@@ -55,7 +55,8 @@ class PreparePrefabHeadersTaskTest {
|
||||
createTestTask<PreparePrefabHeadersTask>(project = project) {
|
||||
it.outputDir.set(outputDir)
|
||||
it.input.set(
|
||||
listOf(PrefabPreprocessingEntry("sample_library", "input/" to expectedPrefix)))
|
||||
listOf(PrefabPreprocessingEntry("sample_library", "input/" to expectedPrefix))
|
||||
)
|
||||
}
|
||||
|
||||
task.taskAction()
|
||||
@@ -76,7 +77,8 @@ class PreparePrefabHeadersTaskTest {
|
||||
createTestTask<PreparePrefabHeadersTask>(project = project) {
|
||||
it.outputDir.set(outputDir)
|
||||
it.input.set(
|
||||
listOf(PrefabPreprocessingEntry("sample_library", "input/" to expectedPrefix)))
|
||||
listOf(PrefabPreprocessingEntry("sample_library", "input/" to expectedPrefix))
|
||||
)
|
||||
}
|
||||
|
||||
task.taskAction()
|
||||
@@ -100,8 +102,10 @@ class PreparePrefabHeadersTaskTest {
|
||||
listOf(
|
||||
PrefabPreprocessingEntry(
|
||||
"sample_library",
|
||||
listOf("input/component1/" to "", "input/component2/" to "")),
|
||||
))
|
||||
listOf("input/component1/" to "", "input/component2/" to ""),
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
task.taskAction()
|
||||
@@ -123,7 +127,9 @@ class PreparePrefabHeadersTaskTest {
|
||||
it.input.set(
|
||||
listOf(
|
||||
PrefabPreprocessingEntry("libraryone", "input/lib1/" to ""),
|
||||
PrefabPreprocessingEntry("librarytwo", "input/lib2/" to "")))
|
||||
PrefabPreprocessingEntry("librarytwo", "input/lib2/" to ""),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
task.taskAction()
|
||||
@@ -146,10 +152,15 @@ class PreparePrefabHeadersTaskTest {
|
||||
it.input.set(
|
||||
listOf(
|
||||
PrefabPreprocessingEntry(
|
||||
"libraryone", listOf("input/lib1/" to "", "input/shared/" to "shared/")),
|
||||
"libraryone",
|
||||
listOf("input/lib1/" to "", "input/shared/" to "shared/"),
|
||||
),
|
||||
PrefabPreprocessingEntry(
|
||||
"librarytwo", listOf("input/lib2/" to "", "input/shared/" to "shared/")),
|
||||
))
|
||||
"librarytwo",
|
||||
listOf("input/lib2/" to "", "input/shared/" to "shared/"),
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
task.taskAction()
|
||||
|
||||
+7
-5
@@ -7,7 +7,7 @@
|
||||
|
||||
package com.facebook.react.tasks.internal.utils
|
||||
|
||||
import groovy.test.GroovyTestCase.assertEquals
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
|
||||
class PrefabPreprocessingEntryTest {
|
||||
@@ -16,10 +16,12 @@ class PrefabPreprocessingEntryTest {
|
||||
fun secondaryConstructor_createsAList() {
|
||||
val sampleEntry =
|
||||
PrefabPreprocessingEntry(
|
||||
libraryName = "justALibrary", pathToPrefixCouple = "aPath" to "andAPrefix")
|
||||
libraryName = "justALibrary",
|
||||
pathToPrefixCouple = "aPath" to "andAPrefix",
|
||||
)
|
||||
|
||||
assertEquals(1, sampleEntry.pathToPrefixCouples.size)
|
||||
assertEquals("aPath", sampleEntry.pathToPrefixCouples[0].first)
|
||||
assertEquals("andAPrefix", sampleEntry.pathToPrefixCouples[0].second)
|
||||
assertThat(sampleEntry.pathToPrefixCouples.size).isEqualTo(1)
|
||||
assertThat(sampleEntry.pathToPrefixCouples[0].first).isEqualTo("aPath")
|
||||
assertThat(sampleEntry.pathToPrefixCouples[0].second).isEqualTo("andAPrefix")
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ internal fun createProject(projectDir: File? = null): Project {
|
||||
internal inline fun <reified T : Task> createTestTask(
|
||||
project: Project = createProject(),
|
||||
taskName: String = T::class.java.simpleName,
|
||||
crossinline block: (T) -> Unit = {}
|
||||
crossinline block: (T) -> Unit = {},
|
||||
): T = project.tasks.register(taskName, T::class.java) { block(it) }.get()
|
||||
|
||||
/** A util function to zip a list of files from [contents] inside the zipfile at [destination]. */
|
||||
|
||||
+4
-2
@@ -37,7 +37,8 @@ class AgpConfiguratorUtilsTest {
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
</manifest>
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val actual = getPackageNameFromManifest(manifest)
|
||||
@@ -55,7 +56,8 @@ class AgpConfiguratorUtilsTest {
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.facebook.react" >
|
||||
</manifest>
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val actual = getPackageNameFromManifest(manifest)
|
||||
|
||||
+55
-26
@@ -40,7 +40,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == localMavenURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
}
|
||||
|
||||
@@ -54,7 +55,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
}
|
||||
|
||||
@@ -68,7 +70,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
}
|
||||
|
||||
@@ -82,7 +85,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
}
|
||||
|
||||
@@ -96,7 +100,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
}
|
||||
|
||||
@@ -106,7 +111,9 @@ class DependencyUtilsTest {
|
||||
|
||||
val project = createProject()
|
||||
project.rootProject.extensions.extraProperties.set(
|
||||
"exclusiveEnterpriseRepository", repositoryURI.toString())
|
||||
"exclusiveEnterpriseRepository",
|
||||
repositoryURI.toString(),
|
||||
)
|
||||
|
||||
configureRepositories(project)
|
||||
|
||||
@@ -114,7 +121,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
}
|
||||
|
||||
@@ -129,7 +137,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNull()
|
||||
|
||||
// We test both with scoped and unscoped property
|
||||
@@ -141,7 +150,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNull()
|
||||
}
|
||||
|
||||
@@ -156,7 +166,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
|
||||
// We test both with scoped and unscoped property
|
||||
@@ -168,7 +179,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
project.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
}
|
||||
|
||||
@@ -224,12 +236,14 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
appProject.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
assertThat(
|
||||
libProject.repositories.firstOrNull {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isNotNull()
|
||||
}
|
||||
|
||||
@@ -252,7 +266,8 @@ class DependencyUtilsTest {
|
||||
assertThat(
|
||||
libProject.repositories.count {
|
||||
it is MavenArtifactRepository && it.url == repositoryURI
|
||||
})
|
||||
}
|
||||
)
|
||||
.isEqualTo(2)
|
||||
}
|
||||
|
||||
@@ -330,13 +345,15 @@ class DependencyUtilsTest {
|
||||
assertThat("com.facebook.react:react-android:0.42.0")
|
||||
.isEqualTo(dependencySubstitutions[0].second)
|
||||
assertThat(
|
||||
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
|
||||
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210."
|
||||
)
|
||||
.isEqualTo(dependencySubstitutions[0].third)
|
||||
assertThat("com.facebook.react:hermes-engine").isEqualTo(dependencySubstitutions[1].first)
|
||||
assertThat("com.facebook.react:hermes-android:0.42.0")
|
||||
.isEqualTo(dependencySubstitutions[1].second)
|
||||
assertThat(
|
||||
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
|
||||
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210."
|
||||
)
|
||||
.isEqualTo(dependencySubstitutions[1].third)
|
||||
}
|
||||
|
||||
@@ -347,12 +364,14 @@ class DependencyUtilsTest {
|
||||
assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first)
|
||||
assertThat("io.github.test:react-android:0.42.0").isEqualTo(dependencySubstitutions[0].second)
|
||||
assertThat(
|
||||
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
|
||||
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210."
|
||||
)
|
||||
.isEqualTo(dependencySubstitutions[0].third)
|
||||
assertThat("com.facebook.react:hermes-engine").isEqualTo(dependencySubstitutions[1].first)
|
||||
assertThat("io.github.test:hermes-android:0.42.0").isEqualTo(dependencySubstitutions[1].second)
|
||||
assertThat(
|
||||
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
|
||||
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210."
|
||||
)
|
||||
.isEqualTo(dependencySubstitutions[1].third)
|
||||
assertThat("com.facebook.react:react-android").isEqualTo(dependencySubstitutions[2].first)
|
||||
assertThat("io.github.test:react-android:0.42.0").isEqualTo(dependencySubstitutions[2].second)
|
||||
@@ -373,7 +392,8 @@ class DependencyUtilsTest {
|
||||
VERSION_NAME=1000.0.0
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val versionString = readVersionAndGroupStrings(propertiesFile).first
|
||||
@@ -390,7 +410,8 @@ class DependencyUtilsTest {
|
||||
VERSION_NAME=0.0.0-20221101-2019-cfe811ab1
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val versionString = readVersionAndGroupStrings(propertiesFile).first
|
||||
@@ -406,7 +427,8 @@ class DependencyUtilsTest {
|
||||
"""
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val versionString = readVersionAndGroupStrings(propertiesFile).first
|
||||
@@ -422,7 +444,8 @@ class DependencyUtilsTest {
|
||||
VERSION_NAME=
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val versionString = readVersionAndGroupStrings(propertiesFile).first
|
||||
@@ -438,7 +461,8 @@ class DependencyUtilsTest {
|
||||
react.internal.publishingGroup=io.github.test
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val groupString = readVersionAndGroupStrings(propertiesFile).second
|
||||
@@ -454,7 +478,8 @@ class DependencyUtilsTest {
|
||||
"""
|
||||
ANOTHER_PROPERTY=true
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val groupString = readVersionAndGroupStrings(propertiesFile).second
|
||||
@@ -503,7 +528,9 @@ class DependencyUtilsTest {
|
||||
fun exclusiveEnterpriseRepository_withScopedProperty() {
|
||||
val project = createProject(tempFolder.root)
|
||||
project.extensions.extraProperties.set(
|
||||
"react.exclusiveEnterpriseRepository", "https://maven.myfabolousorganization.it")
|
||||
"react.exclusiveEnterpriseRepository",
|
||||
"https://maven.myfabolousorganization.it",
|
||||
)
|
||||
assertThat(project.exclusiveEnterpriseRepository())
|
||||
.isEqualTo("https://maven.myfabolousorganization.it")
|
||||
}
|
||||
@@ -512,7 +539,9 @@ class DependencyUtilsTest {
|
||||
fun exclusiveEnterpriseRepository_withUnscopedProperty() {
|
||||
val project = createProject(tempFolder.root)
|
||||
project.extensions.extraProperties.set(
|
||||
"exclusiveEnterpriseRepository", "https://maven.myfabolousorganization.it")
|
||||
"exclusiveEnterpriseRepository",
|
||||
"https://maven.myfabolousorganization.it",
|
||||
)
|
||||
assertThat(project.exclusiveEnterpriseRepository())
|
||||
.isEqualTo("https://maven.myfabolousorganization.it")
|
||||
}
|
||||
|
||||
+12
-5
@@ -147,7 +147,8 @@ class PathUtilsTest {
|
||||
tempFolder.newFolder("node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/")
|
||||
val expected =
|
||||
tempFolder.newFile(
|
||||
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc")
|
||||
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc"
|
||||
)
|
||||
|
||||
assertThat(detectOSAwareHermesCommand(tempFolder.root, "")).isEqualTo(expected.toString())
|
||||
}
|
||||
@@ -189,7 +190,8 @@ class PathUtilsTest {
|
||||
tempFolder.newFolder("node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/")
|
||||
val expected =
|
||||
tempFolder.newFile(
|
||||
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc")
|
||||
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc"
|
||||
)
|
||||
tempFolder.newFolder("node_modules/react-native/sdks/hermesc/osx-bin/")
|
||||
tempFolder.newFile("node_modules/react-native/sdks/hermesc/osx-bin/hermesc")
|
||||
|
||||
@@ -202,7 +204,9 @@ class PathUtilsTest {
|
||||
.isEqualTo(
|
||||
File(
|
||||
tempFolder.root,
|
||||
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc"))
|
||||
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc",
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -212,7 +216,9 @@ class PathUtilsTest {
|
||||
.isEqualTo(
|
||||
File(
|
||||
tempFolder.root,
|
||||
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc.exe"))
|
||||
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc.exe",
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -309,7 +315,8 @@ class PathUtilsTest {
|
||||
"codegenConfig": {}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
val project = ProjectBuilder.builder().withProjectDir(moduleFolder).build()
|
||||
project.plugins.apply("com.android.library")
|
||||
|
||||
+7
-3
@@ -128,7 +128,8 @@ class ProjectUtilsTest {
|
||||
"codegenConfig": {}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
extension.root.set(tempFolder.root)
|
||||
assertThat(project.needsCodegenFromPackageJson(extension.root)).isTrue()
|
||||
@@ -146,7 +147,8 @@ class ProjectUtilsTest {
|
||||
"name": "a-library"
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
extension.root.set(tempFolder.root)
|
||||
assertThat(project.needsCodegenFromPackageJson(extension.root)).isFalse()
|
||||
@@ -203,7 +205,9 @@ class ProjectUtilsTest {
|
||||
fun getReactNativeArchitectures_withMultipleArch_returnsList() {
|
||||
val project = createProject()
|
||||
project.extensions.extraProperties.set(
|
||||
"reactNativeArchitectures", "armeabi-v7a,arm64-v8a,x86,x86_64")
|
||||
"reactNativeArchitectures",
|
||||
"armeabi-v7a,arm64-v8a,x86,x86_64",
|
||||
)
|
||||
|
||||
val archs = project.getReactNativeArchitectures()
|
||||
assertThat(archs.size).isEqualTo(4)
|
||||
|
||||
@@ -58,7 +58,8 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
// See comment above on JDK 11 support
|
||||
jvmTarget.set(JvmTarget.JVM_11)
|
||||
allWarningsAsErrors.set(
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false)
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -51,7 +51,7 @@ abstract class ReactSettingsExtension @Inject constructor(val settings: Settings
|
||||
lockFiles: FileCollection =
|
||||
settings.layout.rootDirectory
|
||||
.dir("../")
|
||||
.files("yarn.lock", "package-lock.json", "package.json", "react-native.config.js")
|
||||
.files("yarn.lock", "package-lock.json", "package.json", "react-native.config.js"),
|
||||
) {
|
||||
outputFile.parentFile.mkdirs()
|
||||
|
||||
@@ -158,9 +158,8 @@ abstract class ReactSettingsExtension @Inject constructor(val settings: Settings
|
||||
logger.error(message)
|
||||
if (cacheJsonConfig.length() != 0L) {
|
||||
logger.error(
|
||||
cacheJsonConfig
|
||||
.readText()
|
||||
.substring(0, min(1024, cacheJsonConfig.length().toInt())))
|
||||
cacheJsonConfig.readText().substring(0, min(1024, cacheJsonConfig.length().toInt()))
|
||||
)
|
||||
}
|
||||
cacheJsonConfig.delete()
|
||||
throw GradleException(message)
|
||||
|
||||
+103
-93
@@ -29,11 +29,12 @@ class ReactSettingsExtensionTest {
|
||||
val validFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"value": "¯\\_(ツ)_/¯"
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
{
|
||||
"value": "¯\\_(ツ)_/¯"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
assertThat(computeSha256(validFile))
|
||||
.isEqualTo("838aa9a72a16fdd55b0d49b510a82e264a30f59333b5fdd97c7798a29146f6a8")
|
||||
}
|
||||
@@ -43,11 +44,12 @@ class ReactSettingsExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val map = getLibrariesToAutolink(validJsonFile)
|
||||
assertThat(map.keys).isEmpty()
|
||||
@@ -58,41 +60,42 @@ class ReactSettingsExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
|
||||
"version": "0.0.1",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
},
|
||||
"android": {
|
||||
"sourceDir": "./node_modules/@react-native/oss-library-example/android",
|
||||
"packageImportPath": "import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;",
|
||||
"packageInstance": "new OSSLibraryExamplePackage()",
|
||||
"buildTypes": ["staging", "debug", "release"],
|
||||
"libraryName": "OSSLibraryExampleSpec",
|
||||
"componentDescriptors": [
|
||||
"SampleNativeComponentComponentDescriptor"
|
||||
],
|
||||
"cmakeListsPath": "./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt",
|
||||
"cxxModuleCMakeListsModuleName": null,
|
||||
"cxxModuleCMakeListsPath": null,
|
||||
"cxxModuleHeaderName": null,
|
||||
"dependencyConfiguration": "implementation",
|
||||
"isPureCxxDependency": false
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
|
||||
"version": "0.0.1",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
},
|
||||
"android": {
|
||||
"sourceDir": "./node_modules/@react-native/oss-library-example/android",
|
||||
"packageImportPath": "import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;",
|
||||
"packageInstance": "new OSSLibraryExamplePackage()",
|
||||
"buildTypes": ["staging", "debug", "release"],
|
||||
"libraryName": "OSSLibraryExampleSpec",
|
||||
"componentDescriptors": [
|
||||
"SampleNativeComponentComponentDescriptor"
|
||||
],
|
||||
"cmakeListsPath": "./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt",
|
||||
"cxxModuleCMakeListsModuleName": null,
|
||||
"cxxModuleCMakeListsPath": null,
|
||||
"cxxModuleHeaderName": null,
|
||||
"dependencyConfiguration": "implementation",
|
||||
"isPureCxxDependency": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val map = getLibrariesToAutolink(validJsonFile)
|
||||
assertThat(map.keys).containsExactly(":react-native_oss-library-example")
|
||||
@@ -105,25 +108,26 @@ class ReactSettingsExtensionTest {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
|
||||
"version": "0.0.1",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
|
||||
"version": "0.0.1",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val map = getLibrariesToAutolink(validJsonFile)
|
||||
assertThat(map.keys).isEmpty()
|
||||
@@ -258,7 +262,8 @@ class ReactSettingsExtensionTest {
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
|
||||
val lockfileCollection = project.files("yarn.lock")
|
||||
@@ -311,7 +316,8 @@ class ReactSettingsExtensionTest {
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
tempFolder.newFile("yarn.lock").apply { writeText("I'm a lockfile") }
|
||||
val lockfileCollection = project.files("yarn.lock")
|
||||
@@ -356,9 +362,10 @@ class ReactSettingsExtensionTest {
|
||||
val invalidConfigFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{}
|
||||
"""
|
||||
.trimIndent())
|
||||
{}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
assertThat(ReactSettingsExtension.isCacheDirty(invalidConfigFile, buildFolder, lockfiles))
|
||||
.isTrue()
|
||||
@@ -377,11 +384,12 @@ class ReactSettingsExtensionTest {
|
||||
val invalidConfigFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
assertThat(ReactSettingsExtension.isCacheDirty(invalidConfigFile, buildFolder, lockfiles))
|
||||
.isTrue()
|
||||
@@ -400,12 +408,13 @@ class ReactSettingsExtensionTest {
|
||||
val invalidConfigFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
assertThat(ReactSettingsExtension.isCacheDirty(invalidConfigFile, buildFolder, lockfiles))
|
||||
.isTrue()
|
||||
@@ -424,25 +433,26 @@ class ReactSettingsExtensionTest {
|
||||
val invalidConfigFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
|
||||
"version": "0.0.1",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
|
||||
"version": "0.0.1",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
assertThat(ReactSettingsExtension.isCacheDirty(invalidConfigFile, buildFolder, lockfiles))
|
||||
.isTrue()
|
||||
|
||||
@@ -31,7 +31,8 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
// See comment above on JDK 11 support
|
||||
jvmTarget.set(JvmTarget.JVM_11)
|
||||
allWarningsAsErrors.set(
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false)
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -13,5 +13,5 @@ package com.facebook.react.tests
|
||||
enum class OS(val propertyName: String) {
|
||||
WIN("Windows"),
|
||||
MAC("MacOs"),
|
||||
LINUX("Linux")
|
||||
LINUX("Linux"),
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
// See comment above on JDK 11 support
|
||||
jvmTarget.set(JvmTarget.JVM_11)
|
||||
allWarningsAsErrors.set(
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false)
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -14,5 +14,5 @@ data class ModelAutolinkingAndroidProjectJson(
|
||||
val applicationId: String,
|
||||
val mainActivity: String,
|
||||
val watchModeCommandParams: List<String>?,
|
||||
val dependencyConfiguration: String?
|
||||
val dependencyConfiguration: String?,
|
||||
)
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ package com.facebook.react.model
|
||||
data class ModelAutolinkingDependenciesJson(
|
||||
val root: String,
|
||||
val name: String,
|
||||
val platforms: ModelAutolinkingDependenciesPlatformJson?
|
||||
val platforms: ModelAutolinkingDependenciesPlatformJson?,
|
||||
) {
|
||||
|
||||
val nameCleansed: String
|
||||
|
||||
+1
-1
@@ -19,5 +19,5 @@ data class ModelAutolinkingDependenciesPlatformAndroidJson(
|
||||
val cxxModuleCMakeListsPath: String? = null,
|
||||
val cxxModuleHeaderName: String? = null,
|
||||
val dependencyConfiguration: String? = null,
|
||||
val isPureCxxDependency: Boolean? = null
|
||||
val isPureCxxDependency: Boolean? = null,
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@ fun windowsAwareCommandLine(args: List<Any>): List<Any> =
|
||||
|
||||
fun windowsAwareBashCommandLine(
|
||||
vararg args: String,
|
||||
bashWindowsHome: String? = null
|
||||
bashWindowsHome: String? = null,
|
||||
): List<String> =
|
||||
if (Os.isWindows()) {
|
||||
listOf(bashWindowsHome ?: "bash", "-c") + args
|
||||
|
||||
+159
-139
@@ -39,20 +39,21 @@ class JsonUtilsTest {
|
||||
val oldJsonConfig =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"name": "yet another npm package",
|
||||
"codegenConfig": {
|
||||
"libraries": [
|
||||
{
|
||||
"name": "an awesome library",
|
||||
"jsSrcsDir": "../js/",
|
||||
"android": {}
|
||||
"name": "yet another npm package",
|
||||
"codegenConfig": {
|
||||
"libraries": [
|
||||
{
|
||||
"name": "an awesome library",
|
||||
"jsSrcsDir": "../js/",
|
||||
"android": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val parsed = JsonUtils.fromPackageJson(oldJsonConfig)!!
|
||||
|
||||
@@ -66,21 +67,22 @@ class JsonUtilsTest {
|
||||
val validJson =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"name": "yet another npm package",
|
||||
"codegenConfig": {
|
||||
"name": "an awesome library",
|
||||
"jsSrcsDir": "../js/",
|
||||
"android": {
|
||||
"javaPackageName": "com.awesome.library"
|
||||
},
|
||||
"ios": {
|
||||
"other ios only keys": "which are ignored during parsing"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
{
|
||||
"name": "yet another npm package",
|
||||
"codegenConfig": {
|
||||
"name": "an awesome library",
|
||||
"jsSrcsDir": "../js/",
|
||||
"android": {
|
||||
"javaPackageName": "com.awesome.library"
|
||||
},
|
||||
"ios": {
|
||||
"other ios only keys": "which are ignored during parsing"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val parsed = JsonUtils.fromPackageJson(validJson)!!
|
||||
|
||||
@@ -111,11 +113,12 @@ class JsonUtilsTest {
|
||||
val validJson =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"version": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
{
|
||||
"version": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val parsed = JsonUtils.fromPackageJson(validJson)!!
|
||||
|
||||
assertThat("1000.0.0").isEqualTo(parsed.version)
|
||||
@@ -133,11 +136,12 @@ class JsonUtilsTest {
|
||||
val validJson =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0"
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
|
||||
|
||||
assertThat("1000.0.0").isEqualTo(parsed.reactNativeVersion)
|
||||
@@ -148,32 +152,33 @@ class JsonUtilsTest {
|
||||
val validJson =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"project": {
|
||||
"ios": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"xcodeProject": {
|
||||
"name": "RNTesterPods.xcworkspace",
|
||||
"isWorkspace": true
|
||||
},
|
||||
"automaticPodsInstallation": false
|
||||
},
|
||||
"android": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"appName": "RN-Tester",
|
||||
"packageName": "com.facebook.react.uiapp",
|
||||
"applicationId": "com.facebook.react.uiapp",
|
||||
"mainActivity": ".RNTesterActivity",
|
||||
"watchModeCommandParams": [
|
||||
"--mode HermesDebug"
|
||||
],
|
||||
"dependencyConfiguration": "implementation"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"project": {
|
||||
"ios": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"xcodeProject": {
|
||||
"name": "RNTesterPods.xcworkspace",
|
||||
"isWorkspace": true
|
||||
},
|
||||
"automaticPodsInstallation": false
|
||||
},
|
||||
"android": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"appName": "RN-Tester",
|
||||
"packageName": "com.facebook.react.uiapp",
|
||||
"applicationId": "com.facebook.react.uiapp",
|
||||
"mainActivity": ".RNTesterActivity",
|
||||
"watchModeCommandParams": [
|
||||
"--mode HermesDebug"
|
||||
],
|
||||
"dependencyConfiguration": "implementation"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
|
||||
|
||||
assertThat("./packages/rn-tester").isEqualTo(parsed.project!!.android!!.sourceDir)
|
||||
@@ -192,36 +197,37 @@ class JsonUtilsTest {
|
||||
val validJson =
|
||||
createJsonFile(
|
||||
"""
|
||||
|
||||
> AwesomeProject@0.0.1 npx
|
||||
> rnc-cli config
|
||||
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"project": {
|
||||
"ios": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"xcodeProject": {
|
||||
"name": "RNTesterPods.xcworkspace",
|
||||
"isWorkspace": true
|
||||
},
|
||||
"automaticPodsInstallation": false
|
||||
},
|
||||
"android": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"appName": "RN-Tester",
|
||||
"packageName": "com.facebook.react.uiapp",
|
||||
"applicationId": "com.facebook.react.uiapp",
|
||||
"mainActivity": ".RNTesterActivity",
|
||||
"watchModeCommandParams": [
|
||||
"--mode HermesDebug"
|
||||
],
|
||||
"dependencyConfiguration": "implementation"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
|
||||
> AwesomeProject@0.0.1 npx
|
||||
> rnc-cli config
|
||||
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"project": {
|
||||
"ios": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"xcodeProject": {
|
||||
"name": "RNTesterPods.xcworkspace",
|
||||
"isWorkspace": true
|
||||
},
|
||||
"automaticPodsInstallation": false
|
||||
},
|
||||
"android": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"appName": "RN-Tester",
|
||||
"packageName": "com.facebook.react.uiapp",
|
||||
"applicationId": "com.facebook.react.uiapp",
|
||||
"mainActivity": ".RNTesterActivity",
|
||||
"watchModeCommandParams": [
|
||||
"--mode HermesDebug"
|
||||
],
|
||||
"dependencyConfiguration": "implementation"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
|
||||
|
||||
assertThat("./packages/rn-tester").isEqualTo(parsed.project!!.android!!.sourceDir)
|
||||
@@ -239,41 +245,42 @@ class JsonUtilsTest {
|
||||
val validJson =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
|
||||
"version": "0.0.1",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
},
|
||||
"android": {
|
||||
"sourceDir": "./node_modules/@react-native/oss-library-example/android",
|
||||
"packageImportPath": "import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;",
|
||||
"packageInstance": "new OSSLibraryExamplePackage()",
|
||||
"buildTypes": ["staging", "debug", "release"],
|
||||
"libraryName": "OSSLibraryExampleSpec",
|
||||
"componentDescriptors": [
|
||||
"SampleNativeComponentComponentDescriptor"
|
||||
],
|
||||
"cmakeListsPath": "./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt",
|
||||
"cxxModuleCMakeListsModuleName": null,
|
||||
"cxxModuleCMakeListsPath": null,
|
||||
"cxxModuleHeaderName": null,
|
||||
"dependencyConfiguration": "implementation",
|
||||
"isPureCxxDependency": false
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/oss-library-example",
|
||||
"name": "@react-native/oss-library-example",
|
||||
"platforms": {
|
||||
"ios": {
|
||||
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
|
||||
"version": "0.0.1",
|
||||
"configurations": [],
|
||||
"scriptPhases": []
|
||||
},
|
||||
"android": {
|
||||
"sourceDir": "./node_modules/@react-native/oss-library-example/android",
|
||||
"packageImportPath": "import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;",
|
||||
"packageInstance": "new OSSLibraryExamplePackage()",
|
||||
"buildTypes": ["staging", "debug", "release"],
|
||||
"libraryName": "OSSLibraryExampleSpec",
|
||||
"componentDescriptors": [
|
||||
"SampleNativeComponentComponentDescriptor"
|
||||
],
|
||||
"cmakeListsPath": "./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt",
|
||||
"cxxModuleCMakeListsModuleName": null,
|
||||
"cxxModuleCMakeListsPath": null,
|
||||
"cxxModuleHeaderName": null,
|
||||
"dependencyConfiguration": "implementation",
|
||||
"isPureCxxDependency": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
|
||||
|
||||
assertThat("./node_modules/@react-native/oss-library-example")
|
||||
@@ -287,73 +294,86 @@ class JsonUtilsTest {
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.sourceDir)
|
||||
.sourceDir
|
||||
)
|
||||
assertThat("import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;")
|
||||
.isEqualTo(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.packageImportPath)
|
||||
.packageImportPath
|
||||
)
|
||||
assertThat("new OSSLibraryExamplePackage()")
|
||||
.isEqualTo(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.packageInstance)
|
||||
.packageInstance
|
||||
)
|
||||
assertThat(listOf("staging", "debug", "release"))
|
||||
.isEqualTo(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.buildTypes)
|
||||
.buildTypes
|
||||
)
|
||||
assertThat("OSSLibraryExampleSpec")
|
||||
.isEqualTo(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.libraryName)
|
||||
.libraryName
|
||||
)
|
||||
assertThat(listOf("SampleNativeComponentComponentDescriptor"))
|
||||
.isEqualTo(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.componentDescriptors)
|
||||
.componentDescriptors
|
||||
)
|
||||
assertThat(
|
||||
"./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt")
|
||||
"./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt"
|
||||
)
|
||||
.isEqualTo(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.cmakeListsPath)
|
||||
.cmakeListsPath
|
||||
)
|
||||
assertThat(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.cxxModuleHeaderName)
|
||||
.cxxModuleHeaderName
|
||||
)
|
||||
.isNull()
|
||||
assertThat(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.cxxModuleCMakeListsPath)
|
||||
.cxxModuleCMakeListsPath
|
||||
)
|
||||
.isNull()
|
||||
assertThat(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.cxxModuleCMakeListsModuleName)
|
||||
.cxxModuleCMakeListsModuleName
|
||||
)
|
||||
.isNull()
|
||||
assertThat("implementation")
|
||||
.isEqualTo(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.dependencyConfiguration)
|
||||
.dependencyConfiguration
|
||||
)
|
||||
assertThat(
|
||||
parsed.dependencies!!["@react-native/oss-library-example"]!!
|
||||
.platforms!!
|
||||
.android!!
|
||||
.isPureCxxDependency!!)
|
||||
.isPureCxxDependency!!
|
||||
)
|
||||
.isFalse()
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ describe('console.timeStamp()', () => {
|
||||
});
|
||||
|
||||
it("doesn't throw when invalid arguments are specified", () => {
|
||||
// $FlowExpectedError[incompatible-call]
|
||||
// $FlowExpectedError[incompatible-type]
|
||||
expect(() => console.timeStamp({})).not.toThrow();
|
||||
expect(() =>
|
||||
// $FlowExpectedError[incompatible-call]
|
||||
// $FlowExpectedError[incompatible-type]
|
||||
console.timeStamp('label', true, null, {}, [], () => {}),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
@@ -63,7 +63,7 @@ const ErrorUtils = {
|
||||
): ?TOut {
|
||||
try {
|
||||
_inGuard++;
|
||||
/* $FlowFixMe[incompatible-call] : TODO T48204745 (1) apply(context,
|
||||
/* $FlowFixMe[incompatible-type] : TODO T48204745 (1) apply(context,
|
||||
* null) is fine. (2) array -> rest array should work */
|
||||
/* $FlowFixMe[incompatible-type] : TODO T48204745 (1) apply(context,
|
||||
* null) is fine. (2) array -> rest array should work */
|
||||
@@ -81,7 +81,7 @@ const ErrorUtils = {
|
||||
args?: ?TArgs,
|
||||
): ?TOut {
|
||||
if (ErrorUtils.inGuard()) {
|
||||
/* $FlowFixMe[incompatible-call] : TODO T48204745 (1) apply(context,
|
||||
/* $FlowFixMe[incompatible-type] : TODO T48204745 (1) apply(context,
|
||||
* null) is fine. (2) array -> rest array should work */
|
||||
/* $FlowFixMe[incompatible-type] : TODO T48204745 (1) apply(context,
|
||||
* null) is fine. (2) array -> rest array should work */
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"@babel/plugin-transform-unicode-regex": "^7.24.7",
|
||||
"@babel/template": "^7.25.0",
|
||||
"@react-native/babel-plugin-codegen": "0.82.0-main",
|
||||
"babel-plugin-syntax-hermes-parser": "0.30.0",
|
||||
"babel-plugin-syntax-hermes-parser": "0.32.0",
|
||||
"babel-plugin-transform-flow-enums": "^0.0.2",
|
||||
"react-refresh": "^0.14.0"
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@react-native/babel-preset": "0.82.0-main",
|
||||
"hermes-parser": "0.30.0",
|
||||
"hermes-parser": "0.32.0",
|
||||
"nullthrows": "^1.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -41,7 +41,7 @@ it('exposes the correct absolute path to a source file to plugins', () => {
|
||||
enableBabelRCLookup: false,
|
||||
globalPrefix: '__metro__',
|
||||
hot: false,
|
||||
// $FlowFixMe[incompatible-call] TODO: Remove when `inlineRequires` has been removed from metro-babel-transformer in OSS
|
||||
// $FlowFixMe[incompatible-type] TODO: Remove when `inlineRequires` has been removed from metro-babel-transformer in OSS
|
||||
inlineRequires: true,
|
||||
minify: false,
|
||||
platform: null,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user