mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add function to set build from source to true (#53674)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53674 ## Context When configuring an app to build with SwiftPM from source, there is a sequence of operations we need to run in order to prepare the project correctly. ## Changed Add a function updates the PAckage.swift file to set BUILD_FROM_SOURCE to true ## Changelog: [Internal] - Reviewed By: cortinico Differential Revision: D81778460 fbshipit-source-id: b06ebc546aa8e87acdb15706a0559e9046173784
This commit is contained in:
committed by
meta-codesync[bot]
parent
87d6043788
commit
d45523639d
@@ -15,6 +15,7 @@ const {
|
||||
findXcodeProjectDirectory,
|
||||
runIosPrebuild,
|
||||
runPodDeintegrate,
|
||||
setBuildFromSource,
|
||||
} = require('../prepare-app-utils');
|
||||
|
||||
// Mock child_process module
|
||||
@@ -189,6 +190,237 @@ describe('findXcodeProjectDirectory', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setBuildFromSource', () => {
|
||||
let mockFs;
|
||||
let mockPath;
|
||||
let mockConsoleLog;
|
||||
let mockConsoleWarn;
|
||||
|
||||
beforeEach(() => {
|
||||
// Setup mocks
|
||||
mockFs = require('fs');
|
||||
mockPath = require('path');
|
||||
mockConsoleLog = console.log;
|
||||
mockConsoleWarn = console.warn;
|
||||
|
||||
// Clear and reset all mocks completely
|
||||
jest.clearAllMocks();
|
||||
jest.resetAllMocks();
|
||||
|
||||
// Set up fresh mock implementations
|
||||
mockFs.existsSync = jest.fn();
|
||||
mockFs.readFileSync = jest.fn();
|
||||
mockFs.writeFileSync = jest.fn();
|
||||
|
||||
// Mock path.join to return realistic paths
|
||||
mockPath.join.mockImplementation((...args) => args.join('/'));
|
||||
});
|
||||
|
||||
it('should update BUILD_FROM_SOURCE from false to true successfully', async () => {
|
||||
// Setup
|
||||
const reactNativePath = '/path/to/react-native';
|
||||
const mockPackageSwiftContent = `
|
||||
// Package.swift
|
||||
import PackageDescription
|
||||
|
||||
let BUILD_FROM_SOURCE = false
|
||||
|
||||
let package = Package(
|
||||
name: "ReactNative",
|
||||
platforms: [.iOS(.v13)],
|
||||
// rest of package
|
||||
)
|
||||
`;
|
||||
|
||||
const expectedUpdatedContent = `
|
||||
// Package.swift
|
||||
import PackageDescription
|
||||
|
||||
let BUILD_FROM_SOURCE = true
|
||||
|
||||
let package = Package(
|
||||
name: "ReactNative",
|
||||
platforms: [.iOS(.v13)],
|
||||
// rest of package
|
||||
)
|
||||
`;
|
||||
|
||||
mockFs.existsSync.mockReturnValue(true);
|
||||
mockFs.readFileSync.mockReturnValue(mockPackageSwiftContent);
|
||||
mockFs.writeFileSync.mockImplementation(() => {});
|
||||
|
||||
// Execute
|
||||
await setBuildFromSource(reactNativePath);
|
||||
|
||||
// Assert
|
||||
expect(mockFs.existsSync).toHaveBeenCalledWith(
|
||||
'/path/to/react-native/Package.swift',
|
||||
);
|
||||
expect(mockFs.readFileSync).toHaveBeenCalledWith(
|
||||
'/path/to/react-native/Package.swift',
|
||||
'utf8',
|
||||
);
|
||||
expect(mockFs.writeFileSync).toHaveBeenCalledWith(
|
||||
'/path/to/react-native/Package.swift',
|
||||
expectedUpdatedContent,
|
||||
'utf8',
|
||||
);
|
||||
expect(mockConsoleLog).toHaveBeenCalledWith(
|
||||
'Updating BUILD_FROM_SOURCE in: /path/to/react-native/Package.swift',
|
||||
);
|
||||
expect(mockConsoleLog).toHaveBeenCalledWith(
|
||||
'✓ BUILD_FROM_SOURCE set to true in Package.swift',
|
||||
);
|
||||
expect(mockConsoleWarn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle when BUILD_FROM_SOURCE is already true', async () => {
|
||||
// Setup
|
||||
const reactNativePath = '/path/to/react-native';
|
||||
const mockPackageSwiftContent = `
|
||||
// Package.swift
|
||||
import PackageDescription
|
||||
|
||||
let BUILD_FROM_SOURCE = true
|
||||
|
||||
let package = Package(
|
||||
name: "ReactNative",
|
||||
platforms: [.iOS(.v13)],
|
||||
// rest of package
|
||||
)
|
||||
`;
|
||||
|
||||
mockFs.existsSync.mockReturnValue(true);
|
||||
mockFs.readFileSync.mockReturnValue(mockPackageSwiftContent);
|
||||
mockFs.writeFileSync.mockImplementation(() => {});
|
||||
|
||||
// Execute
|
||||
await setBuildFromSource(reactNativePath);
|
||||
|
||||
// Assert
|
||||
expect(mockFs.existsSync).toHaveBeenCalledWith(
|
||||
'/path/to/react-native/Package.swift',
|
||||
);
|
||||
expect(mockFs.readFileSync).toHaveBeenCalledWith(
|
||||
'/path/to/react-native/Package.swift',
|
||||
'utf8',
|
||||
);
|
||||
expect(mockFs.writeFileSync).not.toHaveBeenCalled(); // Should not write when already true
|
||||
expect(mockConsoleLog).toHaveBeenCalledWith(
|
||||
'Updating BUILD_FROM_SOURCE in: /path/to/react-native/Package.swift',
|
||||
);
|
||||
expect(mockConsoleLog).toHaveBeenCalledWith(
|
||||
'✓ BUILD_FROM_SOURCE is already set to true in Package.swift',
|
||||
);
|
||||
expect(mockConsoleWarn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should warn when BUILD_FROM_SOURCE declaration is not found', async () => {
|
||||
// Setup
|
||||
const reactNativePath = '/path/to/react-native';
|
||||
const mockPackageSwiftContent = `
|
||||
// Package.swift
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "ReactNative",
|
||||
platforms: [.iOS(.v13)],
|
||||
// rest of package without BUILD_FROM_SOURCE
|
||||
)
|
||||
`;
|
||||
|
||||
mockFs.existsSync.mockReturnValue(true);
|
||||
mockFs.readFileSync.mockReturnValue(mockPackageSwiftContent);
|
||||
mockFs.writeFileSync.mockImplementation(() => {});
|
||||
|
||||
// Execute
|
||||
await setBuildFromSource(reactNativePath);
|
||||
|
||||
// Assert
|
||||
expect(mockFs.existsSync).toHaveBeenCalledWith(
|
||||
'/path/to/react-native/Package.swift',
|
||||
);
|
||||
expect(mockFs.readFileSync).toHaveBeenCalledWith(
|
||||
'/path/to/react-native/Package.swift',
|
||||
'utf8',
|
||||
);
|
||||
expect(mockFs.writeFileSync).not.toHaveBeenCalled(); // Should not write when declaration not found
|
||||
expect(mockConsoleLog).toHaveBeenCalledWith(
|
||||
'Updating BUILD_FROM_SOURCE in: /path/to/react-native/Package.swift',
|
||||
);
|
||||
expect(mockConsoleWarn).toHaveBeenCalledWith(
|
||||
'⚠️ BUILD_FROM_SOURCE declaration not found in Package.swift',
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error when Package.swift does not exist', async () => {
|
||||
// Setup
|
||||
const reactNativePath = '/path/to/react-native';
|
||||
|
||||
mockFs.existsSync.mockReturnValue(false);
|
||||
|
||||
// Execute & Assert
|
||||
await expect(setBuildFromSource(reactNativePath)).rejects.toThrow(
|
||||
'Package.swift not found at: /path/to/react-native/Package.swift',
|
||||
);
|
||||
|
||||
expect(mockFs.existsSync).toHaveBeenCalledWith(
|
||||
'/path/to/react-native/Package.swift',
|
||||
);
|
||||
expect(mockFs.readFileSync).not.toHaveBeenCalled();
|
||||
expect(mockFs.writeFileSync).not.toHaveBeenCalled();
|
||||
expect(mockConsoleLog).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle multiple BUILD_FROM_SOURCE occurrences', async () => {
|
||||
// Setup
|
||||
const reactNativePath = '/path/to/react-native';
|
||||
const mockPackageSwiftContent = `
|
||||
// Package.swift
|
||||
import PackageDescription
|
||||
|
||||
let BUILD_FROM_SOURCE = false
|
||||
// Some comment about BUILD_FROM_SOURCE = false
|
||||
let anotherVar = "BUILD_FROM_SOURCE = false in string"
|
||||
|
||||
let package = Package(
|
||||
name: "ReactNative",
|
||||
platforms: [.iOS(.v13)],
|
||||
// Another BUILD_FROM_SOURCE = false comment
|
||||
)
|
||||
`;
|
||||
|
||||
const expectedUpdatedContent = `
|
||||
// Package.swift
|
||||
import PackageDescription
|
||||
|
||||
let BUILD_FROM_SOURCE = true
|
||||
// Some comment about BUILD_FROM_SOURCE = false
|
||||
let anotherVar = "BUILD_FROM_SOURCE = false in string"
|
||||
|
||||
let package = Package(
|
||||
name: "ReactNative",
|
||||
platforms: [.iOS(.v13)],
|
||||
// Another BUILD_FROM_SOURCE = false comment
|
||||
)
|
||||
`;
|
||||
|
||||
mockFs.existsSync.mockReturnValue(true);
|
||||
mockFs.readFileSync.mockReturnValue(mockPackageSwiftContent);
|
||||
mockFs.writeFileSync.mockImplementation(() => {});
|
||||
|
||||
// Execute
|
||||
await setBuildFromSource(reactNativePath);
|
||||
|
||||
// Assert - should replace only the declaration, not comments or strings
|
||||
expect(mockFs.writeFileSync).toHaveBeenCalledWith(
|
||||
'/path/to/react-native/Package.swift',
|
||||
expectedUpdatedContent,
|
||||
'utf8',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('runIosPrebuild', () => {
|
||||
let mockExecSync;
|
||||
let mockConsoleLog;
|
||||
|
||||
@@ -165,9 +165,51 @@ async function configureAppForSwift(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set BUILD_FROM_SOURCE to true in Package.swift
|
||||
*/
|
||||
async function setBuildFromSource(
|
||||
reactNativePath /*: string */,
|
||||
) /*: Promise<void> */ {
|
||||
const packageSwiftPath = path.join(reactNativePath, 'Package.swift');
|
||||
|
||||
if (!fs.existsSync(packageSwiftPath)) {
|
||||
throw new Error(`Package.swift not found at: ${packageSwiftPath}`);
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(`Updating BUILD_FROM_SOURCE in: ${packageSwiftPath}`);
|
||||
|
||||
const content = fs.readFileSync(packageSwiftPath, 'utf8');
|
||||
|
||||
// Check if BUILD_FROM_SOURCE = false exists and replace it with true
|
||||
if (content.includes('let BUILD_FROM_SOURCE = false')) {
|
||||
const updatedContent = content.replace(
|
||||
/let BUILD_FROM_SOURCE = false/g,
|
||||
'let BUILD_FROM_SOURCE = true',
|
||||
);
|
||||
fs.writeFileSync(packageSwiftPath, updatedContent, 'utf8');
|
||||
console.log('✓ BUILD_FROM_SOURCE set to true in Package.swift');
|
||||
} else if (content.includes('let BUILD_FROM_SOURCE = true')) {
|
||||
console.log(
|
||||
'✓ BUILD_FROM_SOURCE is already set to true in Package.swift',
|
||||
);
|
||||
} else {
|
||||
console.warn(
|
||||
'⚠️ BUILD_FROM_SOURCE declaration not found in Package.swift',
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to update BUILD_FROM_SOURCE in Package.swift: ${error.message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findXcodeProjectDirectory,
|
||||
runPodDeintegrate,
|
||||
runIosPrebuild,
|
||||
configureAppForSwift,
|
||||
setBuildFromSource,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user