import assert from 'assert' ; import fs from 'fs-extra' ; import { sync as globSync } from 'glob' ; import * as path from 'path' ; import { UnexpectedError } from '../utils/errors' ; import { directoryExistsAsync } from '../utils/modules' ; import { ResourceKind } from './Resources' ; export interface ProjectFile < L extends string = string > { path : string ; language : L ; contents : string ; } export type ApplicationProjectFile = ProjectFile < 'java' | 'kt' > ; export type GradleProjectFile = ProjectFile < 'groovy' | 'kt' > ; export function getProjectFilePath ( projectRoot , name ) { const filePath = globSync ( path . join ( projectRoot , `android/app/src/main/java/**/${ name }.@(java|kt)` ) ) [ 0 ] ; assert ( filePath , `Project file "${ name }" does not exist in android project for root "${ projectRoot }"` ) ; return filePath ; } function getLanguage ( filePath ) { const extension = path . extname ( filePath ) ; switch ( extension ) { case '.java' : return 'java' ; case '.kts' : case '.kt' : return 'kt' ; case '.groovy' : case '.gradle' : return 'groovy' ; default : throw new UnexpectedError ( `Unexpected Android file extension: ${ extension }` ) ; } } export function getFileInfo ( filePath ) { return { path : path . normalize ( filePath ) , contents : fs . readFileSync ( filePath , 'utf8' ) , language : getLanguage ( filePath ) as any } ; } export async function getMainApplicationAsync ( projectRoot ) { const filePath = getProjectFilePath ( projectRoot , 'MainApplication' ) ; return getFileInfo ( filePath ) ; } export async function getMainActivityAsync ( projectRoot ) { const filePath = getProjectFilePath ( projectRoot , 'MainActivity' ) ; return getFileInfo ( filePath ) ; } export function getGradleFilePath ( projectRoot , gradleName ) { const groovyPath = path . resolve ( projectRoot , `${ gradleName }.gradle` ) ; const ktPath = path . resolve ( projectRoot , `${ gradleName }.gradle.kts` ) ; const isGroovy = fs . pathExistsSync ( groovyPath ) ; const isKotlin = ! isGroovy && fs . pathExistsSync ( ktPath ) ; if ( ! isGroovy && ! isKotlin ) { throw new Error ( `Failed to find '${ gradleName }.gradle' file for project: ${ projectRoot }.` ) ; } const filePath = isGroovy ? groovyPath : ktPath ; return filePath ; } export function getProjectBuildGradleFilePath ( projectRoot ) { return getGradleFilePath ( path . join ( projectRoot , 'android' ) , 'build' ) ; } export async function getProjectBuildGradleAsync ( projectRoot ) { return getFileInfo ( getProjectBuildGradleFilePath ( projectRoot ) ) ; } export function getSettingsGradleFilePath ( projectRoot ) { return getGradleFilePath ( path . join ( projectRoot , 'android' ) , 'settings' ) ; } export async function getSettingsGradleAsync ( projectRoot ) { return getFileInfo ( getSettingsGradleFilePath ( projectRoot ) ) ; } export function getAppBuildGradleFilePath ( projectRoot ) { return getGradleFilePath ( path . join ( projectRoot , 'android' , 'app' ) , 'build' ) ; } export async function getAppBuildGradleAsync ( projectRoot ) { return getFileInfo ( getAppBuildGradleFilePath ( projectRoot ) ) ; } export async function getProjectPathOrThrowAsync ( projectRoot ) { const projectPath = path . join ( projectRoot , 'android' ) ; if ( await directoryExistsAsync ( projectPath ) ) { return projectPath ; } throw new Error ( `Android project folder is missing in project: ${ projectRoot }` ) ; } export async function getAndroidManifestAsync ( projectRoot ) { const projectPath = await getProjectPathOrThrowAsync ( projectRoot ) ; const filePath = path . join ( projectPath , 'app/src/main/AndroidManifest.xml' ) ; return filePath ; } export async function getResourceFolderAsync ( projectRoot ) { const projectPath = await getProjectPathOrThrowAsync ( projectRoot ) ; return path . join ( projectPath , `app/src/main/res` ) ; } export async function getResourceXMLPathAsync ( projectRoot , { kind = 'values' , name } ) { const resourcePath = await getResourceFolderAsync ( projectRoot ) ; const filePath = path . join ( resourcePath , `${ kind }/${ name }.xml` ) ; return filePath ; }