1082815dcSEvan Baconimport fs from 'fs';
2082815dcSEvan Baconimport path from 'path';
3082815dcSEvan Bacon
4*8a424bebSJames Ideimport { addBuildSourceFileToGroup, getProjectName } from './utils/Xcodeproj';
5082815dcSEvan Baconimport { ConfigPlugin, XcodeProject } from '../Plugin.types';
6082815dcSEvan Baconimport { withXcodeProject } from '../plugins/ios-plugins';
7082815dcSEvan Bacon
8082815dcSEvan Bacon/**
9082815dcSEvan Bacon * Create a build source file and link it to Xcode.
10082815dcSEvan Bacon *
11082815dcSEvan Bacon * @param config
12082815dcSEvan Bacon * @param props.filePath relative to the build source folder. ex: `ViewController.swift` would be created in `ios/myapp/ViewController.swift`.
13082815dcSEvan Bacon * @param props.contents file contents to write.
14082815dcSEvan Bacon * @param props.overwrite should the contents overwrite any existing file in the same location on disk.
15082815dcSEvan Bacon * @returns
16082815dcSEvan Bacon */
17082815dcSEvan Baconexport const withBuildSourceFile: ConfigPlugin<{
18082815dcSEvan Bacon  filePath: string;
19082815dcSEvan Bacon  contents: string;
20082815dcSEvan Bacon  overwrite?: boolean;
21082815dcSEvan Bacon}> = (config, { filePath, contents, overwrite }) => {
22082815dcSEvan Bacon  return withXcodeProject(config, (config) => {
23082815dcSEvan Bacon    const projectName = getProjectName(config.modRequest.projectRoot);
24082815dcSEvan Bacon
25082815dcSEvan Bacon    config.modResults = createBuildSourceFile({
26082815dcSEvan Bacon      project: config.modResults,
27082815dcSEvan Bacon      nativeProjectRoot: config.modRequest.platformProjectRoot,
28082815dcSEvan Bacon      fileContents: contents,
29082815dcSEvan Bacon      filePath: path.join(projectName, filePath),
30082815dcSEvan Bacon      overwrite,
31082815dcSEvan Bacon    });
32082815dcSEvan Bacon    return config;
33082815dcSEvan Bacon  });
34082815dcSEvan Bacon};
35082815dcSEvan Bacon
36082815dcSEvan Bacon/**
37082815dcSEvan Bacon * Add a source file to the Xcode project and write it to the file system.
38082815dcSEvan Bacon *
39082815dcSEvan Bacon * @param nativeProjectRoot absolute path to the native app root `user/app/ios`
40082815dcSEvan Bacon * @param filePath path relative to the `nativeProjectRoot` for the file to create `user/app/ios/myapp/foobar.swift`
41082815dcSEvan Bacon * @param fileContents string file contents to write to the `filePath`
42082815dcSEvan Bacon * @param overwrite should write file even if one already exists
43082815dcSEvan Bacon */
44082815dcSEvan Baconexport function createBuildSourceFile({
45082815dcSEvan Bacon  project,
46082815dcSEvan Bacon  nativeProjectRoot,
47082815dcSEvan Bacon  filePath,
48082815dcSEvan Bacon  fileContents,
49082815dcSEvan Bacon  overwrite,
50082815dcSEvan Bacon}: {
51082815dcSEvan Bacon  project: XcodeProject;
52082815dcSEvan Bacon  nativeProjectRoot: string;
53082815dcSEvan Bacon  filePath: string;
54082815dcSEvan Bacon  fileContents: string;
55082815dcSEvan Bacon  overwrite?: boolean;
56082815dcSEvan Bacon}): XcodeProject {
57082815dcSEvan Bacon  const absoluteFilePath = path.join(nativeProjectRoot, filePath);
58082815dcSEvan Bacon  if (overwrite || !fs.existsSync(absoluteFilePath)) {
59082815dcSEvan Bacon    // Create the file
60082815dcSEvan Bacon    fs.writeFileSync(absoluteFilePath, fileContents, 'utf8');
61082815dcSEvan Bacon  }
62082815dcSEvan Bacon
63082815dcSEvan Bacon  // `myapp`
64082815dcSEvan Bacon  const groupName = path.dirname(filePath);
65082815dcSEvan Bacon
66082815dcSEvan Bacon  // Ensure the file is linked with Xcode resource files
67082815dcSEvan Bacon  if (!project.hasFile(filePath)) {
68082815dcSEvan Bacon    project = addBuildSourceFileToGroup({
69082815dcSEvan Bacon      filepath: filePath,
70082815dcSEvan Bacon      groupName,
71082815dcSEvan Bacon      project,
72082815dcSEvan Bacon    });
73082815dcSEvan Bacon  }
74082815dcSEvan Bacon  return project;
75082815dcSEvan Bacon}
76