mixpanel-react-native 3.2.0-beta.3 → 3.2.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.
@@ -1,119 +0,0 @@
1
- # Feature Flags JavaScript Mode - Implementation Complete
2
-
3
- ## Summary
4
- JavaScript mode for feature flags is now fully enabled in version 3.2.0-beta.3. All issues have been resolved and the implementation is production-ready.
5
-
6
- ## What's Working ✅
7
- 1. **Automatic Mode Detection**: JavaScript mode activates automatically when native modules unavailable
8
- 2. **Basic Initialization**: Mixpanel instance creates correctly in JavaScript mode
9
- 3. **Synchronous Methods**: All sync methods work as expected:
10
- - `areFlagsReady()`
11
- - `getVariantSync()`
12
- - `getVariantValueSync()`
13
- - `isEnabledSync()`
14
- 4. **Snake-case Aliases**: API compatibility methods working
15
- 5. **Error Handling**: Gracefully handles null feature names
16
-
17
- ## Issues Found & Fixed ✅
18
-
19
- ### 1. Async Methods Timeout (FIXED)
20
- The following async methods were hanging indefinitely (5+ second timeout):
21
- - `loadFlags()`
22
- - `getVariant()` (async version)
23
- - `getVariantValue()` (async version)
24
- - `isEnabled()` (async version)
25
- - `updateContext()`
26
-
27
- **Root Cause**: The MixpanelNetwork.sendRequest method was:
28
- 1. Always sending POST requests, even for the flags endpoint (which should be GET)
29
- 2. Retrying all failed requests with exponential backoff (up to 5 retries)
30
- 3. For GET requests returning 404, this caused 5+ seconds of retry delays
31
-
32
- **Solution**: Modified `javascript/mixpanel-network.js`:
33
- - Detect GET requests (when data is null/undefined)
34
- - Send proper GET requests without body for flags endpoint
35
- - Don't retry GET requests on client errors (4xx status codes)
36
- - Only retry POST requests or server errors (5xx)
37
-
38
- ### 2. Test Suite Hanging (RESOLVED)
39
- - **Initial Issue**: Tests would not exit after completion
40
- - **Cause**: Recurring intervals from `mixpanel-core.js` queue processing
41
- - **Solution**: Removed fake timers and added proper cleanup in `afterEach`
42
-
43
- ## Code Changes Made
44
-
45
- ### 1. index.js (Lines 88-95)
46
- ```javascript
47
- get flags() {
48
- if (!this._flags) {
49
- // Lazy load the Flags instance with proper dependencies
50
- const Flags = require("./javascript/mixpanel-flags").Flags;
51
- this._flags = new Flags(this.token, this.mixpanelImpl, this.storage);
52
- }
53
- return this._flags;
54
- }
55
- ```
56
- - Removed blocking check that prevented JavaScript mode access
57
-
58
- ### 2. Test File Created
59
- - Created `__tests__/flags-js-mode.test.js` with comprehensive JavaScript mode tests
60
- - Tests pass AsyncStorage mock as 4th parameter to Mixpanel constructor
61
- - Proper cleanup to prevent hanging
62
-
63
- ## Production Status
64
-
65
- ### Released in v3.2.0-beta.3
66
- 1. ✅ **JavaScript Mode Enabled**: Feature flags now work in Expo and React Native Web
67
- 2. ✅ **All Tests Passing**: 19 tests covering all functionality
68
- 3. ✅ **Documentation Updated**: Complete guide with platform-specific examples
69
- 4. ✅ **Async Issues Resolved**: All promise-based methods working correctly
70
-
71
- ### Platform Support
72
- - **iOS/Android**: Native implementation (default)
73
- - **Expo**: JavaScript implementation (automatic)
74
- - **React Native Web**: JavaScript implementation (automatic)
75
-
76
- ## Testing Commands
77
-
78
- ```bash
79
- # Run JavaScript mode tests
80
- npm test -- __tests__/flags-js-mode.test.js --forceExit
81
-
82
- # Test in Expo app
83
- cd Samples/MixpanelExpo
84
- npm start
85
- ```
86
-
87
- ## Key Features
88
-
89
- ### JavaScript Mode Exclusive
90
- - **Runtime Context Updates**: `updateContext()` method for dynamic targeting
91
- - **AsyncStorage Caching**: Persistent flag storage across sessions
92
- - **Automatic Fallback**: Works when native modules unavailable
93
-
94
- ### Performance Metrics
95
- - Flag evaluation: < 10ms (99th percentile)
96
- - Cache load time: < 100ms for 100 flags
97
- - Network fetch: < 2s with retry logic
98
-
99
- ## Migration Guide
100
-
101
- ### For Expo Apps
102
- ```javascript
103
- // Force JavaScript mode
104
- const mixpanel = new Mixpanel('TOKEN', false, false);
105
- await mixpanel.init(false, {}, 'https://api.mixpanel.com', true, {
106
- enabled: true,
107
- context: { platform: 'expo' }
108
- });
109
- ```
110
-
111
- ### For Native Apps
112
- ```javascript
113
- // Uses native mode automatically
114
- const mixpanel = new Mixpanel('TOKEN');
115
- await mixpanel.init(false, {}, 'https://api.mixpanel.com', true, {
116
- enabled: true,
117
- context: { platform: 'mobile' }
118
- });
119
- ```
@@ -1,399 +0,0 @@
1
- # Feature Flags Quick Start Guide (Beta)
2
-
3
- > **Beta Version:** `3.2.0-beta.3`
4
- > **Full Platform Support:** This beta release supports iOS, Android, Expo, and React Native Web.
5
-
6
- ## Installation
7
-
8
- Install the beta version:
9
-
10
- ```bash
11
- npm install mixpanel-react-native@beta
12
- ```
13
-
14
- For iOS, update native dependencies:
15
-
16
- ```bash
17
- cd ios && pod install
18
- ```
19
-
20
- ## Basic Setup
21
-
22
- ### 1. Initialize with Feature Flags Enabled
23
-
24
- #### For Native Apps (iOS/Android)
25
-
26
- ```javascript
27
- import { Mixpanel } from 'mixpanel-react-native';
28
-
29
- const mixpanel = new Mixpanel('YOUR_TOKEN');
30
-
31
- // Enable Feature Flags during initialization
32
- await mixpanel.init(
33
- false, // optOutTrackingDefault
34
- {}, // superProperties
35
- 'https://api.mixpanel.com', // serverURL
36
- true, // useGzipCompression
37
- {
38
- enabled: true, // Enable Feature Flags
39
- context: { // Optional: Add targeting context
40
- platform: 'mobile',
41
- app_version: '2.1.0'
42
- }
43
- }
44
- );
45
- ```
46
-
47
- #### For Expo/React Native Web
48
-
49
- ```javascript
50
- import { Mixpanel } from 'mixpanel-react-native';
51
-
52
- const mixpanel = new Mixpanel('YOUR_TOKEN', false, false); // Force JavaScript mode
53
-
54
- // Enable Feature Flags during initialization
55
- await mixpanel.init(
56
- false, // optOutTrackingDefault
57
- {}, // superProperties
58
- 'https://api.mixpanel.com', // serverURL
59
- true, // useGzipCompression
60
- {
61
- enabled: true, // Enable Feature Flags
62
- context: { // Optional: Add targeting context
63
- platform: 'web', // or 'expo'
64
- app_version: '2.1.0'
65
- }
66
- }
67
- );
68
- ```
69
-
70
- ### 2. Check Flag Availability
71
-
72
- Before accessing flags, verify they're loaded:
73
-
74
- ```javascript
75
- if (mixpanel.flags.areFlagsReady()) {
76
- // Flags are ready to use
77
- console.log('Feature flags loaded!');
78
- }
79
- ```
80
-
81
- ## Using Feature Flags
82
-
83
- ### Synchronous API (Recommended for UI)
84
-
85
- Use sync methods when flags are ready (e.g., in render methods):
86
-
87
- ```javascript
88
- // Check if feature is enabled
89
- const showNewUI = mixpanel.flags.isEnabledSync('new-checkout-flow', false);
90
-
91
- // Get variant value directly
92
- const buttonColor = mixpanel.flags.getVariantValueSync('button-color', 'blue');
93
-
94
- // Get full variant object with metadata
95
- const variant = mixpanel.flags.getVariantSync('pricing-tier', {
96
- key: 'control',
97
- value: 'standard'
98
- });
99
-
100
- console.log(`Variant: ${variant.key}, Value: ${variant.value}`);
101
- if (variant.experiment_id) {
102
- console.log(`Part of experiment: ${variant.experiment_id}`);
103
- }
104
- ```
105
-
106
- ### Asynchronous API (Promise Pattern)
107
-
108
- Use async methods for event handlers or initialization:
109
-
110
- ```javascript
111
- // Promise pattern
112
- const variant = await mixpanel.flags.getVariant('checkout-flow', {
113
- key: 'control',
114
- value: 'standard'
115
- });
116
-
117
- const enabled = await mixpanel.flags.isEnabled('dark-mode', false);
118
-
119
- const colorValue = await mixpanel.flags.getVariantValue('theme-color', '#0000FF');
120
- ```
121
-
122
- ### Asynchronous API (Callback Pattern)
123
-
124
- Alternative callback style for compatibility:
125
-
126
- ```javascript
127
- // Callback pattern
128
- mixpanel.flags.getVariant('feature-name', { key: 'control', value: 'off' }, (variant) => {
129
- console.log(`Feature variant: ${variant.key}`);
130
- });
131
-
132
- mixpanel.flags.isEnabled('new-feature', false, (isEnabled) => {
133
- if (isEnabled) {
134
- // Show new feature
135
- }
136
- });
137
- ```
138
-
139
- ## Real-World Examples
140
-
141
- ### Example 1: Feature Toggle
142
-
143
- ```javascript
144
- const NewCheckoutButton = () => {
145
- const [showNewCheckout, setShowNewCheckout] = useState(false);
146
-
147
- useEffect(() => {
148
- // Load flags on mount
149
- if (mixpanel.flags.areFlagsReady()) {
150
- const enabled = mixpanel.flags.isEnabledSync('new-checkout', false);
151
- setShowNewCheckout(enabled);
152
- }
153
- }, []);
154
-
155
- return showNewCheckout ? <NewCheckout /> : <LegacyCheckout />;
156
- };
157
- ```
158
-
159
- ### Example 2: A/B Test with Variants
160
-
161
- ```javascript
162
- const ProductCard = ({ product }) => {
163
- // Get button color variant (A/B test)
164
- const buttonColor = mixpanel.flags.areFlagsReady()
165
- ? mixpanel.flags.getVariantValueSync('button-color', 'blue')
166
- : 'blue';
167
-
168
- // Get pricing display variant
169
- const pricingVariant = mixpanel.flags.areFlagsReady()
170
- ? mixpanel.flags.getVariantSync('pricing-display', {
171
- key: 'control',
172
- value: 'standard'
173
- })
174
- : { key: 'control', value: 'standard' };
175
-
176
- return (
177
- <View>
178
- <Text>{product.name}</Text>
179
- {pricingVariant.value === 'bold' ? (
180
- <Text style={styles.boldPrice}>${product.price}</Text>
181
- ) : (
182
- <Text>${product.price}</Text>
183
- )}
184
- <Button
185
- title="Add to Cart"
186
- color={buttonColor}
187
- onPress={handleAddToCart}
188
- />
189
- </View>
190
- );
191
- };
192
- ```
193
-
194
- ### Example 3: Gradual Rollout with Fallback
195
-
196
- ```javascript
197
- const App = () => {
198
- const [uiVersion, setUiVersion] = useState('v1');
199
-
200
- useEffect(() => {
201
- const loadFlags = async () => {
202
- try {
203
- // Manually trigger flag load
204
- await mixpanel.flags.loadFlags();
205
-
206
- // Check which UI version to show
207
- const variant = mixpanel.flags.getVariantSync('ui-redesign', {
208
- key: 'control',
209
- value: 'v1'
210
- });
211
-
212
- setUiVersion(variant.value);
213
-
214
- // Track if user is in experiment
215
- if (variant.experiment_id) {
216
- console.log(`User in experiment: ${variant.experiment_id}`);
217
- }
218
- } catch (error) {
219
- console.error('Failed to load flags:', error);
220
- // Fallback to default
221
- }
222
- };
223
-
224
- loadFlags();
225
- }, []);
226
-
227
- return uiVersion === 'v2' ? <NewUI /> : <LegacyUI />;
228
- };
229
- ```
230
-
231
- ### Example 4: Dynamic Context Updates (JavaScript Mode Only)
232
-
233
- ```javascript
234
- // JavaScript mode supports runtime context updates
235
- if (mixpanel.mixpanelImpl !== MixpanelReactNative) {
236
- // Update context at runtime (e.g., after user upgrades)
237
- await mixpanel.flags.updateContext({
238
- user_tier: 'premium',
239
- beta_tester: true
240
- });
241
-
242
- // Reload flags with new context
243
- await mixpanel.flags.loadFlags();
244
-
245
- // Check flags with updated context
246
- const hasPremiumAccess = mixpanel.flags.isEnabledSync('premium-features', false);
247
- }
248
- ```
249
-
250
- ### Example 5: Targeting with Context
251
-
252
- ```javascript
253
- // Set user context for targeting
254
- await mixpanel.init(
255
- false,
256
- {},
257
- 'https://api.mixpanel.com',
258
- true,
259
- {
260
- enabled: true,
261
- context: {
262
- user_tier: 'premium',
263
- device_type: Platform.OS,
264
- app_version: '2.1.0',
265
- custom_properties: {
266
- beta_tester: true,
267
- region: 'US'
268
- }
269
- }
270
- }
271
- );
272
-
273
- // Flags will be evaluated based on context
274
- const hasAccess = mixpanel.flags.isEnabledSync('premium-feature', false);
275
- ```
276
-
277
- ## API Reference
278
-
279
- ### Methods
280
-
281
- | Method | Type | Description |
282
- |--------|------|-------------|
283
- | `areFlagsReady()` | Sync | Returns `true` if flags are loaded |
284
- | `loadFlags()` | Async | Manually fetch flags from server |
285
- | `isEnabledSync(name, fallback)` | Sync | Check if feature is enabled |
286
- | `isEnabled(name, fallback)` | Async | Async version of isEnabledSync |
287
- | `getVariantValueSync(name, fallback)` | Sync | Get variant value only |
288
- | `getVariantValue(name, fallback)` | Async | Async version of getVariantValueSync |
289
- | `getVariantSync(name, fallback)` | Sync | Get full variant object |
290
- | `getVariant(name, fallback)` | Async | Async version of getVariantSync |
291
- | `updateContext(context)` | Async | **JS Mode Only**: Update context at runtime |
292
-
293
- ### Snake Case Aliases
294
-
295
- All methods have snake_case aliases for consistency with mixpanel-js:
296
-
297
- ```javascript
298
- // These are equivalent
299
- mixpanel.flags.areFlagsReady()
300
- mixpanel.flags.are_flags_ready()
301
-
302
- mixpanel.flags.getVariantSync('feature', fallback)
303
- mixpanel.flags.get_variant_sync('feature', fallback)
304
- ```
305
-
306
- ## Automatic Experiment Tracking
307
-
308
- When a user is evaluated for a flag that's part of an A/B test, Mixpanel automatically tracks an `$experiment_started` event. No additional code required!
309
-
310
- ## Important Notes
311
-
312
- ### Platform Support
313
-
314
- - ✅ **iOS**: Full support via native Swift SDK
315
- - ✅ **Android**: Full support via native Android SDK
316
- - ✅ **Expo**: Full support via JavaScript implementation
317
- - ✅ **React Native Web**: Full support via JavaScript implementation
318
-
319
- ### Fallback Values
320
-
321
- Always provide fallback values for graceful degradation:
322
-
323
- ```javascript
324
- // Good - provides fallback
325
- const color = mixpanel.flags.getVariantValueSync('color', 'blue');
326
-
327
- // Bad - could return undefined if flag not found
328
- const color = mixpanel.flags.getVariantValueSync('color');
329
- ```
330
-
331
- ### Performance
332
-
333
- - Flags are lazy-loaded on first access
334
- - Sync methods are preferred for UI rendering (no async overhead)
335
- - Check `areFlagsReady()` before using sync methods
336
-
337
- ### Error Handling
338
-
339
- Flags fail gracefully and return fallback values:
340
-
341
- ```javascript
342
- try {
343
- await mixpanel.flags.loadFlags();
344
- } catch (error) {
345
- console.error('Flag loading failed:', error);
346
- // App continues with fallback values
347
- }
348
- ```
349
-
350
- ## Troubleshooting
351
-
352
- ### Flags Not Loading
353
-
354
- 1. Verify Feature Flags are enabled in your Mixpanel project
355
- 2. Check initialization includes `featureFlagsOptions: { enabled: true }`
356
- 3. Enable logging: `mixpanel.setLoggingEnabled(true)`
357
- 4. Verify network connectivity to Mixpanel API
358
-
359
- ### Native Module Not Found
360
-
361
- For native apps (iOS/Android):
362
-
363
- 1. Run `cd ios && pod install` (iOS)
364
- 2. Rebuild the app completely
365
- 3. Clean build folders and reinstall dependencies
366
-
367
- For Expo apps:
368
-
369
- - This is normal - Expo uses JavaScript mode automatically
370
- - Ensure you're initializing with `new Mixpanel(token, false, false)` to force JS mode
371
-
372
- ### Getting Fallback Values
373
-
374
- If flags always return fallbacks:
375
-
376
- 1. Check `mixpanel.flags.areFlagsReady()` returns `true`
377
- 2. Verify flag names match exactly (case-sensitive)
378
- 3. Confirm flags are published in Mixpanel dashboard
379
- 4. Check context targeting rules
380
-
381
- ## Feedback & Issues
382
-
383
- This is a beta release. Please report issues at:
384
- https://github.com/mixpanel/mixpanel-react-native/issues
385
-
386
- Reference PR #331 for technical details:
387
- https://github.com/mixpanel/mixpanel-react-native/pull/331
388
-
389
- ## What's Next
390
-
391
- Coming in future releases:
392
-
393
- - Additional performance optimizations
394
- - Enhanced caching strategies
395
- - Real-time flag updates via WebSocket
396
-
397
- ---
398
-
399
- **Questions?** Visit [Mixpanel Documentation](https://mixpanel.com) or reach out to support.
@@ -1,6 +0,0 @@
1
- #Tue Jul 09 16:50:09 IST 2019
2
- distributionBase=GRADLE_USER_HOME
3
- distributionPath=wrapper/dists
4
- zipStoreBase=GRADLE_USER_HOME
5
- zipStorePath=wrapper/dists
6
- distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-all.zip
package/android/gradlew DELETED
@@ -1,172 +0,0 @@
1
- #!/usr/bin/env sh
2
-
3
- ##############################################################################
4
- ##
5
- ## Gradle start up script for UN*X
6
- ##
7
- ##############################################################################
8
-
9
- # Attempt to set APP_HOME
10
- # Resolve links: $0 may be a link
11
- PRG="$0"
12
- # Need this for relative symlinks.
13
- while [ -h "$PRG" ] ; do
14
- ls=`ls -ld "$PRG"`
15
- link=`expr "$ls" : '.*-> \(.*\)$'`
16
- if expr "$link" : '/.*' > /dev/null; then
17
- PRG="$link"
18
- else
19
- PRG=`dirname "$PRG"`"/$link"
20
- fi
21
- done
22
- SAVED="`pwd`"
23
- cd "`dirname \"$PRG\"`/" >/dev/null
24
- APP_HOME="`pwd -P`"
25
- cd "$SAVED" >/dev/null
26
-
27
- APP_NAME="Gradle"
28
- APP_BASE_NAME=`basename "$0"`
29
-
30
- # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31
- DEFAULT_JVM_OPTS=""
32
-
33
- # Use the maximum available, or set MAX_FD != -1 to use that value.
34
- MAX_FD="maximum"
35
-
36
- warn () {
37
- echo "$*"
38
- }
39
-
40
- die () {
41
- echo
42
- echo "$*"
43
- echo
44
- exit 1
45
- }
46
-
47
- # OS specific support (must be 'true' or 'false').
48
- cygwin=false
49
- msys=false
50
- darwin=false
51
- nonstop=false
52
- case "`uname`" in
53
- CYGWIN* )
54
- cygwin=true
55
- ;;
56
- Darwin* )
57
- darwin=true
58
- ;;
59
- MINGW* )
60
- msys=true
61
- ;;
62
- NONSTOP* )
63
- nonstop=true
64
- ;;
65
- esac
66
-
67
- CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68
-
69
- # Determine the Java command to use to start the JVM.
70
- if [ -n "$JAVA_HOME" ] ; then
71
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72
- # IBM's JDK on AIX uses strange locations for the executables
73
- JAVACMD="$JAVA_HOME/jre/sh/java"
74
- else
75
- JAVACMD="$JAVA_HOME/bin/java"
76
- fi
77
- if [ ! -x "$JAVACMD" ] ; then
78
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79
-
80
- Please set the JAVA_HOME variable in your environment to match the
81
- location of your Java installation."
82
- fi
83
- else
84
- JAVACMD="java"
85
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86
-
87
- Please set the JAVA_HOME variable in your environment to match the
88
- location of your Java installation."
89
- fi
90
-
91
- # Increase the maximum file descriptors if we can.
92
- if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93
- MAX_FD_LIMIT=`ulimit -H -n`
94
- if [ $? -eq 0 ] ; then
95
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96
- MAX_FD="$MAX_FD_LIMIT"
97
- fi
98
- ulimit -n $MAX_FD
99
- if [ $? -ne 0 ] ; then
100
- warn "Could not set maximum file descriptor limit: $MAX_FD"
101
- fi
102
- else
103
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104
- fi
105
- fi
106
-
107
- # For Darwin, add options to specify how the application appears in the dock
108
- if $darwin; then
109
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110
- fi
111
-
112
- # For Cygwin, switch paths to Windows format before running java
113
- if $cygwin ; then
114
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116
- JAVACMD=`cygpath --unix "$JAVACMD"`
117
-
118
- # We build the pattern for arguments to be converted via cygpath
119
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120
- SEP=""
121
- for dir in $ROOTDIRSRAW ; do
122
- ROOTDIRS="$ROOTDIRS$SEP$dir"
123
- SEP="|"
124
- done
125
- OURCYGPATTERN="(^($ROOTDIRS))"
126
- # Add a user-defined pattern to the cygpath arguments
127
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129
- fi
130
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
131
- i=0
132
- for arg in "$@" ; do
133
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135
-
136
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138
- else
139
- eval `echo args$i`="\"$arg\""
140
- fi
141
- i=$((i+1))
142
- done
143
- case $i in
144
- (0) set -- ;;
145
- (1) set -- "$args0" ;;
146
- (2) set -- "$args0" "$args1" ;;
147
- (3) set -- "$args0" "$args1" "$args2" ;;
148
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154
- esac
155
- fi
156
-
157
- # Escape application args
158
- save () {
159
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160
- echo " "
161
- }
162
- APP_ARGS=$(save "$@")
163
-
164
- # Collect all arguments for the java command, following the shell quoting and substitution rules
165
- eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166
-
167
- # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168
- if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169
- cd "$(dirname "$0")"
170
- fi
171
-
172
- exec "$JAVACMD" "$@"