-
Notifications
You must be signed in to change notification settings - Fork 100
/
Copy pathsourcemaps.gradle
168 lines (133 loc) · 6.55 KB
/
sourcemaps.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import org.apache.tools.ant.taskdefs.condition.Os
gradle.projectsEvaluated {
// Works for both `bundleReleaseJsAndAssets` and `createBundleReleaseJsAndAssets` and product flavors
def suffix = 'ReleaseJsAndAssets'
def bundleTasks = project(':app').tasks.findAll {
task -> task.name.endsWith(suffix)
}
bundleTasks.forEach { task ->
def name = task.name
def prefixes = ['bundle', 'createBundle']
def start = name.startsWith(prefixes[0]) ? prefixes[0].length() : prefixes[1].length()
def end = name.length() - suffix.length()
def flavor = name.substring(start, end).uncapitalize()
def defaultVersion = getDefaultVersion(flavor)
task.finalizedBy createUploadSourcemapsTask(flavor, defaultVersion.name, defaultVersion.code)
}
}
Task createUploadSourcemapsTask(String flavor, String defaultVersionName, String defaultVersionCode) {
def name = 'uploadSourcemaps' + flavor.capitalize()
// Don't recreate the task if it already exists.
// This prevents the build from failing in an edge case where the user has
// both `bundleReleaseJsAndAssets` and `createBundleReleaseJsAndAssets`
def taskExists = tasks.getNames().contains(name)
if (taskExists) {
return tasks.named(name).get()
}
def provider = tasks.register(name) {
group 'instabug'
description 'Uploads sourcemaps file to Instabug server'
enabled = isUploadSourcemapsEnabled()
doLast {
try {
def appProject = project(':app')
def appDir = appProject.projectDir
def sourceMapFile = getSourceMapFile(appDir, flavor)
def jsProjectDir = rootDir.parentFile
def instabugDir = new File(['node', '-p', 'require.resolve("@instabug/instabug-reactnative-dream11/package.json")'].execute(null, rootDir).text.trim()).getParentFile()
def tokenShellFile = new File(instabugDir, 'scripts/find-token.sh')
def inferredToken = executeShellScript(tokenShellFile, jsProjectDir)
def appToken = resolveVar('App Token', 'INSTABUG_APP_TOKEN', inferredToken)
def versionName = resolveVar('Version Name', 'INSTABUG_VERSION_NAME', defaultVersionName)
def versionCode = resolveVar('Version Code', 'INSTABUG_VERSION_CODE', defaultVersionCode)
exec {
def osCompatibility = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c'] : []
def args = [
'npx', 'instabug', 'upload-sourcemaps',
'--platform', 'android',
'--file', sourceMapFile.absolutePath,
'--token', appToken,
'--name', versionName,
'--code', versionCode
]
commandLine(*osCompatibility, *args)
}
} catch (exception) {
project.logger.error "Failed to upload source map file.\n" +
"Reason: ${exception.message}"
}
}
}
return provider.get()
}
File getSourceMapFile(File appDir, String flavor) {
def defaultFlavorPath = flavor.empty ? 'release' : "${flavor}Release"
def defaultSourceMapDest = "build/generated/sourcemaps/react/${defaultFlavorPath}/index.android.bundle.map"
def defaultSourceMapFile = new File(appDir, defaultSourceMapDest)
if (defaultSourceMapFile.exists()) {
return defaultSourceMapFile
}
if (flavor.empty) {
throw new InvalidUserDataException("Unable to find source map file at: ${defaultSourceMapFile.absolutePath}.")
}
def fallbackSourceMapDest = "build/generated/sourcemaps/react/${flavor}/release/index.android.bundle.map"
def fallbackSourceMapFile = new File(appDir, fallbackSourceMapDest)
project.logger.info "Unable to find source map file at: ${defaultSourceMapFile.absolutePath}.\n" +
"Falling back to ${fallbackSourceMapFile.absolutePath}."
if (!fallbackSourceMapFile.exists()) {
throw new InvalidUserDataException("Unable to find source map file at: ${fallbackSourceMapFile.absolutePath} either.")
}
return fallbackSourceMapFile
}
/**
* Infers the app version to use in source map upload based on the flavor.
* This is needed since different flavors may have different version codes and names (e.g. version suffixes).
*
* It checks the version for the flavor's variant.
* If no variant is found it falls back to the app's default config.
*
*
* @param flavor The flavor to get the app version for.
* @return A map containing the version code and version name.
*/
Map<String, String> getDefaultVersion(String flavor) {
def appProject = project(':app')
def defaultConfig = appProject.android.defaultConfig
def variants = appProject.android.applicationVariants
// uncapitalize is used to turn "Release" into "release" if the flavor is empty
def variantName = "${flavor}Release".uncapitalize()
def variant = variants.find { it.name.uncapitalize() == variantName }
def versionName = variant?.versionName ?: defaultConfig.versionName
def versionCode = variant?.versionCode ?: defaultConfig.versionCode
return [name: "${versionName}", code: "${versionCode}"]
}
boolean isUploadSourcemapsEnabled() {
def envValue = System.getenv('INSTABUG_SOURCEMAPS_UPLOAD_DISABLE')?.toBoolean()
def defaultValue = true
return (envValue != null) ? !envValue : defaultValue
}
String resolveVar(String name, String envKey, String defaultValue) {
def env = System.getenv()
def envValue = env.get(envKey)
if (envValue != null && defaultValue !=null && envValue != defaultValue) {
project.logger.warn "Environment variable `${envKey}` might have incorrect value, " +
"make sure this was intentional:\n" +
" Environment Value: ${envValue}\n" +
" Default Value: ${defaultValue}"
}
def value = envValue ?: defaultValue
if (value == null) {
throw new InvalidUserDataException("Unable to find ${name}! " +
"Set the environment variable `${envKey}` and try again.")
}
return value
}
static String executeShellScript(File script, File workingDir) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
return null
}
def output = new StringBuffer()
def process = ['sh', script.getAbsolutePath()].execute(null, workingDir)
process?.waitForProcessOutput(output, new StringBuffer())
return process?.exitValue() == 0 ? output.toString().trim() : null
}