Skip to content
This repository was archived by the owner on Mar 10, 2022. It is now read-only.

Commit 1cd752d

Browse files
committed
fix: miscellaneous fixes
- Use nodejs `https` module instead of shelling out to `src api` - Display GitHub stars next to notebook results - Make `didFocus()` for the tree view cancelable
1 parent 17d4ca9 commit 1cd752d

6 files changed

Lines changed: 81 additions & 39 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"viewsWelcome": [
7272
{
7373
"view": "sourcegraph.commands",
74-
"contents": "[New Search Notebook](command:extension.newNotebook)\n[Go to File](command:extension.goToFile)\n[Go to Repository](command:extension.goToRepository)"
74+
"contents": "[New Search Notebook](command:extension.newNotebook)\n[Go to Repository](command:extension.goToRepository)\n[Go to File](command:extension.goToFile)"
7575
},
7676
{
7777
"view": "sourcegraph.files",

src/file-system/SourcegraphTreeDataProvider.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export class SourcegraphTreeDataProvider implements vscode.TreeDataProvider<stri
1313
private isExpandedNode = new Set<string>()
1414
private treeView: vscode.TreeView<string> | undefined
1515
private activeUri: vscode.Uri | undefined
16+
private didFocusToken = new vscode.CancellationTokenSource()
1617
private readonly didChangeTreeData = new vscode.EventEmitter<string | undefined>()
1718
public readonly onDidChangeTreeData: vscode.Event<string | undefined> = this.didChangeTreeData.event
1819

@@ -65,11 +66,13 @@ export class SourcegraphTreeDataProvider implements vscode.TreeDataProvider<stri
6566
}
6667

6768
public async didFocus(vscodeUri: vscode.Uri | undefined): Promise<void> {
69+
this.didFocusToken.cancel()
70+
this.didFocusToken = new vscode.CancellationTokenSource()
6871
this.activeUri = vscodeUri
6972
if (vscodeUri && vscodeUri.scheme === 'sourcegraph' && this.treeView && this.isTreeViewVisible) {
7073
const uri = this.fs.sourcegraphUri(vscodeUri)
7174
await this.fs.downloadFiles(uri, uri.revision || '')
72-
await this.didFocusString(uri, true)
75+
await this.didFocusString(uri, true, this.didFocusToken.token)
7376
}
7477
}
7578

@@ -101,12 +104,19 @@ export class SourcegraphTreeDataProvider implements vscode.TreeDataProvider<stri
101104
}
102105
}
103106

104-
private async didFocusString(uri: SourcegraphUri, isDestinationNode: boolean): Promise<void> {
107+
private async didFocusString(
108+
uri: SourcegraphUri,
109+
isDestinationNode: boolean,
110+
token: vscode.CancellationToken
111+
): Promise<void> {
105112
try {
106113
if (this.treeView) {
107114
const parent = uri.parentUri()
108115
if (parent && !this.isExpandedNode.has(parent)) {
109-
await this.didFocusString(SourcegraphUri.parse(parent), false)
116+
await this.didFocusString(SourcegraphUri.parse(parent), false, token)
117+
}
118+
if (token.isCancellationRequested) {
119+
return
110120
}
111121
await this.treeView.reveal(uri.uri, {
112122
focus: true,

src/queries/graphqlQuery.ts

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,65 @@
1-
import { spawn } from 'child_process'
1+
import { request, RequestOptions } from 'https'
22
import { CancellationToken } from 'vscode'
33
import { log } from '../log'
44
import { debugEnabledSetting } from '../settings/debugEnabledSetting'
5+
import { endpointHostnameSetting } from '../settings/endpointSetting'
56

67
export function graphqlQuery<A, B>(query: string, variables: A, token: CancellationToken): Promise<B | undefined> {
78
return new Promise<B | undefined>((resolve, reject) => {
8-
const stdoutBuffer: string[] = []
9-
const onExit = (exit: number) => {
10-
if (exit === 0) {
11-
const json = stdoutBuffer.join('')
12-
try {
13-
const parsed: B = JSON.parse(json)
14-
resolve(parsed) // wrap in promise because this method will be async in the future
15-
} catch (error) {
16-
reject(error)
9+
const data = JSON.stringify({
10+
query,
11+
variables,
12+
})
13+
const accessToken = process.env.SRC_ACCESS_TOKEN || ''
14+
const options: RequestOptions = {
15+
hostname: endpointHostnameSetting(),
16+
port: 443,
17+
path: '/.api/graphql',
18+
method: 'POST',
19+
headers: {
20+
Authorization: `token ${accessToken}`,
21+
'Content-Length': data.length,
22+
},
23+
}
24+
const req = request(options, res => {
25+
const body: Uint8Array[] = []
26+
res.on('data', json => {
27+
body.push(json)
28+
})
29+
res.on('error', reject)
30+
const onClose = () => {
31+
if (res.statusCode === 200) {
32+
try {
33+
const json = Buffer.concat(body).toString()
34+
const parsed: B = JSON.parse(json)
35+
resolve(parsed)
36+
} catch (error) {
37+
log.error(`graphql(${data})`, error)
38+
reject(error)
39+
}
40+
} else {
41+
log.error(`graphql(${data}), statusCode=${res.statusCode}`, body)
42+
reject(body.join(''))
1743
}
18-
} else {
19-
reject({ exit })
2044
}
21-
}
22-
const onData = (chunk: string) => {
23-
stdoutBuffer.push(chunk)
24-
}
25-
const command: string[] = [
26-
'api',
27-
'-query',
28-
query.trim().replace(/\n/g, ' ').replace(/ +/g, ' '),
29-
'-vars',
30-
JSON.stringify(variables),
31-
]
45+
res.on('close', onClose)
46+
res.on('end', onClose)
47+
})
48+
req.on('error', reject)
49+
req.write(data)
50+
req.end()
3251
if (debugEnabledSetting()) {
52+
const command: string[] = [
53+
'api',
54+
'-query',
55+
query.trim().replace(/\n/g, ' ').replace(/ +/g, ' '),
56+
'-vars',
57+
JSON.stringify(variables),
58+
]
3359
log.appendLine('src ' + command.map(part => `'${part}'`).join(' '))
3460
}
35-
const proc = spawn('src', command)
36-
proc.stdout.on('data', onData)
37-
proc.on('close', onExit)
38-
proc.on('disconnect', onExit)
39-
proc.on('error', onExit)
40-
proc.on('exit', onExit)
4161
token.onCancellationRequested(() => {
42-
if (!proc.killed) {
43-
proc.kill()
44-
reject()
45-
}
62+
req.destroy()
4663
})
4764
})
4865
}

src/queries/repositoryMetadataQuery.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export async function repositoryMetadataQuery(
1616
): Promise<RepositoryMetadata> {
1717
const response = await graphqlQuery<RevisionParameters, RevisionResult>(
1818
gql`
19-
query Revision($repositoryName: String!) {
19+
query RepositoryMetadata($repositoryName: String!) {
2020
repositoryRedirect(name: $repositoryName) {
2121
... on Repository {
2222
id

src/queries/searchQuery.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ export function searchQueryResult(
2929
file {
3030
url
3131
}
32+
repository {
33+
stars
34+
}
3235
lineMatches {
3336
lineNumber
3437
offsetAndLengths
@@ -90,6 +93,9 @@ interface SearchResultNode {
9093
file?: {
9194
url?: string
9295
}
96+
repository?: {
97+
stars?: number
98+
}
9399
lineMatches?: LineMatch[]
94100
}
95101

src/search/searchHtml.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export async function searchHtml(
1616
if (!url) {
1717
continue
1818
}
19+
const starCount = node?.repository?.stars
20+
const stars = starCount ? ` ⭐ ${formatStarCount(starCount)}` : ''
1921
const lineMatches = node.lineMatches || []
2022
if (lineMatches.length === 0) {
2123
continue
@@ -55,7 +57,7 @@ export async function searchHtml(
5557
if (first) {
5658
first = false
5759
html.push('<p>')
58-
html.push(`<code>${url}</code>`)
60+
html.push(`<code>${url}${stars}</code>`)
5961
html.push('<pre>')
6062
}
6163
const uri = `sourcegraph://${host}${url}?L${line + 1}:${character}`
@@ -73,6 +75,13 @@ export async function searchHtml(
7375
return html.join('')
7476
}
7577

78+
function formatStarCount(starCount: number): string {
79+
if (starCount > 1000) {
80+
return `${Math.round(starCount / 1000)}k`
81+
}
82+
return starCount.toLocaleString()
83+
}
84+
7685
// FIXME: this method is copy pasted from Stackoverflow and should be replaced with a proper implementation
7786
// https://stackoverflow.com/a/6234804
7887
export function escapeHtml(unescapedHtml: string): string {

0 commit comments

Comments
 (0)