Skip to content

Commit

Permalink
feat: add deeplinks to our documentation
Browse files Browse the repository at this point in the history
These changes will only start to work once our documentation is updated
to support this feature:
- facebook/react-native-website#3618
- facebook/react-native-website#3619
- facebook/react-native-website#3620
  • Loading branch information
blakef committed Mar 20, 2023
1 parent f3218c3 commit bde1e1f
Show file tree
Hide file tree
Showing 19 changed files with 258 additions and 13 deletions.
1 change: 1 addition & 0 deletions __e2e__/__snapshots__/config.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`shows up current config without unnecessary output 1`] = `
{
"root": "<<REPLACED_ROOT>>/TestProject",
"reactNativePath": "<<REPLACED_ROOT>>/TestProject/node_modules/react-native",
"reactNativeVersion": "0.71",
"dependencies": {},
"commands": [
{
Expand Down
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = {
],
plugins: [
[require.resolve('@babel/plugin-transform-modules-commonjs'), {lazy: true}],
'@babel/plugin-proposal-export-namespace-from',
],
sourceMaps: true,
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
"@babel/plugin-transform-modules-commonjs": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.6.2",
"@babel/preset-env": "^7.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Object {
"platforms": Object {},
"project": Object {},
"reactNativePath": "<<REPLACED>>",
"reactNativeVersion": "unknown",
"root": "<<REPLACED>>",
}
`;
Expand Down
22 changes: 22 additions & 0 deletions packages/cli-config/src/loadConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import path from 'path';
import fs from 'fs';
import semver from 'semver';
import {
UserDependencyConfig,
ProjectConfig,
Expand Down Expand Up @@ -65,6 +67,7 @@ function loadConfig(projectRoot: string = findProjectRoot()): Config {
? path.resolve(projectRoot, userConfig.reactNativePath)
: resolveReactNativePath(projectRoot);
},
reactNativeVersion: 'unknown',
dependencies: userConfig.dependencies,
commands: userConfig.commands,
healthChecks: [],
Expand All @@ -89,6 +92,25 @@ function loadConfig(projectRoot: string = findProjectRoot()): Config {
},
};

// Try our best to figure out what version of React Native we're running. This is
// currently being used to get our deeplinks working, so it's only worried with
// the major and minor version.
try {
const {version} = JSON.parse(
fs.readFileSync(
path.join(initialConfig.reactNativePath, 'package.json'),
{encoding: 'utf8'},
),
);
const out = semver.parse(version);
if (out) {
// Retain only these version, since they correspond with our documentation.
initialConfig.reactNativeVersion = `${out.major}.${out.minor}`;
}
} catch (_) {
// We don't seem to be in a well formed project, give up quietly.
}

const finalConfig = Array.from(
new Set([
...Object.keys(userConfig.dependencies),
Expand Down
8 changes: 6 additions & 2 deletions packages/cli-doctor/src/tools/healthchecks/androidSDK.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {findProjectRoot, logger} from '@react-native-community/cli-tools';
import {findProjectRoot, logger, link} from '@react-native-community/cli-tools';
import chalk from 'chalk';
import fs from 'fs';
import path from 'path';
Expand Down Expand Up @@ -182,7 +182,11 @@ export default {

return logManualInstallation({
healthcheck: 'Android SDK',
url: 'https://reactnative.dev/docs/environment-setup',
url: link.docs('environment-setup', {
hash: 'android-sdk',
guide: 'native',
platform: 'android',
}),
});
},
} as HealthCheckInterface;
8 changes: 7 additions & 1 deletion packages/cli-doctor/src/tools/healthchecks/androidStudio.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {join} from 'path';

import {link} from '@react-native-community/cli-tools';

import {HealthCheckInterface} from '../../types';

import {downloadAndUnzip} from '../downloadAndUnzip';
Expand Down Expand Up @@ -74,7 +76,11 @@ export default {

return logManualInstallation({
healthcheck: 'Android Studio',
url: 'https://reactnative.dev/docs/environment-setup',
url: link.docs('environment-setup', {
hash: 'android-studio',
guide: 'native',
platform: 'android',
}),
});
},
} as HealthCheckInterface;
9 changes: 8 additions & 1 deletion packages/cli-doctor/src/tools/healthchecks/jdk.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import {join} from 'path';

import {link} from '@react-native-community/cli-tools';

import versionRanges from '../versionRanges';
import {doesSoftwareNeedToBeFixed} from '../checkInstallation';
import {HealthCheckInterface} from '../../types';
Expand Down Expand Up @@ -58,7 +61,11 @@ export default {
loader.fail();
logManualInstallation({
healthcheck: 'JDK',
url: 'https://reactnative.dev/docs/environment-setup',
url: link.docs('environment-setup', {
hash: 'jdk-studio',
guide: 'native',
platform: 'android',
}),
});
},
} as HealthCheckInterface;
8 changes: 6 additions & 2 deletions packages/cli-doctor/src/tools/healthchecks/ruby.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import execa from 'execa';
import chalk from 'chalk';

import {logger, findProjectRoot} from '@react-native-community/cli-tools';
import {logger, findProjectRoot, link} from '@react-native-community/cli-tools';

import versionRanges from '../versionRanges';
import {doesSoftwareNeedToBeFixed} from '../checkInstallation';
Expand Down Expand Up @@ -174,7 +174,11 @@ export default {

logManualInstallation({
healthcheck: 'Ruby',
url: 'https://reactnative.dev/docs/environment-setup#ruby',
url: link.docs('environment-setup', {
hash: 'ruby',
guide: 'native',
platform: 'ios',
}),
});
},
} as HealthCheckInterface;
6 changes: 4 additions & 2 deletions packages/cli-doctor/src/tools/installPods.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'fs';
import execa from 'execa';
import chalk from 'chalk';
import {logger, NoopLoader} from '@react-native-community/cli-tools';
import {logger, NoopLoader, link} from '@react-native-community/cli-tools';
import sudo from 'sudo-prompt';
import runBundleInstall from './runBundleInstall';
import {Loader} from '../types';
Expand Down Expand Up @@ -38,7 +38,9 @@ async function runPodInstall(
logger.error(stderr);

throw new Error(
'Looks like your iOS environment is not properly set. Please go to https://reactnative.dev/docs/next/environment-setup and follow the React Native CLI QuickStart guide for macOS and iOS.',
`Looks like your iOS environment is not properly set. Please go to ${link.docs(
'environment-setup',
)} and follow the React Native CLI QuickStart guide for macOS and iOS.`,
);
}
}
Expand Down
6 changes: 4 additions & 2 deletions packages/cli-doctor/src/tools/runBundleInstall.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import execa from 'execa';
import {CLIError, logger} from '@react-native-community/cli-tools';
import {CLIError, logger, link} from '@react-native-community/cli-tools';

import {Loader} from '../types';

Expand All @@ -12,7 +12,9 @@ async function runBundleInstall(loader: Loader) {
loader.fail();
logger.error((error as any).stderr || (error as any).stdout);
throw new CLIError(
'Looks like your iOS environment is not properly set. Please go to https://reactnative.dev/docs/next/environment-setup and follow the React Native CLI QuickStart guide for macOS and iOS.',
`Looks like your iOS environment is not properly set. Please go to ${link.docs(
'environment-setup',
)} and follow the React Native CLI QuickStart guide for macOS and iOS.`,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import tryRunAdbReverse from './tryRunAdbReverse';
import tryLaunchAppOnDevice from './tryLaunchAppOnDevice';
import tryInstallAppOnDevice from './tryInstallAppOnDevice';
import getAdbPath from './getAdbPath';
import {logger, CLIError} from '@react-native-community/cli-tools';
import {logger, CLIError, link} from '@react-native-community/cli-tools';
import {getAndroidProject} from '../../config/getAndroidProject';
import listAndroidDevices from './listAndroidDevices';
import tryLaunchEmulator from './tryLaunchEmulator';
Expand All @@ -38,6 +38,12 @@ export type AndroidProject = NonNullable<Config['project']['android']>;
* Starts the app on a connected Android emulator or device.
*/
async function runAndroid(_argv: Array<string>, config: Config, args: Flags) {
link.setPlatform('android');

if (config.reactNativeVersion !== 'unknown') {
link.setVersion(config.reactNativeVersion);
}

if (args.binaryPath) {
if (args.tasks) {
throw new CLIError(
Expand Down
8 changes: 7 additions & 1 deletion packages/cli-platform-ios/src/commands/runIOS/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import fs from 'fs';
import chalk from 'chalk';
import {Config, IOSProjectInfo} from '@react-native-community/cli-types';
import {getDestinationSimulator} from '../../tools/getDestinationSimulator';
import {logger, CLIError} from '@react-native-community/cli-tools';
import {logger, CLIError, link} from '@react-native-community/cli-tools';
import {BuildFlags, buildProject} from '../buildIOS/buildProject';
import {iosBuildOptions} from '../buildIOS';
import {Device} from '../../types';
Expand All @@ -35,6 +35,12 @@ export interface FlagsT extends BuildFlags {
}

async function runIOS(_: Array<string>, ctx: Config, args: FlagsT) {
link.setPlatform('ios');

if (ctx.reactNativeVersion !== 'unknown') {
link.setVersion(ctx.reactNativeVersion);
}

if (!ctx.project.ios) {
throw new CLIError(
'iOS project folder not found. Are you sure this is a React Native project?',
Expand Down
56 changes: 56 additions & 0 deletions packages/cli-tools/src/__tests__/doclink.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as link from '../doclink';

const mockPlatform = jest.fn().mockReturnValue('darwin');
jest.mock('os', () => ({
platform: mockPlatform,
}));

describe('link', () => {
it('builds a link with the platform and os defined', () => {
mockPlatform.mockReturnValueOnce('darwin');
link.setPlatform('android');

const url = new URL(link.docs('environment-setup')).toString();
expect(url).toMatch(/os=macos/);
expect(url).toMatch(/platform=android/);
expect(url).toEqual(
expect.stringContaining('https://reactnative.dev/docs/environment-setup'),
);

// Handles a change of os
mockPlatform.mockReturnValueOnce('win32');
expect(link.docs('environment-setup')).toMatch(/os=windows/);

// Handles a change of platform
link.setPlatform('ios');
expect(link.docs('environment-setup')).toMatch(/platform=ios/);
});

it('preserves anchor-links', () => {
expect(link.docs('environment-setup', 'ruby')).toMatch(/#ruby/);
});

describe('overrides', () => {
afterAll(() => link.setVersion(null));
it.each([
[{hash: 'ruby'}, /#ruby/],
[{hash: 'ruby', os: 'linux'}, /os=linux/],
[{platform: 'ios'}, /platform=ios/],
[{'extra stuff': 'here?ok'}, /extra\+stuff=here%3Fok/],
])("link.doc('environment-setup, %o) -> %o", (param, re) => {
expect(link.docs('environment-setup', param)).toMatch(re);
});
});

describe('versions', () => {
afterAll(() => link.setVersion(null));
it('supports linking to a specific version of React Native', () => {
link.setVersion('0.71');
expect(link.docs('environment-setup', 'ruby')).toEqual(
expect.stringContaining(
'https://reactnative.dev/docs/0.71/environment-setup',
),
);
});
});
});
Loading

0 comments on commit bde1e1f

Please sign in to comment.