【问题标题】:Issues resolving and cleaning output问题解决和清理输出
【发布时间】:2019-11-23 18:51:05
【问题描述】:

我正在开发 https://github.com/cdr/sshcode 的分支,更具体地说,我正在开发 PR 以向程序添加 git4win/msys2 支持

目前问题源于这两个函数

func gitbashWindowsDir(dir string) string {
    if dir == "~" { //Special case
        return "~/"
    }
    mountPoints := gitbashMountPointsAndHome()

    // Apply mount points
    absDir, _ := filepath.Abs(dir)
    absDir = filepath.ToSlash(absDir)
    for _, mp := range mountPoints {
        if strings.HasPrefix(absDir, mp[0]) {
            resolved := strings.Replace(absDir, mp[0], mp[1], 1)
            flog.Info("Resolved windows path '%s' to '%s", dir, resolved)
            return resolved
        }
    }
    return dir
}

// This function returns an array with MINGW64 mount points including relative home dir
func gitbashMountPointsAndHome() [][]string {
    // Initialize mount points with home dir
    mountPoints := [][]string{{filepath.ToSlash(os.Getenv("HOME")), "~"}}
    // Load mount points
    out, err := exec.Command("mount").Output()
    if err != nil {
        log.Fatal(err)
    }
    lines := strings.Split(string(out), "\n")
    var mountRx = regexp.MustCompile(`^(.*) on (.*) type`)
    for _, line := range lines {
        extract := mountRx.FindStringSubmatch(line)
        if len(extract) > 0 {
            mountPoints = append(mountPoints, []string{extract[1], extract[2]})
        }
        res = strings.TrimPrefix(dir, line)
    }
    // Sort by size to get more restrictive mount points first
    sort.Slice(mountPoints, func(i, j int) bool {
        return len(mountPoints[i][0]) > len(mountPoints[j][0])
    })
    return mountPoints
}

这是如何使用的,在 msys2/git4win 上,你给 gitbashWindowsDir("/Workspace") 它应该返回 /Workspace 因为它处理 msys2/git4win 处理路径的非正统方式。

当你给它gitbashWindowsDir("Workspace/") 时,它会返回与echo $PWD/Workspace/ 基本相同的输出,但采用窗口格式

我正在开发一个使用 strings.Prefix 东西的第一步补丁, 到目前为止,这就是我为这个补丁所拥有的东西

package main

import (
    "fmt"
    "os"
)

func main() {
    mydir, err := os.Getwd()
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(os.Getenv("PWD"))
    fmt.Println(mydir)
}

我想检查输入是否有前缀/,如果有,只需将其作为字符串返回,这似乎是gitbashWindowsDir("/Workspace") 返回//Workspace 的简单修复 但我认为最困难的部分是gitbashWindowsDir("Workspace/"),因为它返回与echo $PWD/Workspace/ 相同的输出,但采用Windows 格式(Z:\Workspace\

______________________________________________ ______________________________________________

更新,我已经得到前缀修剪工作,(愚蠢的简单) 但是现在我遇到了这个问题

package main

import (
    "fmt"
    "log"
    "os"
    "os/exec"
    "path/filepath"
    "regexp"
    "sort"
    "strings"

    "go.coder.com/flog"
)

func main() {
    fmt.Println("RESOLVED: ", gitbashWindowsDir(os.Args[1]))
    fmt.Println("RESOLVED: ", gitbashWindowsDir("C:\\msys64\\Workspace"))
}

func gitbashWindowsDir(dir string) string {

    // if dir is left empty, line82:main.go will set it to `~`, this makes it so that
    // if dir is `~`, return `~/` instead of continuing with the gitbashWindowsDir()
    // function.
    if dir == "~" {
        return "~/"
    }

    mountPoints := gitbashMountPointsAndHome()

    // Apply mount points
    absDir, _ := filepath.Abs(dir)
    absDir = filepath.ToSlash(absDir)
    for _, mp := range mountPoints {
        if strings.HasPrefix(absDir, mp[0]) {
            resolved := strings.Replace(absDir, mp[0], mp[1], 1)

            if strings.HasPrefix(resolved, "//") {
                resolved = strings.TrimPrefix(resolved, "/")
                flog.Info("DEBUG: strings.TrimPrefix")
                flog.Info("Resolved windows path '%s' to '%s", dir, resolved)
                flog.Info("'%s'", resolved)
                return resolved
            }

            flog.Info("Resolved windows path '%s' to '%s", dir, resolved)
            return resolved
        }
    }
    return dir
}

// This function returns an array with MINGW64 mount points including relative home dir
func gitbashMountPointsAndHome() [][]string {
    mountPoints := [][]string{{filepath.ToSlash(os.Getenv("HOME")), "~"}}

    // Load mount points
    out, err := exec.Command("mount").Output()
    if err != nil {
        //log.Error(err)
        log.Println(err)
    }
    lines := strings.Split(string(out), "\n")
    var mountRx = regexp.MustCompile(`^(.*) on (.*) type`)
    for _, line := range lines {
        extract := mountRx.FindStringSubmatch(line)
        if len(extract) > 0 {
            mountPoints = append(mountPoints, []string{extract[1], extract[2]})
        }
    }

    // Sort by size to get more restrictive mount points first
    sort.Slice(mountPoints, func(i, j int) bool {
        return len(mountPoints[i][0]) > len(mountPoints[j][0])
    })
    return mountPoints
}

当它运行时,它会返回

merith@DESKTOP-BQUQ80R MINGW64 /z/sshcode
$ go run ../debug.go Workspace
2019-11-27 10:49:38 INFO       Resolved windows path 'Workspace' to '/z/sshcode/Workspace
RESOLVED:  /z/sshcode/Workspace
2019-11-27 10:49:38 INFO       DEBUG: strings.TrimPrefix
2019-11-27 10:49:38 INFO       Resolved windows path 'C:\msys64\Workspace' to '/Workspace
2019-11-27 10:49:38 INFO       '/Workspace'
RESOLVED:  /Workspace

现在我需要弄清楚如何检测和删除/*/ 前缀,以便/z/sshcode/Workspace 变为Workspace/

【问题讨论】:

    标签: windows go msys2


    【解决方案1】:

    对于确定字符串是否以正斜杠为前缀的第一个问题,您可以使用如下函数:

    func ensureSlashPrefix(path string) string {
        return fmt.Sprintf("/%s", strings.Replace(path, "/", "", -1))
    }
    

    对于您的第二个问题,也许我理解错了,但此函数会将绝对路径返回到提供的相对路径或类似的输出到echo $PWD/path

    func cleanWindowsPath(path string) string {
        base := filepath.Base(strings.Replace(path, "\\", "/", -1))
        return ensureSlashPrefix(base)
    }
    

    (Go Playground)

    【讨论】:

    • part1) 看起来它会起作用,现在测试 part2) 有点,对于这个例子,当你提供一个路径作为参数时,我在C:\msys64 安装了 msys2,例如/Workspace msys2 给出去C:\msys2\Workspace,但是由于它被提供了一个在远程linux服务器上打开的Abs路径,它通过从路径中删除安装目录路径来解决这个问题,但问题是它在开头添加了一个额外的/,意思是/Workspace变成//Workspace
    • 哦,我明白了,所以实际上您正在寻找的是在 Windows 绝对路径(如 C:\msys64\Workspace)和您想要 /Workspace 的输出之间的转换?
    • 是的,继续自己测试一下,当您在 msys2 中将 /Workspace 作为 arg 传递时,它会将其读取为路径,并将其“安装目录”打到开头,因此 windows程序可以打开该路径/文件。
    • 我已经编辑了答案,将 Windows 绝对路径转换为/Workspace。另外,我添加了一个有效的 Go Playground 链接。随意在那里玩。我也重新设计了第一个函数,使其更稳定并涵盖更多边缘情况。
    • 很好奇它如何将Z:` part, i see where it fixes and converts \` 删除到/,但不是在哪里删除Z: 编辑:这个问题是,如果我给它路径Z:\\msys64\\Workspace\\Dragon ,它只返回/Dragon play.golang.org/p/TsGGxtwbdR-
    猜你喜欢
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多