@digia-engage/core 2.2.1 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/DigiaEngageReactNative.podspec +1 -1
  2. package/LICENSE +77 -0
  3. package/README.md +1 -1
  4. package/lib/commonjs/Digia.js +1 -1
  5. package/lib/commonjs/DigiaAnchorView.js +42 -25
  6. package/lib/commonjs/DigiaAnchorView.js.map +1 -1
  7. package/lib/commonjs/DigiaHealthReporter.js +1 -1
  8. package/lib/commonjs/DigiaProvider.js +38 -6
  9. package/lib/commonjs/DigiaProvider.js.map +1 -1
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/module/Digia.js +1 -1
  12. package/lib/module/DigiaAnchorView.js +42 -25
  13. package/lib/module/DigiaAnchorView.js.map +1 -1
  14. package/lib/module/DigiaHealthReporter.js +1 -1
  15. package/lib/module/DigiaProvider.js +38 -6
  16. package/lib/module/DigiaProvider.js.map +1 -1
  17. package/lib/module/index.js.map +1 -1
  18. package/lib/typescript/DigiaAnchorView.d.ts +17 -1
  19. package/lib/typescript/DigiaAnchorView.d.ts.map +1 -1
  20. package/lib/typescript/DigiaProvider.d.ts.map +1 -1
  21. package/lib/typescript/index.d.ts +1 -0
  22. package/lib/typescript/index.d.ts.map +1 -1
  23. package/lib/typescript/templateTypes.d.ts +2 -0
  24. package/lib/typescript/templateTypes.d.ts.map +1 -1
  25. package/package.json +2 -8
  26. package/src/Digia.ts +1 -1
  27. package/src/DigiaAnchorView.tsx +74 -41
  28. package/src/DigiaHealthReporter.ts +1 -1
  29. package/src/DigiaProvider.tsx +36 -6
  30. package/src/index.ts +1 -0
  31. package/src/templateTypes.ts +2 -0
  32. package/android/.project +0 -28
  33. package/android/bin/.gradle/8.13/fileHashes/fileHashes.lock +0 -0
  34. package/android/bin/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  35. package/android/bin/.gradle/buildOutputCleanup/cache.properties +0 -2
  36. package/android/bin/.project +0 -34
  37. package/android/bin/build/generated/source/buildConfig/debug/com/digia/engage/rn/BuildConfig.class +0 -0
  38. package/android/bin/build/generated/source/codegen/java/com/digia/engage/rn/NativeDigiaEngageSpec.class +0 -0
  39. package/android/bin/build.gradle +0 -97
  40. package/android/bin/gradle/wrapper/gradle-wrapper.jar +0 -0
  41. package/android/bin/gradle/wrapper/gradle-wrapper.properties +0 -5
  42. package/android/bin/gradle.properties +0 -2
  43. package/android/bin/gradlew +0 -185
  44. package/android/bin/gradlew.bat +0 -89
  45. package/android/bin/local.properties +0 -1
  46. package/android/bin/settings.gradle +0 -25
  47. package/android/bin/src/main/AndroidManifest.xml +0 -2
  48. package/android/bin/src/main/java/com/digia/engage/rn/DigiaAnchorViewManager.kt +0 -90
  49. package/android/bin/src/main/java/com/digia/engage/rn/DigiaModule.kt +0 -309
  50. package/android/bin/src/main/java/com/digia/engage/rn/DigiaPackage.kt +0 -70
  51. package/android/bin/src/main/java/com/digia/engage/rn/DigiaSlotViewManager.kt +0 -183
  52. package/android/bin/src/main/java/com/digia/engage/rn/DigiaViewManager.kt +0 -64
  53. package/android/local.properties +0 -1
@@ -1,54 +1,87 @@
1
- import React, { useCallback, useEffect, useRef } from 'react';
1
+ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from 'react';
2
2
  import { View } from 'react-native';
3
3
  import type { ViewProps } from 'react-native';
4
4
  import { Digia } from './Digia';
5
5
  import { nativeDigiaModule } from './NativeDigiaEngage';
6
6
  import { digiaAnchorRegistry } from './digiaAnchorRegistry';
7
7
 
8
+ export interface DigiaAnchorViewRef {
9
+ /**
10
+ * Tell the anchor that the entrance/layout animation wrapping it has
11
+ * finished. The anchor then captures its final, resting position and
12
+ * publishes it to the registry so tooltips can attach to it.
13
+ *
14
+ * Attaching a ref is itself the signal that this anchor is animated: until
15
+ * the first `animationCompleted()` call the anchor publishes NOTHING, so a
16
+ * guide that triggers mid-animation simply finds no layout and stays
17
+ * invisible instead of painting at a transient (wrong) position.
18
+ *
19
+ * If you never attach a ref, none of this applies — the anchor measures on
20
+ * layout exactly as a static anchor always has.
21
+ */
22
+ animationCompleted: () => void;
23
+ }
24
+
8
25
  interface Props extends ViewProps {
9
26
  anchorKey: string;
10
27
  children?: React.ReactNode;
11
28
  }
12
29
 
13
- export function DigiaAnchorView({ anchorKey, children, style, ...rest }: Props) {
14
- useEffect(() => {
15
- Digia.registerAnchor(anchorKey);
16
- return () => {
17
- Digia.unregisterAnchor(anchorKey);
18
- digiaAnchorRegistry.remove(anchorKey);
19
- };
20
- }, [anchorKey]);
21
-
22
- return (
23
- <JsMeasureAnchor anchorKey={anchorKey} style={style} {...rest}>
24
- {children}
25
- </JsMeasureAnchor>
26
- );
27
- }
30
+ export const DigiaAnchorView = forwardRef<DigiaAnchorViewRef, Props>(
31
+ function DigiaAnchorView({ anchorKey, children, style, ...rest }, ref) {
32
+ // The native View we read the on-screen position from.
33
+ const viewRef = useRef<View>(null);
28
34
 
29
- function JsMeasureAnchor({ anchorKey, children, style, ...rest }: Props) {
30
- const ref = useRef<View>(null);
31
-
32
- const measure = useCallback(() => {
33
- ref.current?.measure((_x, _y, width, height, pageX, pageY) => {
34
- if (width === 0 && height === 0) return;
35
- nativeDigiaModule.registerAnchor(anchorKey, Math.round(pageX), Math.round(pageY), Math.round(width), Math.round(height));
36
- digiaAnchorRegistry.setLayout(anchorKey, { pageX, pageY, width, height });
37
- });
38
- }, [anchorKey]);
39
-
40
- useEffect(() => {
41
- digiaAnchorRegistry.registerMeasure(anchorKey, measure);
42
- return () => {
43
- digiaAnchorRegistry.unregisterMeasure(anchorKey, measure);
44
- nativeDigiaModule.unregisterAnchor(anchorKey);
45
- };
46
- }, [anchorKey, measure]);
47
-
48
- return (
49
- <View ref={ref} onLayout={measure} style={style} {...rest}>
50
- {children}
51
- </View>
52
- );
53
- }
35
+ // A ref attached by the consumer means "this anchor is animated, wait
36
+ // for me to call animationCompleted()". No ref means a plain static
37
+ // anchor that should measure as soon as it lays out.
38
+ const isAnimated = ref != null;
39
+
40
+ // The gate that decides whether measure() is allowed to publish.
41
+ // Static anchors start open (true) and behave exactly as before.
42
+ // Animated anchors start closed (false) and open on animationCompleted().
43
+ const canMeasure = useRef(!isAnimated);
44
+
45
+ // Read the View's current position and publish it to the registry.
46
+ // No-op while the gate is closed (animation still in flight).
47
+ const measure = useCallback(() => {
48
+ if (!canMeasure.current) return;
49
+ viewRef.current?.measure((_x, _y, width, height, pageX, pageY) => {
50
+ if (width === 0 && height === 0) return;
51
+ nativeDigiaModule.registerAnchor(anchorKey, Math.round(pageX), Math.round(pageY), Math.round(width), Math.round(height));
52
+ digiaAnchorRegistry.setLayout(anchorKey, { pageX, pageY, width, height });
53
+ });
54
+ }, [anchorKey]);
55
+
56
+ // What the consumer calls from their animation's completion callback.
57
+ // Open the gate, then measure on the frame after the animation's final
58
+ // commit so the position we capture is the resting one.
59
+ const animationCompleted = useCallback(() => {
60
+ canMeasure.current = true;
61
+ requestAnimationFrame(() => requestAnimationFrame(measure));
62
+ }, [measure]);
63
+
64
+ // Expose animationCompleted() on the ref. When no ref is attached this
65
+ // is a no-op, so static anchors carry zero extra behaviour.
66
+ useImperativeHandle(ref, () => ({ animationCompleted }), [animationCompleted]);
67
+
68
+ // Register the anchor (and its measure callback) with the SDK on mount,
69
+ // and tear everything down on unmount.
70
+ useEffect(() => {
71
+ Digia.registerAnchor(anchorKey);
72
+ digiaAnchorRegistry.registerMeasure(anchorKey, measure);
73
+ return () => {
74
+ Digia.unregisterAnchor(anchorKey);
75
+ digiaAnchorRegistry.unregisterMeasure(anchorKey, measure);
76
+ nativeDigiaModule.unregisterAnchor(anchorKey);
77
+ digiaAnchorRegistry.remove(anchorKey);
78
+ };
79
+ }, [anchorKey, measure]);
54
80
 
81
+ return (
82
+ <View ref={viewRef} onLayout={measure} style={style} {...rest}>
83
+ {children}
84
+ </View>
85
+ );
86
+ },
87
+ );
@@ -27,7 +27,7 @@ export class DigiaHealthReporter {
27
27
 
28
28
  report(eventType: HealthEventType, detail: Record<string, unknown>): void {
29
29
  if (!this._projectId) return;
30
- // TODO: TO BE PICKED LATER @aditya-digia — health event backend endpoint being removed
30
+ // Health-event reporting is currently disabled.
31
31
  // fetch(`${this._baseUrl}/engage/sdk/recordHealthEvent`, {
32
32
  // method: 'POST',
33
33
  // headers: {
@@ -220,6 +220,8 @@ function TooltipOverlay({
220
220
  const [floatPos, setFloatPos] = useState<FloatPos | null>(null);
221
221
  const [resolvedPlacement, setResolvedPlacement] = useState<string>('bottom');
222
222
  const [floatingSize, setFloatingSize] = useState<{ w: number; h: number } | null>(null);
223
+ const [readyStep, setReadyStep] = useState(-1);
224
+ const ready = readyStep === stepIndex;
223
225
  const step = config.steps[stepIndex];
224
226
  const { width: screenW } = useWindowDimensions();
225
227
  const opacityAnim = useRef(new Animated.Value(1)).current;
@@ -230,9 +232,21 @@ function TooltipOverlay({
230
232
  const showArrow = step.showArrow !== false;
231
233
  const gap = showArrow ? arrowSize + 4 : 8;
232
234
 
235
+ // Wait for the step's delayInMs before marking it ready. Re-runs on every step entry.
236
+ useEffect(() => {
237
+ const delay = step.delayInMs ?? 0;
238
+ if (delay <= 0) {
239
+ setReadyStep(stepIndex);
240
+ return;
241
+ }
242
+ const timer = setTimeout(() => setReadyStep(stepIndex), delay);
243
+ return () => clearTimeout(timer);
244
+ }, [stepIndex]); // eslint-disable-line react-hooks/exhaustive-deps
245
+
233
246
  useEffect(() => {
234
247
  setLayout(null);
235
248
  setFloatPos(null);
249
+ if (!ready) return;
236
250
  let skipCached = false;
237
251
  const unsub = digiaAnchorRegistry.subscribe(step.anchorKey, (l) => {
238
252
  if (!skipCached) return;
@@ -246,7 +260,7 @@ function TooltipOverlay({
246
260
  skipCached = true;
247
261
  digiaAnchorRegistry.remeasure(step.anchorKey);
248
262
  return unsub;
249
- }, [step.anchorKey]); // eslint-disable-line react-hooks/exhaustive-deps
263
+ }, [step.anchorKey, ready]); // eslint-disable-line react-hooks/exhaustive-deps
250
264
 
251
265
  useEffect(() => {
252
266
  if (!layout || !floatingSize) return;
@@ -273,8 +287,9 @@ function TooltipOverlay({
273
287
  }
274
288
  }, [floatPos, opacityAnim]);
275
289
 
276
- // Fire viewed/step_viewed when the step renders.
290
+ // Fire viewed/step_viewed when the step renders (after any delay has elapsed).
277
291
  useEffect(() => {
292
+ if (!ready) return;
278
293
  const isMultiStep = config.steps.length > 1;
279
294
  if (stepIndex === 0) {
280
295
  request.onExperienceEvent({ type: 'viewed', stepIndex: 0, stepTotal: config.steps.length, anchorKey: step.anchorKey, displayStyle: 'tooltip' });
@@ -283,7 +298,7 @@ function TooltipOverlay({
283
298
  request.onExperienceEvent({ type: 'step_viewed', stepIndex, stepTotal: config.steps.length, anchorKey: step.anchorKey, displayStyle: 'tooltip' });
284
299
  }
285
300
  // eslint-disable-next-line react-hooks/exhaustive-deps
286
- }, [stepIndex]);
301
+ }, [stepIndex, ready]);
287
302
 
288
303
  // Closes guide without firing analytics — used after CTA actions have already fired clicked events.
289
304
  const closeFromCTA = useCallback(() => {
@@ -596,13 +611,27 @@ function SpotlightOverlay({
596
611
  }) {
597
612
  const [stepIndex, setStepIndex] = useState(0);
598
613
  const [layout, setLayout] = useState<AnchorLayout | null>(null);
614
+ const [readyStep, setReadyStep] = useState(-1);
615
+ const ready = readyStep === stepIndex;
599
616
  const step = config.steps[stepIndex];
600
617
  const { width: screenW, height: screenH } = useWindowDimensions();
601
618
  const opacityAnim = useRef(new Animated.Value(1)).current;
602
619
  const pendingFadeIn = useRef(false);
603
620
 
621
+ // Wait for the step's delayInMs before marking it ready. Re-runs on every step entry.
622
+ useEffect(() => {
623
+ const delay = step.delayInMs ?? 0;
624
+ if (delay <= 0) {
625
+ setReadyStep(stepIndex);
626
+ return;
627
+ }
628
+ const timer = setTimeout(() => setReadyStep(stepIndex), delay);
629
+ return () => clearTimeout(timer);
630
+ }, [stepIndex]); // eslint-disable-line react-hooks/exhaustive-deps
631
+
604
632
  useEffect(() => {
605
633
  setLayout(null);
634
+ if (!ready) return; // hold off measuring/showing until the delay has elapsed
606
635
  let skipCached = false;
607
636
  const unsub = digiaAnchorRegistry.subscribe(step.anchorKey, (l) => {
608
637
  if (!skipCached) return;
@@ -616,7 +645,7 @@ function SpotlightOverlay({
616
645
  skipCached = true;
617
646
  digiaAnchorRegistry.remeasure(step.anchorKey);
618
647
  return unsub;
619
- }, [step.anchorKey]); // eslint-disable-line react-hooks/exhaustive-deps
648
+ }, [step.anchorKey, ready]); // eslint-disable-line react-hooks/exhaustive-deps
620
649
 
621
650
  useEffect(() => {
622
651
  if (layout && pendingFadeIn.current) {
@@ -625,8 +654,9 @@ function SpotlightOverlay({
625
654
  }
626
655
  }, [layout, opacityAnim]);
627
656
 
628
- // Fire viewed/step_viewed when the step renders.
657
+ // Fire viewed/step_viewed when the step renders (after any delay has elapsed).
629
658
  useEffect(() => {
659
+ if (!ready) return;
630
660
  const isMultiStep = config.steps.length > 1;
631
661
  if (stepIndex === 0) {
632
662
  request.onExperienceEvent({ type: 'viewed', stepIndex: 0, stepTotal: config.steps.length, anchorKey: step.anchorKey, displayStyle: 'spotlight' });
@@ -635,7 +665,7 @@ function SpotlightOverlay({
635
665
  request.onExperienceEvent({ type: 'step_viewed', stepIndex, stepTotal: config.steps.length, anchorKey: step.anchorKey, displayStyle: 'spotlight' });
636
666
  }
637
667
  // eslint-disable-next-line react-hooks/exhaustive-deps
638
- }, [stepIndex]);
668
+ }, [stepIndex, ready]);
639
669
 
640
670
  const closeFromCTA = useCallback(() => {
641
671
  Animated.timing(opacityAnim, { toValue: 0, duration: 150, useNativeDriver: true }).start(() => {
package/src/index.ts CHANGED
@@ -14,6 +14,7 @@ export { DigiaHostView } from './DigiaHostView';
14
14
  export { DigiaHost } from './DigiaProvider';
15
15
  export { DigiaSlotView } from './DigiaSlotView';
16
16
  export { DigiaAnchorView } from './DigiaAnchorView';
17
+ export type { DigiaAnchorViewRef } from './DigiaAnchorView';
17
18
  export type { ActionContext, ActionResult, CampaignType, DigiaAction, DigiaConfig, DigiaDelegate, DigiaExperienceEvent, DigiaPlugin, InAppBrowserAdapter, InAppPayload, OnAction } from './types';
18
19
  export { defaultInAppBrowser } from './defaultInAppBrowser';
19
20
  export { DigiaHealthReporter, HealthEventType, digiaHealthReporter } from './DigiaHealthReporter';
@@ -9,6 +9,7 @@ export type Action =
9
9
 
10
10
  export type TooltipStep = {
11
11
  anchorKey: string
12
+ delayInMs?: number
12
13
  title: string
13
14
  body: string
14
15
  placement: 'top' | 'bottom' | 'left' | 'right' | 'auto'
@@ -36,6 +37,7 @@ export type TooltipStep = {
36
37
 
37
38
  export type SpotlightStep = {
38
39
  anchorKey: string
40
+ delayInMs?: number
39
41
  title: string
40
42
  body: string
41
43
  calloutPosition: 'above' | 'below' | 'left' | 'right' | 'auto'
package/android/.project DELETED
@@ -1,28 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <projectDescription>
3
- <name>digia-engage_core</name>
4
- <comment>Project digia-engage_core created by Buildship.</comment>
5
- <projects>
6
- </projects>
7
- <buildSpec>
8
- <buildCommand>
9
- <name>org.eclipse.buildship.core.gradleprojectbuilder</name>
10
- <arguments>
11
- </arguments>
12
- </buildCommand>
13
- </buildSpec>
14
- <natures>
15
- <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
16
- </natures>
17
- <filteredResources>
18
- <filter>
19
- <id>1780322402778</id>
20
- <name></name>
21
- <type>30</type>
22
- <matcher>
23
- <id>org.eclipse.core.resources.regexFilterMatcher</id>
24
- <arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
25
- </matcher>
26
- </filter>
27
- </filteredResources>
28
- </projectDescription>
@@ -1,2 +0,0 @@
1
- #Tue Mar 24 10:26:20 IST 2026
2
- gradle.version=8.13
@@ -1,34 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <projectDescription>
3
- <name>digia-engage_core</name>
4
- <comment>Project digia-engage_core created by Buildship.</comment>
5
- <projects>
6
- </projects>
7
- <buildSpec>
8
- <buildCommand>
9
- <name>org.eclipse.jdt.core.javabuilder</name>
10
- <arguments>
11
- </arguments>
12
- </buildCommand>
13
- <buildCommand>
14
- <name>org.eclipse.buildship.core.gradleprojectbuilder</name>
15
- <arguments>
16
- </arguments>
17
- </buildCommand>
18
- </buildSpec>
19
- <natures>
20
- <nature>org.eclipse.jdt.core.javanature</nature>
21
- <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
22
- </natures>
23
- <filteredResources>
24
- <filter>
25
- <id>1780322402778</id>
26
- <name></name>
27
- <type>30</type>
28
- <matcher>
29
- <id>org.eclipse.core.resources.regexFilterMatcher</id>
30
- <arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
31
- </matcher>
32
- </filter>
33
- </filteredResources>
34
- </projectDescription>
@@ -1,97 +0,0 @@
1
- /**
2
- * Android Gradle build file for the @digia/engage-react-native library module.
3
- *
4
- * This module is a thin bridge layer that:
5
- * • Depends on the Digia Engage Android AAR
6
- * • Depends on the React Native SDK
7
- * • Exposes a ReactPackage (DigiaPackage) that registers the native module
8
- * and native view to React Native's bridge
9
- *
10
- * The Compose runtime/tooling dependencies are inherited transitively from
11
- * the Digia Engage AAR via `api` declarations; we only add what is needed for
12
- * the bridge code itself.
13
- */
14
-
15
- def isNewArchitectureEnabled() {
16
- return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
17
- }
18
-
19
- plugins {
20
- id 'com.android.library'
21
- id 'org.jetbrains.kotlin.android'
22
- id 'org.jetbrains.kotlin.plugin.compose' version '2.1.20'
23
- }
24
-
25
- if (isNewArchitectureEnabled()) {
26
- apply plugin: 'com.facebook.react'
27
- }
28
-
29
- if (isNewArchitectureEnabled()) {
30
- react {
31
- jsRootDir = file("../src/")
32
- libraryName = "DigiaEngageSpec"
33
- codegenJavaPackageName = "com.digia.engage.rn"
34
- }
35
- }
36
-
37
- android {
38
- compileSdk 35
39
- namespace 'com.digia.engage.rn'
40
-
41
- defaultConfig {
42
- minSdk 24
43
- targetSdk 35
44
- }
45
-
46
- buildTypes {
47
- release {
48
- minifyEnabled false
49
- }
50
- }
51
-
52
- compileOptions {
53
- sourceCompatibility JavaVersion.VERSION_17
54
- targetCompatibility JavaVersion.VERSION_17
55
- }
56
-
57
- kotlinOptions {
58
- jvmTarget = '17'
59
- }
60
-
61
- buildFeatures {
62
- compose true
63
- }
64
-
65
- sourceSets {
66
- main {
67
- java.srcDirs += 'src/main/java'
68
- }
69
- }
70
- }
71
-
72
- dependencies {
73
- // Digia Engage Android library
74
- implementation 'tech.digia:engage:2.1.0-Local'
75
-
76
- // ── React Native ─────────────────────────────────────────────────────────
77
- // React Native is provided by the host app; mark as compileOnly so it is
78
- // NOT bundled into this library.
79
- compileOnly "com.facebook.react:react-android"
80
-
81
- // ── Jetpack Compose ───────────────────────────────────────────────────────
82
- // Compose UI is transitively provided by digia-ui; we only need the
83
- // platform BOM for version alignment.
84
- implementation platform('androidx.compose:compose-bom:2023.03.00')
85
-
86
- // UI tooling annotations (used by AbstractComposeView / preview)
87
- implementation 'androidx.compose.ui:ui'
88
-
89
- // Lifecycle: ViewTreeLifecycleOwner / setViewTreeLifecycleOwner
90
- implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
91
-
92
- // SavedState: setViewTreeSavedStateRegistryOwner
93
- implementation 'androidx.savedstate:savedstate-ktx:1.2.1'
94
-
95
- // Activity: ComponentActivity needed for lifecycle owner detection
96
- implementation 'androidx.activity:activity-compose:1.7.2'
97
- }
@@ -1,5 +0,0 @@
1
- distributionBase=GRADLE_USER_HOME
2
- distributionPath=wrapper/dists
3
- distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4
- zipStoreBase=GRADLE_USER_HOME
5
- zipStorePath=wrapper/dists
@@ -1,2 +0,0 @@
1
- android.useAndroidX=true
2
- android.enableJetifier=true
@@ -1,185 +0,0 @@
1
- #!/usr/bin/env sh
2
-
3
- #
4
- # Copyright 2015 the original author or authors.
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # https://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- ##############################################################################
20
- ##
21
- ## Gradle start up script for UN*X
22
- ##
23
- ##############################################################################
24
-
25
- # Attempt to set APP_HOME
26
- # Resolve links: $0 may be a link
27
- PRG="$0"
28
- # Need this for relative symlinks.
29
- while [ -h "$PRG" ] ; do
30
- ls=`ls -ld "$PRG"`
31
- link=`expr "$ls" : '.*-> \(.*\)$'`
32
- if expr "$link" : '/.*' > /dev/null; then
33
- PRG="$link"
34
- else
35
- PRG=`dirname "$PRG"`"/$link"
36
- fi
37
- done
38
- SAVED="`pwd`"
39
- cd "`dirname \"$PRG\"`/" >/dev/null
40
- APP_HOME="`pwd -P`"
41
- cd "$SAVED" >/dev/null
42
-
43
- APP_NAME="Gradle"
44
- APP_BASE_NAME=`basename "$0"`
45
-
46
- # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47
- DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48
-
49
- # Use the maximum available, or set MAX_FD != -1 to use that value.
50
- MAX_FD="maximum"
51
-
52
- warn () {
53
- echo "$*"
54
- }
55
-
56
- die () {
57
- echo
58
- echo "$*"
59
- echo
60
- exit 1
61
- }
62
-
63
- # OS specific support (must be 'true' or 'false').
64
- cygwin=false
65
- msys=false
66
- darwin=false
67
- nonstop=false
68
- case "`uname`" in
69
- CYGWIN* )
70
- cygwin=true
71
- ;;
72
- Darwin* )
73
- darwin=true
74
- ;;
75
- MINGW* )
76
- msys=true
77
- ;;
78
- NONSTOP* )
79
- nonstop=true
80
- ;;
81
- esac
82
-
83
- CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84
-
85
-
86
- # Determine the Java command to use to start the JVM.
87
- if [ -n "$JAVA_HOME" ] ; then
88
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89
- # IBM's JDK on AIX uses strange locations for the executables
90
- JAVACMD="$JAVA_HOME/jre/sh/java"
91
- else
92
- JAVACMD="$JAVA_HOME/bin/java"
93
- fi
94
- if [ ! -x "$JAVACMD" ] ; then
95
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96
-
97
- Please set the JAVA_HOME variable in your environment to match the
98
- location of your Java installation."
99
- fi
100
- else
101
- JAVACMD="java"
102
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103
-
104
- Please set the JAVA_HOME variable in your environment to match the
105
- location of your Java installation."
106
- fi
107
-
108
- # Increase the maximum file descriptors if we can.
109
- if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110
- MAX_FD_LIMIT=`ulimit -H -n`
111
- if [ $? -eq 0 ] ; then
112
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113
- MAX_FD="$MAX_FD_LIMIT"
114
- fi
115
- ulimit -n $MAX_FD
116
- if [ $? -ne 0 ] ; then
117
- warn "Could not set maximum file descriptor limit: $MAX_FD"
118
- fi
119
- else
120
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121
- fi
122
- fi
123
-
124
- # For Darwin, add options to specify how the application appears in the dock
125
- if $darwin; then
126
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127
- fi
128
-
129
- # For Cygwin or MSYS, switch paths to Windows format before running java
130
- if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133
-
134
- JAVACMD=`cygpath --unix "$JAVACMD"`
135
-
136
- # We build the pattern for arguments to be converted via cygpath
137
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138
- SEP=""
139
- for dir in $ROOTDIRSRAW ; do
140
- ROOTDIRS="$ROOTDIRS$SEP$dir"
141
- SEP="|"
142
- done
143
- OURCYGPATTERN="(^($ROOTDIRS))"
144
- # Add a user-defined pattern to the cygpath arguments
145
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147
- fi
148
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
149
- i=0
150
- for arg in "$@" ; do
151
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153
-
154
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156
- else
157
- eval `echo args$i`="\"$arg\""
158
- fi
159
- i=`expr $i + 1`
160
- done
161
- case $i in
162
- 0) set -- ;;
163
- 1) set -- "$args0" ;;
164
- 2) set -- "$args0" "$args1" ;;
165
- 3) set -- "$args0" "$args1" "$args2" ;;
166
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172
- esac
173
- fi
174
-
175
- # Escape application args
176
- save () {
177
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178
- echo " "
179
- }
180
- APP_ARGS=`save "$@"`
181
-
182
- # Collect all arguments for the java command, following the shell quoting and substitution rules
183
- eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184
-
185
- exec "$JAVACMD" "$@"