diff --git a/src/Analyser/DependencyHandler.elm b/src/Analyser/DependencyHandler.elm index e4914f66..3318b23b 100644 --- a/src/Analyser/DependencyHandler.elm +++ b/src/Analyser/DependencyHandler.elm @@ -1,4 +1,4 @@ -port module Analyser.DependencyHandler exposing (CacheDependencyRead(..), DependencyPointer, loadDependencyFiles, loadOnlineDocumentation, onLoadDependencyFilesFromDisk, onOnlineDocumentation, onReadFromDisk, readFromDisk, storeToDisk) +port module Analyser.DependencyHandler exposing (CacheDependencyRead(..), DependencyPointer, loadDependencyFiles, loadDocsJson, onDocsLoaded, onLoadDependencyFilesFromDisk, onReadFromDisk, readFromDisk, storeToDisk) import Analyser.FileContext as FileContext import Analyser.Files.FileContent as FileContent exposing (FileContent) @@ -46,7 +46,7 @@ type alias DependencyFiles = } -type alias HttpDocumentationLoad = +type alias DocsJsonLoad = { dependency : DependencyPointer , json : Value } @@ -101,20 +101,15 @@ onReadFromDisk { name, version } = -- Online Docs Ports -port loadHttpDocumentation : DependencyPointer -> Cmd msg +port loadDocsJson : DependencyPointer -> Cmd msg -port onHttpDocumentation : (HttpDocumentationLoad -> msg) -> Sub msg +port onDocsJsonLoaded : (DocsJsonLoad -> msg) -> Sub msg -loadOnlineDocumentation : DependencyPointer -> Cmd msg -loadOnlineDocumentation = - loadHttpDocumentation - - -onOnlineDocumentation : DependencyPointer -> Sub (Maybe (Result JD.Error Dependency)) -onOnlineDocumentation dep = - onHttpDocumentation +onDocsLoaded : DependencyPointer -> Sub (Maybe (Result JD.Error Dependency)) +onDocsLoaded dep = + onDocsJsonLoaded (\{ dependency, json } -> if dependency == dep then JD.decodeValue (JD.list Elm.Docs.decoder) json diff --git a/src/Analyser/Files/DependencyLoader.elm b/src/Analyser/Files/DependencyLoader.elm index 4c7aa0ed..09bf3a4f 100644 --- a/src/Analyser/Files/DependencyLoader.elm +++ b/src/Analyser/Files/DependencyLoader.elm @@ -14,7 +14,7 @@ type alias Model = type State = AwaitingCache - | LoadingOnlineDocs + | LoadingDocs | RawDiskLoading | Failure | Done Dependency @@ -22,7 +22,7 @@ type State type Msg = OnCacheRead CacheDependencyRead - | OnOnlineDocs (Maybe (Result JD.Error Dependency)) + | OnDocsLoaded (Maybe (Result JD.Error Dependency)) | OnLocallyBuildDependency (Maybe (Result String Dependency)) @@ -70,8 +70,8 @@ update msg model = ) Failed -> - ( { model | state = LoadingOnlineDocs } - , DependencyHandler.loadOnlineDocumentation model.dependency + ( { model | state = LoadingDocs } + , DependencyHandler.loadDocsJson model.dependency ) Ignore -> @@ -79,7 +79,7 @@ update msg model = , Cmd.none ) - OnOnlineDocs result -> + OnDocsLoaded result -> case result of Nothing -> ( model, Cmd.none ) @@ -129,9 +129,9 @@ subscriptions model = Done _ -> Sub.none - LoadingOnlineDocs -> - DependencyHandler.onOnlineDocumentation model.dependency - |> Sub.map OnOnlineDocs + LoadingDocs -> + DependencyHandler.onDocsLoaded model.dependency + |> Sub.map OnDocsLoaded RawDiskLoading -> DependencyHandler.onLoadDependencyFilesFromDisk model.dependency diff --git a/ts/domain.ts b/ts/domain.ts index 00eb1e12..a7d2e753 100644 --- a/ts/domain.ts +++ b/ts/domain.ts @@ -16,7 +16,7 @@ export interface DependencyStore { dependency: DependencyPointer; content: string; } -export interface HttpDocumentationLoad { +export interface DocsJsonLoad { dependency: DependencyPointer; json: any; } @@ -63,7 +63,7 @@ interface ElmApp { storeAstForSha: Subscription; storeFile: Subscription; loadFileContentWithSha: Subscription; - loadHttpDocumentation: Subscription; + loadDocsJson: Subscription; storeRawDependency: Subscription; loadRawDependency: Subscription; @@ -76,7 +76,7 @@ interface ElmApp { fileContent: MailBox; onStoredFiles: MailBox; onFileContentWithShas: MailBox; - onHttpDocumentation: MailBox; + onDocsJsonLoaded: MailBox; onRawDependency: MailBox; }; } diff --git a/ts/file-loading-ports.ts b/ts/file-loading-ports.ts index 782d1101..c91690cf 100644 --- a/ts/file-loading-ports.ts +++ b/ts/file-loading-ports.ts @@ -2,7 +2,7 @@ import { ElmApp, Config } from './domain'; import * as DependencyFiles from './ports/dependency-files'; import * as RawDependencies from './ports/raw-dependencies'; -import * as HttpDocumentation from './ports/http-documentation'; +import * as DocsJsonLoader from './ports/docs-json-loader'; import * as FileLoader from './ports/file-loader'; import * as Context from './ports/context'; import { LocalCache } from './util/cache'; @@ -12,7 +12,7 @@ export function setup(app: ElmApp, config: Config, directory: string): void { const localCache = new LocalCache(directory); const fileReader = new FileReader(localCache); - HttpDocumentation.setup(app); + DocsJsonLoader.setup(app, directory); RawDependencies.setup(app); DependencyFiles.setup(app, directory, fileReader); FileLoader.setup(app, config, directory, localCache, fileReader); diff --git a/ts/ports/docs-json-loader.ts b/ts/ports/docs-json-loader.ts new file mode 100644 index 00000000..36c90fc0 --- /dev/null +++ b/ts/ports/docs-json-loader.ts @@ -0,0 +1,49 @@ +import * as request from 'request'; +import * as path from 'path'; +import * as os from 'os'; + +import { ElmApp, DependencyPointer } from '../domain'; + +function loadFromPackageSite({ name, version }: DependencyPointer, cb: (result: any) => void) { + request.get(`http://package.elm-lang.org/packages/${name}/${version}/docs.json`, function( + err: any, + _response: request.Response, + body: string + ) { + if (err) { + cb(null); + } + try { + const parsed = JSON.parse(body); + cb(parsed); + } catch (e) { + cb(null); + } + }); +} + +function loadFromElmHome({ name, version }: DependencyPointer, directory: string) { + const projectElmJson = path.resolve(directory, 'elm.json'); + const elmVersion = require(projectElmJson)['elm-version']; + const elmHome = process.env.ELM_HOME || path.resolve(os.homedir(), '.elm'); + const docsJsonPath = path.resolve(elmHome, elmVersion, 'package', name, version, 'docs.json'); + return require(docsJsonPath); +} + +function setup(app: ElmApp, directory: string) { + app.ports.loadDocsJson.subscribe((pointer: DependencyPointer) => { + const onLoaded = (json: any) => + app.ports.onDocsJsonLoaded.send({ + dependency: pointer, + json + }); + try { + const docs = loadFromElmHome(pointer, directory); + onLoaded(docs); + } catch (e) { + loadFromPackageSite(pointer, onLoaded); + } + }); +} + +export { setup }; diff --git a/ts/ports/http-documentation.ts b/ts/ports/http-documentation.ts deleted file mode 100644 index 072b5976..00000000 --- a/ts/ports/http-documentation.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as request from 'request'; -import { ElmApp, DependencyPointer } from '../domain'; - -function setup(app: ElmApp) { - app.ports.loadHttpDocumentation.subscribe((pointer: DependencyPointer) => { - const { name, version } = pointer; - - request.get(`http://package.elm-lang.org/packages/${name}/${version}/docs.json`, function( - err: any, - _response: request.Response, - body: string - ) { - if (err) { - app.ports.onHttpDocumentation.send({ - dependency: pointer, - json: null - }); - return; - } - try { - const parsed = JSON.parse(body); - app.ports.onHttpDocumentation.send({ - dependency: pointer, - json: parsed - }); - } catch (e) { - app.ports.onHttpDocumentation.send({ - dependency: pointer, - json: null - }); - } - }); - }); -} - -export { setup };