Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow absolute paths #7

Merged
merged 4 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"plugins": [
"@typescript-eslint"
],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"rules": {
"@typescript-eslint/naming-convention": "warn",
"@typescript-eslint/semi": "warn",
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ jobs:
- name: Version Package
run: |
npm version $RELEASE_VERSION
git tag -a $RELEASE_VERSION -m "$RELEASE_VERSION"
- name: Package Extension
run: npm run package -- $RELEASE_VERSION -o "./rover-runner-$RELEASE_VERSION.vsix"
- name: Publish to Visual Studio Marketplace
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This extension requires a `supergraph.json` file at `.rover-runner/supergraph.js
{
"subgraphs": {
"Subgraph1": {
"path": "",
"path": "/Users/name/Desktop/repos/subgraph",
"localUrl": "http://localhost:3000/graphql"
},
"Subgraph2": {
Expand All @@ -40,7 +40,7 @@ This extension requires a `supergraph.json` file at `.rover-runner/supergraph.js
```
Some notes about this format:
- `Subgraph1`, `Subgraph2`, etc are the subgraph names and should match the names in Apollo Studio
- `path` is the relative path to the subgraph from the workspace root. If this is blank like in `Subgraph1`, then you need to run the subgraph on its own
- `path` is the path to the subgraph. It can either be a relative path from the workspace root like in `Subgraph2` or an absolute path like in `Subgraph1`.
- `localUrl` is the graphQL endpoint when running the subgraph locally
- `devUrl` is the graphQL endpoint for the GraphQL variant. This field is optional as the extension will grab the endpoint from Apollo Studio by default

Expand Down
29 changes: 16 additions & 13 deletions src/Subgraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const startup = (
subgraph: Subgraph,
debug: boolean,
context: vscode.ExtensionContext,
shouldRefresh: boolean = true
shouldRefresh = true
) => {
const subgraphStartupFulfilled = (name: string) => {
context.workspaceState.update(name, 'RunningSubgraph');
Expand Down Expand Up @@ -99,7 +99,7 @@ export class Subgraph extends vscode.TreeItem {
// Add auth header if Bearer Token set
const authHeader = vscode.workspace.getConfiguration().get('rover-runner.authorizationHeader', '');
process.env.ROV_TOK = authHeader;
let introspectionQuery = authHeader.length
const introspectionQuery = authHeader.length
? `rover subgraph introspect ${url} --header "Authorization: $ROV_TOK" --output ${this.label}.graphql`
: `rover subgraph introspect ${url} --output ${this.label}.graphql`;
const workspacePath = join(vscode.workspace?.workspaceFolders?.[0]?.uri?.fsPath || '', '.rover-runner/');
Expand All @@ -108,8 +108,10 @@ export class Subgraph extends vscode.TreeItem {
env: process.env,
});
return Promise.resolve('');
} catch (e: any) {
console.log(e?.message);
} catch (err) {
if (err instanceof Error) {
console.log(err?.message);
}
return Promise.reject(`Introspection failed at ${url}. Make sure Auth is up to date`);
}
}
Expand All @@ -124,14 +126,14 @@ export class Subgraph extends vscode.TreeItem {
return Promise.resolve('Path not provided');
} else if (debug) {
this.setLaunchJson();
let folder = vscode.workspace.workspaceFolders?.[0];
const folder = vscode.workspace.workspaceFolders?.[0];
await vscode.debug.startDebugging(folder, this.label, {
suppressDebugToolbar: false,
});
this.contextValue = 'RunningSubgraph';
return Promise.resolve('Launched in debug mode');
} else {
let subgraphTerminal =
const subgraphTerminal =
vscode.window.terminals.find((i) => i.name === this.label) || vscode.window.createTerminal(this.label);
subgraphTerminal.show(true);
subgraphTerminal.sendText(
Expand All @@ -145,7 +147,7 @@ export class Subgraph extends vscode.TreeItem {

public async startRunning(debug: boolean): Promise<string> {
this.contextValue = 'RunningSubgraph';
let roverTerminal =
const roverTerminal =
vscode.window.terminals.find((i) => i.name === `Rover ${this.label}`) ||
vscode.window.createTerminal(`Rover ${this.label}`);
roverTerminal.sendText(`
Expand All @@ -159,7 +161,7 @@ export class Subgraph extends vscode.TreeItem {
await setTimeout(3000);
roverTerminal.show(true);
// Make sure the subgraph is running before trying to run rover
let port: number = parseInt(this.local.split(':')?.[2]?.split('/')?.[0]);
const port: number = parseInt(this.local.split(':')?.[2]?.split('/')?.[0]);
return await detect(port).then((_port: number) => {
// _port is the next available port so if equal then server isn't running
if (port === _port && this.filePath) {
Expand Down Expand Up @@ -209,17 +211,18 @@ export class Subgraph extends vscode.TreeItem {
}

public async stopRunning(): Promise<string> {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve) => {
this.contextValue = 'StoppedSubgraph';
let roverTerminal = vscode.window.terminals.find((i) => i.name === `Rover ${this.label}`);
const roverTerminal = vscode.window.terminals.find((i) => i.name === `Rover ${this.label}`);
if (roverTerminal) {
roverTerminal.sendText('\u0003');
await setTimeout(3000);
roverTerminal.dispose();
}

if (this.current === 'localUrl') {
let subgraphTerminal = vscode.window.terminals.find((i) => i.name === this.label);
const subgraphTerminal = vscode.window.terminals.find((i) => i.name === this.label);
if (subgraphTerminal) {
subgraphTerminal.sendText('\u0003');
await setTimeout(3000);
Expand All @@ -231,8 +234,8 @@ export class Subgraph extends vscode.TreeItem {
}

setLaunchJson = () => {
let fileP: string = vscode.workspace.workspaceFolders?.[0].uri.path + '/.vscode/launch.json';
let launchFile = existsSync(fileP) ? readFileSync(fileP, 'utf-8') : undefined;
const fileP: string = vscode.workspace.workspaceFolders?.[0].uri.path + '/.vscode/launch.json';
const launchFile = existsSync(fileP) ? readFileSync(fileP, 'utf-8') : undefined;
let launchJson = launchFile ? JSON.parse(launchFile) : {};

if (!launchJson || !launchJson?.configurations) {
Expand All @@ -254,7 +257,7 @@ export class Subgraph extends vscode.TreeItem {
type: 'node',
request: 'launch',
name: this.label,
program: '${workspaceRoot}' + `/${this.filePath}/server.js`,
program: `${this.filePath}/server.js`,
skipFiles: ['<node_internals>/**'],
// eslint-disable-next-line @typescript-eslint/naming-convention
env: { NODE_ENV: 'local' },
Expand Down
6 changes: 3 additions & 3 deletions src/SubgraphsProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class SubgraphsProvider implements vscode.TreeDataProvider<Subgraph | Sup
}

private getSupergraphs(configPath: string): Supergraph[] {
const toSupergraph = (supergraphName: string, supergraph: []): Supergraph => {
const toSupergraph = (supergraphName: string): Supergraph => {
// Can either be Stopped or Running
const contextValue = this.context.workspaceState.get(`${supergraphName}Supergraph`, 'StoppedSupergraph');
const newSupergraph = new Supergraph(
Expand All @@ -69,11 +69,11 @@ export class SubgraphsProvider implements vscode.TreeDataProvider<Subgraph | Sup
return newSupergraph;
};
const configJson = JSON.parse(readFileSync(configPath, 'utf-8'));
let supergraphs: Supergraph[] = [toSupergraph('All', [])];
let supergraphs: Supergraph[] = [toSupergraph('All')];
supergraphs = supergraphs.concat(
configJson.supergraphs
? Object.keys(configJson.supergraphs).map((supergraph) =>
toSupergraph(supergraph, configJson.supergraphs[supergraph])
toSupergraph(supergraph)
)
: []
);
Expand Down
10 changes: 5 additions & 5 deletions src/quickPicks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const selectUrl = (rootPath: string, subgraph: Subgraph, context: Extensi
},
];
urlSelector.onDidChangeSelection(() => {
let label = urlSelector.selectedItems[0].label || '';
const label = urlSelector.selectedItems[0].label || '';
if (!label) {
return;
}
Expand All @@ -37,7 +37,7 @@ export const selectUrl = (rootPath: string, subgraph: Subgraph, context: Extensi
urlSelector.dispose();
});
urlSelector.onDidTriggerItemButton((item) => {
let placeHolder = item.item.label === 'Use Local Url' ? subgraph.local : subgraph.dev;
const placeHolder = item.item.label === 'Use Local Url' ? subgraph.local : subgraph.dev;
window
.showInputBox({
ignoreFocusOut: true,
Expand All @@ -49,12 +49,12 @@ export const selectUrl = (rootPath: string, subgraph: Subgraph, context: Extensi
if (!inp) {
return;
}
let filePath = `${rootPath}/.rover-runner/${context.workspaceState.get(
const filePath = `${rootPath}/.rover-runner/${context.workspaceState.get(
'Supergraph Configuration Filename',
'supergraph.json'
)}`;
let supergraphJson = JSON.parse(readFileSync(filePath, 'utf-8'));
let urlKey: string = item.item.label === 'Use Local Url' ? 'localUrl' : 'devUrl';
const supergraphJson = JSON.parse(readFileSync(filePath, 'utf-8'));
const urlKey: string = item.item.label === 'Use Local Url' ? 'localUrl' : 'devUrl';
supergraphJson.subgraphs[subgraph.label][urlKey] = inp;
writeFileSync(filePath, JSON.stringify(supergraphJson, null, 2), 'utf-8');
if (urlKey === 'localUrl') {
Expand Down
4 changes: 2 additions & 2 deletions src/redis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ export const startRedis = () => {
detect(6379).then((_port: number) => {
// _port is the next available port so if equal then server isn't running
if (6379 === _port) {
let redisTerminal =
const redisTerminal =
window.terminals.find((i: { name: string }) => i.name === `Redis`) || window.createTerminal(`Redis`);
redisTerminal.sendText('redis-server');
}
});
};

export const stopRedis = () => {
let redisTerminal = window.terminals.find((i: { name: string }) => i.name === `Redis`);
const redisTerminal = window.terminals.find((i: { name: string }) => i.name === `Redis`);
if (redisTerminal) {
redisTerminal.sendText('\u0003');
redisTerminal.dispose();
Expand Down
36 changes: 29 additions & 7 deletions src/setup.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { commands, window, workspace } from 'vscode';
import { existsSync, mkdirSync, writeFileSync } from 'fs';
import { isAbsolute, join } from 'path';
import axios from 'axios';

export const sampleSupergraphJson = {
subgraphs: {
// eslint-disable-next-line @typescript-eslint/naming-convention
Subgraph1: {
path: '',
path: '/Users/name/Desktop/repos/subgraph',
localUrl: 'http://localhost:3000/graphql',
},
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand Down Expand Up @@ -38,25 +39,36 @@ export const generateTemplate = (rootPath: string) => {
mkdirSync(rootPath + '/.vscode');
}
if (!existsSync(rootPath + '/.rover-runner/supergraph.json')) {
writeFileSync(`${rootPath}/.rover-runner/supergraph.json`, JSON.stringify(sampleSupergraphJson, null, 2), 'utf-8');
writeFileSync(
`${rootPath}/.rover-runner/supergraph.json`,
JSON.stringify(sampleSupergraphJson, null, 2),
'utf-8'
);
commands.executeCommand('subgraphsList.refreshEntry');
}
};

export const isApolloConfigured = () => {
if (
workspace.getConfiguration().get('apolloStudioConfiguration.apolloKey', '').length > 0 &&
workspace.getConfiguration().get('apolloStudioConfiguration.apolloGraphRef', '').length > 0
workspace.getConfiguration().get('apolloStudioConfiguration.apolloKey', '')
.length > 0 &&
workspace
.getConfiguration()
.get('apolloStudioConfiguration.apolloGraphRef', '').length > 0
) {
return true;
}
return false;
};

export const fetchSubgraphUrls = async () => {
let apolloKey = workspace.getConfiguration().get('apolloStudioConfiguration.apolloKey', '');
let graphRef = workspace.getConfiguration().get('apolloStudioConfiguration.apolloGraphRef', '');
let body = {
const apolloKey = workspace
.getConfiguration()
.get('apolloStudioConfiguration.apolloKey', '');
const graphRef = workspace
.getConfiguration()
.get('apolloStudioConfiguration.apolloGraphRef', '');
const body = {
operationName: 'GetSubgraphUrls',
query:
'query GetSubgraphUrls($ref: ID!) { variant(ref: $ref) { ... on GraphVariant { subgraphs { name url }} ... on InvalidRefFormat { message }}}',
Expand Down Expand Up @@ -91,3 +103,13 @@ export const fetchSubgraphUrls = async () => {
return {};
});
};

export const makePathAbsolute = (filePath: string, configPath: string) => {
// If absolute or empty path, then return
if (isAbsolute(filePath) || filePath.length === 0) {
return filePath;
}
// Convert relative path to be absolute
const workspaceRoot = configPath.split('.rover-runner')[0];
return join(workspaceRoot, filePath);
};
18 changes: 10 additions & 8 deletions src/supergraph.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { readFileSync } from 'fs';
import { setTimeout } from 'timers/promises';
import { fetchSubgraphUrls } from './setup';
import { fetchSubgraphUrls, makePathAbsolute } from './setup';
import { ExtensionContext, TreeItem, TreeItemCollapsibleState, window, workspace } from 'vscode';
import { SupergraphYaml, writeSupergraphYaml } from './supergraphYaml';
import { Subgraph } from './Subgraph';
Expand All @@ -23,26 +23,27 @@ export class Supergraph extends TreeItem {

async getChildren(configPath: string, context: ExtensionContext): Promise<Subgraph[]> {
const toSubgraph = (subgraphName: string): Subgraph[] => {
let apolloDevUrl =
const apolloDevUrl =
apolloSubgraphs.data.variant?.subgraphs.find((e: any) => e['name'] === subgraphName)?.url ?? '';
let subgraphConfig = configJson.subgraphs[subgraphName];
const subgraphConfig = configJson.subgraphs[subgraphName];
if (!subgraphConfig) {
window.showErrorMessage(`Subgraph ${subgraphName} in supergraph has no match in the subgraphs list`);
return [];
}
let usedDevUrl = subgraphConfig?.devUrl ?? apolloDevUrl;
const usedDevUrl = subgraphConfig?.devUrl ?? apolloDevUrl;
// Can either be devUrl or localUrl
const current = context.workspaceState.get(subgraphName + 'currentUrl', 'devUrl');
// Can either be Stopped or Running
const contextValue = context.workspaceState.get(subgraphName, 'StoppedSubgraph');
const filePath = makePathAbsolute(subgraphConfig.path, configPath);
return [
new Subgraph(
subgraphName,
current,
subgraphConfig.localUrl,
usedDevUrl,
contextValue,
subgraphConfig.path,
filePath,
TreeItemCollapsibleState.None
),
];
Expand Down Expand Up @@ -105,7 +106,7 @@ export class Supergraph extends TreeItem {
.then(() => writeSupergraphYaml(supergraphYaml))
.then(
() => {
let roverTerminal =
const roverTerminal =
window.terminals.find((i) => i.name === `Rover Runner`) || window.createTerminal(`Rover Runner`);
roverTerminal.show(true);
roverTerminal.sendText(`
Expand All @@ -123,14 +124,15 @@ export class Supergraph extends TreeItem {
}

public stopRunning(context: ExtensionContext): Promise<string> {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve, reject) => {
let roverTerminal = window.terminals.find((i) => i.name === `Rover Runner`);
const roverTerminal = window.terminals.find((i) => i.name === `Rover Runner`);
if (roverTerminal) {
roverTerminal.sendText('\u0003');
await setTimeout(3000);
roverTerminal.dispose();
}
let stopList: any[] = [];
const stopList: Promise<void>[] = [];
// Add subgraphs to a promise all
this.children.forEach((subgraph) => {
if (context.workspaceState.get(subgraph.label) === 'RunningSubgraph') {
Expand Down