UNPKG

literate-elm

Version:

Runs literate Elm code blocks and calculates Elm expressions

151 lines 6.71 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ensureEnvironment = void 0; const fs_extra_1 = require("fs-extra"); const object_hash_1 = __importDefault(require("object-hash")); const path_1 = require("path"); const auxFiles_1 = require("./shared/auxFiles"); const gc_1 = require("./shared/gc"); const tools_1 = require("./shared/tools"); const cacheShapeVersion = "v1"; const cacheDirectorySalt = "v0.19"; const defaultTimeout = 30000; const projectExpiryWithErrors = 1000 * 60; const projectExpiryWithNoElmFound = 1000 * 5; const prepareElmApplication = (directory, dependencies, sourceDirectories) => __awaiter(void 0, void 0, void 0, function* () { // install dependencies yield (0, tools_1.initializeElmProject)(directory); let userRequestsJsonPackage = false; for (const packageName in dependencies) { if (Object.prototype.hasOwnProperty.call(dependencies, packageName)) { const packageVersion = dependencies[packageName]; yield (0, tools_1.installElmPackage)(directory, packageName, packageVersion); if (packageName === "elm/json") { userRequestsJsonPackage = true; } } } if (!userRequestsJsonPackage) { yield (0, tools_1.installElmPackage)(directory, "elm/json", "latest"); } // add sourceDirectories to elm.json yield (0, tools_1.patchElmJson)(directory, (elmJson) => { elmJson["source-directories"] = [...sourceDirectories, "."]; }); }); const resolvePathToMetadata = (workingDirectory) => { return (0, path_1.resolve)(workingDirectory, "literate-elm-metadata.json"); }; const ensureEnvironment = (spec, literateElmDirectory, timeout = defaultTimeout) => __awaiter(void 0, void 0, void 0, function* () { const now = +new Date(); const currentCacheDirectory = (0, path_1.resolve)(literateElmDirectory, cacheShapeVersion); try { yield (0, auxFiles_1.ensureUnlocked)(literateElmDirectory); } catch (e) { // resetting directory lock (garbage collector in another process could get stuck) (0, auxFiles_1.unlock)(literateElmDirectory); } yield (0, gc_1.collectGarbageIfNeeded)(literateElmDirectory); const specDirectory = (0, path_1.resolve)(currentCacheDirectory, `spec${(0, object_hash_1.default)({ spec, CACHE_DIRECTORY_SALT: cacheDirectorySalt })}`); try { yield (0, fs_extra_1.ensureDir)(specDirectory); const specJsonPath = (0, path_1.resolve)(specDirectory, `spec.json`); if (!(yield (0, fs_extra_1.pathExists)(specJsonPath))) { yield (0, fs_extra_1.writeFile)(specJsonPath, JSON.stringify(spec, null, 4), "utf8"); } } catch (e) { return { spec, workingDirectory: specDirectory, metadata: { createdAt: now, status: "error", errorMessage: `Could not create directory ${specDirectory}`, }, }; } // attempt to restore existing environment const currentWorkingDirectoryLocatorPath = (0, path_1.resolve)(specDirectory, "wd"); try { yield (0, auxFiles_1.ensureUnlocked)(specDirectory, timeout); const workingSubdirectory = yield (0, fs_extra_1.readFile)(currentWorkingDirectoryLocatorPath, "utf8"); const workingDirectory = (0, path_1.resolve)(specDirectory, workingSubdirectory); const metadata = JSON.parse(yield (0, fs_extra_1.readFile)(resolvePathToMetadata(workingDirectory), "utf8")); if (metadata.expiresAt && metadata.expiresAt < now) { throw new Error("Expired"); } return { metadata, spec, workingDirectory, }; } catch (e) { // } try { yield (0, auxFiles_1.lock)(specDirectory); const workingSubdirectory = `wd${now}`; const workingDirectory = (0, path_1.resolve)(specDirectory, workingSubdirectory); yield (0, fs_extra_1.ensureDir)(workingDirectory); let metadata; try { yield prepareElmApplication(workingDirectory, spec.dependencies, spec.sourceDirectories); metadata = { status: "ready", createdAt: now, }; } catch (e) { yield (0, auxFiles_1.touch)((0, path_1.resolve)(workingDirectory, "ProgramFORGC")); const isElmFound = `${e.message}`.indexOf("ENOENT") === -1 && `${e.message}`.indexOf("No elm global binary available") === -1; metadata = { status: "error", createdAt: now, expiresAt: now + (isElmFound ? projectExpiryWithErrors : projectExpiryWithNoElmFound), errorMessage: isElmFound ? e.message : 'I am having trouble finding Elm on your machine. Is it installed? Check by opening a terminal window and typing "elm --version" (without quotation marks). If you have recently installed Elm, try restarting your machine.', }; } yield (0, fs_extra_1.writeFile)(resolvePathToMetadata(workingDirectory), JSON.stringify(metadata, null, 2), "utf8"); yield (0, fs_extra_1.writeFile)(currentWorkingDirectoryLocatorPath, workingSubdirectory, "utf8"); return { spec, workingDirectory, metadata, }; } catch (e) { return { spec, workingDirectory: specDirectory, metadata: { createdAt: now, status: "error", errorMessage: e.message, }, }; } finally { yield (0, auxFiles_1.unlock)(specDirectory); } }); exports.ensureEnvironment = ensureEnvironment; //# sourceMappingURL=ensureEnvironment.js.map