diff --git a/src/install_linux.ts b/src/install_linux.ts index ceed334e..d6762713 100644 --- a/src/install_linux.ts +++ b/src/install_linux.ts @@ -4,7 +4,7 @@ import type { Installed } from './install'; import type { Config } from './config'; import { exec } from './shell'; import { buildVim } from './vim'; -import { downloadNeovim, downloadStableNeovim } from './neovim'; +import { buildNeovim, downloadNeovim, downloadStableNeovim } from './neovim'; async function isUbuntu18OrEarlier(): Promise { const version = await getUbuntuVersion(); @@ -35,7 +35,13 @@ export function install(config: Config): Promise { if (config.version === 'stable') { return downloadStableNeovim('linux', config.token); } else { - return downloadNeovim(config.version, 'linux'); + try { + return downloadNeovim(config.version, 'linux'); + } catch (e) { + const message = e instanceof Error ? e.message : e; + core.debug(`Neovim download failure: ${message}.`); + } + return buildNeovim(config.version, 'linux'); } } else { if (config.version === 'stable') { diff --git a/src/neovim.ts b/src/neovim.ts index 9dffbc93..6f4f475f 100644 --- a/src/neovim.ts +++ b/src/neovim.ts @@ -1,3 +1,4 @@ +import { strict as assert } from 'assert'; import { homedir } from 'os'; import * as path from 'path'; import { promises as fs } from 'fs'; @@ -118,3 +119,46 @@ export async function downloadStableNeovim(os: Os, token: string | null = null): throw err; } } + +export async function buildNeovim(version: string, os: Os): Promise { + assert.equal(version, 'nightly'); + assert.equal(os, 'linux'); + + await exec('sudo', [ + 'apt-get', + 'install', + '-y', + 'ninja-build', + 'gettext', + 'libtool', + 'libtool-bin', + 'autoconf', + 'automake', + 'cmake', + 'g++', + 'pkg-config', + 'unzip', + 'curl', + ]); + + const installDir = path.join(homedir(), 'nvim'); + core.debug(`Building and installing Neovim to ${installDir}.`); + const dir = path.join(await makeTmpdir(), 'neovim'); + + await exec('git', ['clone', '--depth=1', 'https://github.com/neovim/neovim', dir]); + + const opts = { cwd: dir }; + await exec( + 'make', + ['-j', `CMAKE_EXTRA_FLAGS=-DCMAKE_INSTALL_PREFIX=${installDir}`, 'CMAKE_BUILD_TYPE=RelWithDebug'], + opts, + ); + core.debug(`Built Neovim in ${opts.cwd}.`); + await exec('make', ['install'], opts); + core.debug(`Installed Neovim to ${installDir}.`); + + return { + executable: exeName(true, os), + binDir: path.join(installDir, 'bin'), + }; +}