vlang / v-analyzer

The @vlang language server, for all your editing needs like go-to-definition, code completion, type hints, and more.
MIT License
86 stars 9 forks source link

build.vsh not working if V path contains spaces #82

Closed nixpare closed 3 months ago

nixpare commented 3 months ago

Describe the bug

When trying to build v-analyzer from source, the build process fails because the V executable is under "C:\Program Files\V.bin\v.exe", which contains a space

Expected Behavior

The compile process should start as expected

Current Behavior

I get the following error:

[ERROR] Failed to build v-analyzer
"C:\Program" is not recognized as an internal or external command,
 operable program or batch file.

Reproduction Steps

Have V installed in a path that contains at least one space and build from source

Possible Solution

Change the build.vsh file to use the os.Process struct and not os.execute_opt function. This is a working build.vsh file that i used to build it without changing my configuration:

#!/usr/bin/env -S v

// This script is used to build the v-analyzer binary.
// Usage:
//  v build.vsh [debug|dev|release]
// By default, just `v build.vsh` will use debug mode.
import os
import cli
import term
import time
import src.metadata

const bin_path = os.abs_path('./bin/v-analyzer') + $if windows { '.exe' } $else { '' }
const build_commit = os.execute('git rev-parse --short HEAD').output.trim_space()
const build_datetime = time.now().format_ss()

enum ReleaseMode {
    release
    debug
    dev
}

fn errorln(msg string) {
    eprintln('${term.red('[ERROR]')} ${msg}')
}

fn (m ReleaseMode) compile_cmd() os.Process {
    mut p := os.Process{
        filename: @VEXE,
        args: [@VMODROOT, '-o', bin_path, '-no-parallel']
    }

    if cc := os.getenv_opt('CC') {
        p.args << ['-cc',  cc]
    } else {
        $if windows {
            // TCC cannot build tree-sitter on Windows.
            p.args << ['-cc', 'gcc']
        } // Else let `-prod` toggle the appropriate production compiler.
    }

    $if cross_compile_macos_arm64 ? {
        p.args << ['-cflags',  '-target arm64-apple-darwin']
    } $else $if linux {
        if m == .release { p.args << ['-cflags', '-static'] }
    }

    libbacktrace := $if windows { []string{} } $else { ['-d', 'use_libbacktrace'] }
    match m {
        .release { p.args << '-prod' }
        .debug { p.args << '-g'; p.args << libbacktrace }
        .dev { p.args << ['-d', 'show_ast_on_hover', '-g']; p.args << libbacktrace }
    }

    return p
}

fn prepare_output_dir() {
    if os.exists('./bin') {
        return
    }
    os.mkdir('./bin') or { errorln('Failed to create output directory: ${err}') }
}

fn build(mode ReleaseMode, explicit_debug bool) {
    println('Building v-analyzer at commit: ${build_commit}, build time: ${build_datetime} ...')

    prepare_output_dir()
    println('${term.green('✓')} Prepared output directory')

    mut p := mode.compile_cmd()
    defer { p.close() }
    println('Building v-analyzer in ${term.bold(mode.str())} mode, using: ${p.filename} ${p.args.join(' ')}')
    if mode == .release {
        println('This may take a while...')
    }

    if !explicit_debug && mode == .debug {
        println('To build in ${term.bold('release')} mode, run ${term.bold('v build.vsh release')}')
        println('Release mode is recommended for production use. At runtime, it is about 30-40% faster than debug mode.')
    }

    p.run()
    p.wait()

    if p.code != 0 {
        errorln('Failed to build v-analyzer')
        exit(p.code)
    }

    println('${term.green('✓')} Successfully built v-analyzer!')
    println('Binary is located at ${term.bold(abs_path(bin_path))}')
}

// main program:

os.setenv('BUILD_DATETIME', build_datetime, true)
os.setenv('BUILD_COMMIT', build_commit, true)

mut cmd := cli.Command{
    name: 'v-analyzer-builder'
    version: metadata.manifest.version
    description: 'Builds the v-analyzer binary.'
    posix_mode: true
    execute: fn (_ cli.Command) ! {
        build(.debug, false)
    }
}

// debug builds the v-analyzer binary in debug mode.
// This is the default mode.
// Thanks to -d use_libbacktrace, the binary will print beautiful stack traces,
// which is very useful for debugging.
cmd.add_command(cli.Command{
    name: 'debug'
    description: 'Builds the v-analyzer binary in debug mode.'
    execute: fn (_ cli.Command) ! {
        build(.debug, true)
    }
})

// dev builds the v-analyzer binary in development mode.
// In this mode, additional development features are enabled.
cmd.add_command(cli.Command{
    name: 'dev'
    description: 'Builds the v-analyzer binary in development mode.'
    execute: fn (_ cli.Command) ! {
        build(.dev, false)
    }
})

// release builds the v-analyzer binary in release mode.
// This is the recommended mode for production use.
// It is about 30-40% faster than debug mode.
cmd.add_command(cli.Command{
    name: 'release'
    description: 'Builds the v-analyzer binary in release mode.'
    execute: fn (_ cli.Command) ! {
        build(.release, false)
    }
})

cmd.parse(os.args)

Additional Information/Context

No response

Environment details (v doctor output)

V full version: V 0.4.5 d5370bd.55cafa9 OS: windows, Microsoft Windows 11 Pro v22631 64-bit Processor: 12 cpus, 64bit, little endian,

getwd: C:\Users\aless.config\v-analyzer vexe: C:\Program Files\V\v.exe vexe mtime: 2024-04-03 15:20:20

vroot: contains spaces, value: C:\Program Files\V VMODULES: OK, value: C:\Users\aless.vmodules VTMP: OK, value: C:\Users\aless\AppData\Local\Temp\v_0

Git version: git version 2.44.0.windows.1 Git vroot status: weekly.2024.14-8-g55cafa9b .git/config present: true

CC version: cc (Rev5, Built by MSYS2 project) 13.2.0 thirdparty/tcc status: thirdparty-windows-amd64 b99a453d-dirty

Editor name

VSCode

v-analyzer Version

v-analyzer version 0.0.4-beta.1.95869fa

VS Code Extension Version

No response