Skip to content

Commit 23a65ef

Browse files
Copilotanupriya13
andcommitted
Fix module-windows-setup to use actual Windows project directory structure instead of codegen spec names
Co-authored-by: anupriya13 <[email protected]>
1 parent b0c3793 commit 23a65ef

File tree

1 file changed

+78
-15
lines changed

1 file changed

+78
-15
lines changed

packages/@react-native-windows/cli/src/commands/moduleWindowsSetup/moduleWindowsSetup.ts

Lines changed: 78 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ interface MethodSignature {
4343
export class ModuleWindowsSetup {
4444
private actualModuleName?: string;
4545
private discoveredSpecFiles: string[] = [];
46+
private actualProjectPath?: string;
4647
public root: string;
4748
public options: ModuleWindowsSetupOptions;
4849

@@ -138,6 +139,22 @@ export class ModuleWindowsSetup {
138139
}
139140
}
140141

142+
public getActualProjectPaths(): {headerPath: string, cppPath: string} {
143+
if (this.actualProjectPath) {
144+
return {
145+
headerPath: `${this.actualProjectPath}.h`,
146+
cppPath: `${this.actualProjectPath}.cpp`
147+
};
148+
}
149+
150+
// Fallback to getFinalModuleName for backward compatibility
151+
const moduleName = this.actualModuleName || 'SampleModule';
152+
return {
153+
headerPath: `windows/${moduleName}/${moduleName}.h`,
154+
cppPath: `windows/${moduleName}/${moduleName}.cpp`
155+
};
156+
}
157+
141158
private verboseMessage(message: any) {
142159
if (this.options.logging) {
143160
console.log(`[ModuleWindowsSetup] ${message}`);
@@ -837,18 +854,63 @@ export default TurboModuleRegistry.getEnforcing<Spec>('${moduleName}');
837854
this.verboseMessage(`Error reading codegen directory contents: ${error}`);
838855
}
839856

840-
for (const specFile of specFiles) {
841-
const specName = specFile.replace('Spec.g.h', '');
842-
const windowsDir = path.join(this.root, 'windows');
843-
const moduleDir = path.join(windowsDir, specName);
844-
const headerPath = path.join(moduleDir, `${specName}.h`);
845-
const cppPath = path.join(moduleDir, `${specName}.cpp`);
846-
847-
if (!(await fs.exists(moduleDir))) {
857+
// Find the actual Windows project directory created by init-windows
858+
const windowsDir = path.join(this.root, 'windows');
859+
const actualModuleName = await this.getFinalModuleName();
860+
861+
// Look for existing Windows project directory (created by init-windows)
862+
let moduleDir = path.join(windowsDir, actualModuleName);
863+
864+
// If the expected directory doesn't exist, find any existing project directory
865+
if (!(await fs.exists(moduleDir))) {
866+
this.verboseMessage(`Expected directory ${moduleDir} not found, searching for existing Windows project directory...`);
867+
868+
try {
869+
const windowsDirContents = await fs.readdir(windowsDir);
870+
const projectDirs = [];
871+
872+
for (const item of windowsDirContents) {
873+
const itemPath = path.join(windowsDir, item);
874+
const stats = await fs.stat(itemPath);
875+
876+
if (stats.isDirectory() && !item.startsWith('.') &&
877+
item !== 'ExperimentalFeatures.props' &&
878+
!item.endsWith('.sln')) {
879+
// Check if this directory contains typical project files
880+
const possibleHeaderFile = path.join(itemPath, `${item}.h`);
881+
const possibleCppFile = path.join(itemPath, `${item}.cpp`);
882+
if (await fs.exists(possibleHeaderFile) || await fs.exists(possibleCppFile)) {
883+
projectDirs.push(item);
884+
}
885+
}
886+
}
887+
888+
if (projectDirs.length > 0) {
889+
const existingProjectName = projectDirs[0];
890+
moduleDir = path.join(windowsDir, existingProjectName);
891+
this.verboseMessage(`Found existing Windows project directory: ${moduleDir}`);
892+
} else {
893+
this.verboseMessage(`No existing project directory found, creating: ${moduleDir}`);
894+
await fs.mkdir(moduleDir, {recursive: true});
895+
}
896+
} catch (error) {
897+
this.verboseMessage(`Error searching for Windows project directory: ${error}`);
848898
await fs.mkdir(moduleDir, {recursive: true});
849899
}
900+
}
901+
902+
// Use the project directory name for file names
903+
const projectName = path.basename(moduleDir);
904+
905+
// Store the actual project path for the success message
906+
this.actualProjectPath = path.join('windows', projectName, projectName);
907+
908+
for (const specFile of specFiles) {
909+
const headerPath = path.join(moduleDir, `${projectName}.h`);
910+
const cppPath = path.join(moduleDir, `${projectName}.cpp`);
850911

851912
// Parse method signatures from codegen files first, then fallback to TypeScript spec files
913+
const specName = specFile.replace('Spec.g.h', '');
852914
const methods = await this.parseSpecFileForMethods(specName, codegenDir);
853915

854916
if (methods.length === 0) {
@@ -861,16 +923,16 @@ export default TurboModuleRegistry.getEnforcing<Spec>('${moduleName}');
861923
);
862924
}
863925

864-
// Generate header file with parsed methods
865-
const headerContent = await this.generateHeaderStub(specName, methods);
926+
// Generate header file with parsed methods using the project name
927+
const headerContent = await this.generateHeaderStub(projectName, methods);
866928
// Always write the header file to ensure it has the correct methods from the spec
867929
await fs.writeFile(headerPath, headerContent);
868930
this.verboseMessage(
869931
`Generated header stub: ${headerPath} with ${methods.length} methods`,
870932
);
871933

872-
// Generate cpp file with parsed methods
873-
const cppContent = await this.generateCppStub(specName, methods);
934+
// Generate cpp file with parsed methods using the project name
935+
const cppContent = await this.generateCppStub(projectName, methods);
874936
// Always write the cpp file to ensure it has the correct methods from the spec
875937
await fs.writeFile(cppPath, cppContent);
876938
this.verboseMessage(
@@ -1683,8 +1745,9 @@ export async function moduleWindowsSetupInternal(
16831745
await setup.run(spinner, config);
16841746
const endTime = performance.now();
16851747

1686-
// Get the actual module name for display
1748+
// Get the actual module name and project paths for display
16871749
const moduleName = await setup.getFinalModuleName();
1750+
const projectPaths = setup.getActualProjectPaths();
16881751

16891752
console.log(
16901753
`${chalk.green('Success:')} Windows module setup completed! (${Math.round(
@@ -1702,10 +1765,10 @@ export async function moduleWindowsSetupInternal(
17021765
`🏗️ Native${moduleName}.ts - TurboModule spec file (edit with your API)`,
17031766
);
17041767
console.log(
1705-
`💻 windows/${moduleName}/${moduleName}.h - C++ header file (implement your methods here)`,
1768+
`💻 ${projectPaths.headerPath} - C++ header file (implement your methods here)`,
17061769
);
17071770
console.log(
1708-
`⚙️ windows/${moduleName}/${moduleName}.cpp - C++ implementation file (add your logic here)`,
1771+
`⚙️ ${projectPaths.cppPath} - C++ implementation file (add your logic here)`,
17091772
);
17101773
console.log('');
17111774
console.log(chalk.bold('Next steps:'));

0 commit comments

Comments
 (0)