-
-
Notifications
You must be signed in to change notification settings - Fork 276
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for non repo root Haskell projects. (#463)
In my use case we keep several Haskell projects in one repository (monorepo approach). This PR extends search to modules relative to Haskell project root (not git root). It is detected by cutting current path on `src`, `lib`, `app`, or `test`. Also adds navigation in test suites.
- Loading branch information
Showing
8 changed files
with
124 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,34 @@ | ||
import assert from 'assert'; | ||
import githubSearch from '@octolinker/resolver-github-search'; | ||
import { hoogleSearch } from '@octolinker/resolver-hoogle-search'; | ||
import Haskell from '../index'; | ||
|
||
describe('haskell', () => { | ||
const path = '/user/repo/blob/d6/lib/plugins/javascript.js'; | ||
const target = 'Foo.Bar'; | ||
it('resolves links - top level project', () => { | ||
const path = '/user/repo/blob/v0.1/src/Main.hs'; | ||
const target = 'Foo.Bar'; | ||
|
||
it('resolves links', () => { | ||
assert.deepEqual(Haskell.resolve(path, [target]), [ | ||
'{BASE_URL}/user/repo/blob/master/src/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/master/lib/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/master/Foo/Bar.hs', | ||
githubSearch({ path, target }).toString(), | ||
'https://hackage.haskell.org/package/base/docs/Foo-Bar.html', | ||
'{BASE_URL}/user/repo/blob/v0.1/src/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/v0.1/lib/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/v0.1/app/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/v0.1/test/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/v0.1/Foo/Bar.hs', | ||
hoogleSearch({ target }).toString(), | ||
]); | ||
}); | ||
|
||
it('resolves links - monorepo project', () => { | ||
const path = | ||
'/user/repo/blob/v0.1/projects/project-in-monorepo/src/Main.hs'; | ||
const target = 'Foo.Bar'; | ||
|
||
assert.deepEqual(Haskell.resolve(path, [target]), [ | ||
'{BASE_URL}/user/repo/blob/v0.1/projects/project-in-monorepo/src/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/v0.1/projects/project-in-monorepo/lib/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/v0.1/projects/project-in-monorepo/app/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/v0.1/projects/project-in-monorepo/test/Foo/Bar.hs', | ||
'{BASE_URL}/user/repo/blob/v0.1/projects/project-in-monorepo/Foo/Bar.hs', | ||
hoogleSearch({ target }).toString(), | ||
]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import assert from 'assert'; | ||
import { hoogleSearch } from '../index'; | ||
|
||
describe('hoogle-search', () => { | ||
const target = 'Data.Typeable'; | ||
let response; | ||
beforeAll(() => { | ||
global.fetch = jest.fn().mockImplementation(() => | ||
Promise.resolve({ | ||
json() { | ||
return response; | ||
}, | ||
}), | ||
); | ||
}); | ||
|
||
it('returns a function', () => { | ||
assert.deepEqual(typeof hoogleSearch({ target }), 'function'); | ||
}); | ||
|
||
it('calls the hoogle search api', () => { | ||
hoogleSearch({ target })(); | ||
|
||
expect(global.fetch).toBeCalledWith( | ||
'https://hoogle.haskell.org/?hoogle=Data.Typeable%20is:module%20is:exact&mode=json', | ||
); | ||
}); | ||
|
||
it('returns url', async () => { | ||
response = [ | ||
{ | ||
url: | ||
'https://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Typeable.html', | ||
}, | ||
]; | ||
|
||
expect(await hoogleSearch({ target })()).toBe( | ||
'https://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Typeable.html', | ||
); | ||
}); | ||
|
||
it('returns null when no results', async () => { | ||
response = []; | ||
|
||
expect(await hoogleSearch({ target })()).toBe(null); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
function handleResponse(hoogleSearchUrl, target, response) { | ||
const checkExact = function(item) { | ||
return item.url.includes(`docs/${target.replace(/\./g, '-')}.html`); | ||
}; | ||
|
||
if (response.length > 0) { | ||
// Multiple packages may provide the same module (see Crypto.MAC.HMAC) | ||
// We redirect to doc if there is only exact match | ||
// Otherwise, we redirect to hoogle search to avoid confucion | ||
const exactMatches = response.filter(checkExact); | ||
if (exactMatches.length === 1) { | ||
return exactMatches[0].url; | ||
} | ||
return hoogleSearchUrl; | ||
} | ||
return null; | ||
} | ||
|
||
export function hoogleSearch({ target }) { | ||
const query = `${encodeURIComponent(target)}%20is:module%20is:exact`; | ||
const hoogleSearchUrl = `https://hoogle.haskell.org/?hoogle=${query}&mode=json`; | ||
|
||
return async function doHoogleSearch() { | ||
const response = await fetch(hoogleSearchUrl); | ||
const json = await response.json(); | ||
|
||
return handleResponse(hoogleSearchUrl, target, json); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "@octolinker/resolver-hoogle-search", | ||
"version": "1.0.0", | ||
"description": "", | ||
"repository": "https://github.com/octolinker/octolinker/tree/master/packages/resolver-hoogle-search", | ||
"license": "MIT", | ||
"main": "./index.js", | ||
"dependencies": { | ||
"@octolinker/helper-settings": "1.0.0" | ||
} | ||
} |