Open source the Sandbox plugin
Summary: This diff is mainly moving diffs around to open source the Sandbox plugin. I created the MD file writing some docs. The rest is just making our own FB implementation work Reviewed By: danielbuechele Differential Revision: D8731839 fbshipit-source-id: 27ac67223c6de9d1be406ab8c06b71b82d5407bc
This commit is contained in:
committed by
Facebook Github Bot
parent
03a8e696a9
commit
53753801b0
71
android/plugins/sandbox/SandboxSonarPlugin.java
Normal file
71
android/plugins/sandbox/SandboxSonarPlugin.java
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the LICENSE
|
||||||
|
* file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.facebook.sonar.plugins.sandbox;
|
||||||
|
|
||||||
|
import com.facebook.sonar.core.SonarArray;
|
||||||
|
import com.facebook.sonar.core.SonarConnection;
|
||||||
|
import com.facebook.sonar.core.SonarObject;
|
||||||
|
import com.facebook.sonar.core.SonarPlugin;
|
||||||
|
import com.facebook.sonar.core.SonarReceiver;
|
||||||
|
import com.facebook.sonar.core.SonarResponder;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SandboxSonarPlugin implements SonarPlugin {
|
||||||
|
public static final String ID = "Sandbox";
|
||||||
|
|
||||||
|
private static final String SET_METHOD_NAME = "setSandbox";
|
||||||
|
private static final String GET_METHOD_NAME = "getSandbox";
|
||||||
|
|
||||||
|
private final SandboxSonarPluginStrategy mStrategy;
|
||||||
|
|
||||||
|
public SandboxSonarPlugin(SandboxSonarPluginStrategy strategy) {
|
||||||
|
mStrategy = strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnect(SonarConnection connection) {
|
||||||
|
connection.receive(
|
||||||
|
GET_METHOD_NAME,
|
||||||
|
new SonarReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(SonarObject params, final SonarResponder responder) {
|
||||||
|
final SonarArray.Builder sandboxes = new SonarArray.Builder();
|
||||||
|
Map<String, String> knownSandboxes = mStrategy.getKnownSandboxes();
|
||||||
|
if (knownSandboxes == null) {
|
||||||
|
responder.success(sandboxes.build());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String sandboxName : knownSandboxes.keySet()) {
|
||||||
|
sandboxes.put(
|
||||||
|
new SonarObject.Builder()
|
||||||
|
.put("name", sandboxName)
|
||||||
|
.put("value", knownSandboxes.get(sandboxName)));
|
||||||
|
}
|
||||||
|
responder.success(sandboxes.build());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connection.receive(
|
||||||
|
SET_METHOD_NAME,
|
||||||
|
new SonarReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(SonarObject params, SonarResponder responder) throws Exception {
|
||||||
|
String sandbox = params.getString("sandbox");
|
||||||
|
mStrategy.setSandbox(sandbox);
|
||||||
|
responder.success(new SonarObject.Builder().put("result", true).build());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect() {}
|
||||||
|
}
|
||||||
19
android/plugins/sandbox/SandboxSonarPluginStrategy.java
Normal file
19
android/plugins/sandbox/SandboxSonarPluginStrategy.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the LICENSE
|
||||||
|
* file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.facebook.sonar.plugins.sandbox;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public interface SandboxSonarPluginStrategy {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Map<String, String> getKnownSandboxes();
|
||||||
|
|
||||||
|
void setSandbox(@Nullable String sandbox);
|
||||||
|
}
|
||||||
25
docs/sandbox-plugin.md
Normal file
25
docs/sandbox-plugin.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
id: sandbox-plugin
|
||||||
|
title: Sandbox
|
||||||
|
---
|
||||||
|
|
||||||
|
The Sandbox plugin is useful for developers that had to test changes of their apps by pointing them to some Sandbox environment. Through this plugin and a few lines of code in the client,
|
||||||
|
the app can get a callback and get the value that the user has input through Sonar. At this point, the developer can plugin its logic to save this setting in its app.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
To use the sandbox plugin, you need to add the plugin to your Sonar client instance.
|
||||||
|
|
||||||
|
### Android
|
||||||
|
|
||||||
|
```java
|
||||||
|
import com.facebook.sonar.plugins.SandboxSonarPlugin;
|
||||||
|
import com.facebook.sonar.plugins.SandboxSonarPluginStrategy;
|
||||||
|
|
||||||
|
final SandboxSonarPluginStrategy strategy = getStrategy(); // Your strategy goes here
|
||||||
|
client.addPlugin(new SandboxSonarPlugin(strategy));
|
||||||
|
```
|
||||||
|
|
||||||
|
### iOS
|
||||||
|
|
||||||
|
Coming soon
|
||||||
144
src/plugins/sandbox/index.js
Normal file
144
src/plugins/sandbox/index.js
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018-present Facebook.
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {SonarPlugin} from 'sonar';
|
||||||
|
import {FlexColumn} from 'sonar';
|
||||||
|
import {ButtonGroup, Button, styled, colors} from 'sonar';
|
||||||
|
|
||||||
|
export type Sandbox = {
|
||||||
|
name: string,
|
||||||
|
value: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
type SandboxState = {|
|
||||||
|
sandboxes: Array<Sandbox>,
|
||||||
|
customSandbox: string,
|
||||||
|
showFeedback: boolean,
|
||||||
|
|};
|
||||||
|
|
||||||
|
const BigButton = Button.extends({
|
||||||
|
flexGrow: 1,
|
||||||
|
fontSize: 24,
|
||||||
|
padding: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
const ButtonContainer = FlexColumn.extends({
|
||||||
|
alignItems: 'center',
|
||||||
|
padding: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default class SandboxView extends SonarPlugin<SandboxState> {
|
||||||
|
state = {
|
||||||
|
sandboxes: [],
|
||||||
|
customSandbox: '',
|
||||||
|
showFeedback: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
static title = 'Sandbox';
|
||||||
|
static id = 'Sandbox';
|
||||||
|
static icon = 'translate';
|
||||||
|
|
||||||
|
static TextInput = styled.textInput({
|
||||||
|
border: `1px solid ${colors.light10}`,
|
||||||
|
fontSize: '1em',
|
||||||
|
padding: '0 5px',
|
||||||
|
borderRight: 0,
|
||||||
|
borderTopLeftRadius: 4,
|
||||||
|
borderBottomLeftRadius: 4,
|
||||||
|
flexGrow: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
static FeedbackMessage = styled.text({
|
||||||
|
fontSize: '1.2em',
|
||||||
|
paddingTop: '10px',
|
||||||
|
color: 'green',
|
||||||
|
});
|
||||||
|
|
||||||
|
static TextInputLayout = FlexColumn.extends({
|
||||||
|
float: 'left',
|
||||||
|
justifyContent: 'center',
|
||||||
|
flexGrow: 1,
|
||||||
|
borderRadius: 4,
|
||||||
|
marginRight: 15,
|
||||||
|
marginTop: 15,
|
||||||
|
marginLeft: 15,
|
||||||
|
});
|
||||||
|
|
||||||
|
reducers = {
|
||||||
|
UpdateSandboxes(state: SandboxState, results: Object) {
|
||||||
|
return {
|
||||||
|
sandboxes: results.results,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.client.call('getSandbox', {}).then((results: Array<Sandbox>) => {
|
||||||
|
this.dispatchAction({results, type: 'UpdateSandboxes'});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSendSandboxEnvironment = (sandbox: string) => {
|
||||||
|
this.client
|
||||||
|
.call('setSandbox', {
|
||||||
|
sandbox: sandbox,
|
||||||
|
})
|
||||||
|
.then((result: Object) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setState({showFeedback: false});
|
||||||
|
}, 3000);
|
||||||
|
this.setState({showFeedback: result.result});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onChangeSandbox = (e: SyntheticInputEvent<>) => {
|
||||||
|
this.setState({customSandbox: e.target.value});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<FlexColumn>
|
||||||
|
<SandboxView.TextInputLayout>
|
||||||
|
<ButtonGroup flexGrow={1}>
|
||||||
|
<SandboxView.TextInput
|
||||||
|
type="text"
|
||||||
|
placeholder="Sandbox URL (e.g. unixname.sb.facebook.com)"
|
||||||
|
key="sandbox-url"
|
||||||
|
onChange={this.onChangeSandbox}
|
||||||
|
onKeyPress={event => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
this.onSendSandboxEnvironment(this.state.customSandbox);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
key="sandbox-send"
|
||||||
|
icon="download"
|
||||||
|
onClick={() =>
|
||||||
|
this.onSendSandboxEnvironment(this.state.customSandbox)
|
||||||
|
}
|
||||||
|
disabled={this.state.customSandbox == null}
|
||||||
|
/>
|
||||||
|
</ButtonGroup>
|
||||||
|
<SandboxView.FeedbackMessage
|
||||||
|
hidden={this.state.showFeedback == false}>
|
||||||
|
Success!
|
||||||
|
</SandboxView.FeedbackMessage>
|
||||||
|
</SandboxView.TextInputLayout>
|
||||||
|
{this.state.sandboxes.map(sandbox => (
|
||||||
|
<ButtonContainer>
|
||||||
|
<BigButton
|
||||||
|
key={sandbox.value}
|
||||||
|
onClick={() => this.onSendSandboxEnvironment(sandbox.value)}>
|
||||||
|
{sandbox.name}
|
||||||
|
</BigButton>
|
||||||
|
</ButtonContainer>
|
||||||
|
))}
|
||||||
|
</FlexColumn>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/plugins/sandbox/package.json
Normal file
7
src/plugins/sandbox/package.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "sonar-plugin-sandbox",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"license": "MIT",
|
||||||
|
"gatekeeper": "sonar_sandbox_plugin"
|
||||||
|
}
|
||||||
4
src/plugins/sandbox/yarn.lock
Normal file
4
src/plugins/sandbox/yarn.lock
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
{
|
{
|
||||||
"docs": {
|
"docs": {
|
||||||
"Using Sonar": ["getting-started", "understand", "stetho"],
|
"Using Sonar": ["getting-started", "understand", "stetho"],
|
||||||
"Built-in Plugins": ["logs-plugin", "layout-plugin", "network-plugin"],
|
"Built-in Plugins": [
|
||||||
|
"logs-plugin",
|
||||||
|
"layout-plugin",
|
||||||
|
"network-plugin",
|
||||||
|
"sandbox-plugin"
|
||||||
|
],
|
||||||
"Plugins: Desktop part": [
|
"Plugins: Desktop part": [
|
||||||
"js-setup",
|
"js-setup",
|
||||||
"communicating",
|
"communicating",
|
||||||
|
|||||||
Reference in New Issue
Block a user