<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[xlings: 跨平台一键安装功能设计与思考 - 多编程环境搭建、工具软件安装、项目依赖管理]]></title><description><![CDATA[<p dir="auto">在前段时间开源了一个开发者命令行工具<a href="https://github.com/d2learn/xlings" rel="nofollow ugc">xlings</a>, 收到了一些关注和反馈, 并且最近也对其中的<strong>一键安装功能</strong>做了进步增强。希望不仅可以帮助初学者快速的搭建编程环境, 也能用于<strong>项目开发者来管理复杂项目的开发环境依赖和一键搭建配置支持</strong></p>
<p dir="auto">下面就从 <strong>最小功能实现、递归依赖安装、项目依赖管理</strong>循序渐进的介绍一下这个功能的设计和思考</p>
<p dir="auto"><img src="/assets/uploads/files/1732634270059-e39f59bf-5006-4ee1-8d34-8f36104417f2-image.png" alt="e39f59bf-5006-4ee1-8d34-8f36104417f2-image.png" class=" img-fluid img-markdown" /></p>
<blockquote>
<p dir="auto">注:  这个软件和功能目前依然处于比较前期的探索和开发中</p>
</blockquote>
<h2>一、最小功能实现 - 接口规范</h2>
<h3>1.1 接口设计视角</h3>
<p dir="auto">对于安装一个软件或编程环境大概可以划分成3个步骤: <strong>下载 - 安装 - 配置</strong></p>
<p dir="auto"><img src="/assets/uploads/files/1732634323896-95355e31-b6bd-4402-9253-cdf3a9094bae-image.png" alt="95355e31-b6bd-4402-9253-cdf3a9094bae-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">并且为了避免重复安装和显示软件的信息, 用top-down的思想，大概核心的接口设计如下:</p>
<pre><code class="language-lua">function support()
-- ...
end

function installed()
-- ...
end

function install()
-- ...
end

function config()
-- ...
end

function info()
-- ...
end
</code></pre>
<p dir="auto">其中support接口用来标识当前系统是否支持, info接口是用于获取软件的基础信息</p>
<pre><code class="language-lua">function support()
    return {
        windows = true,
        linux = true,
        macosx = false
    }
end

function info()
    return {
        name     = "vscode",
        homepage = "https://code.visualstudio.com",
        author   = "https://github.com/microsoft/vscode/graphs/contributors",
        licenses = "MIT",
        github   = "https://github.com/microsoft/vscode",
        docs     = "https://code.visualstudio.com/docs",
        profile  = "Visual Studio Code",
    }
end
</code></pre>
<h3>1.2 接口实现视角</h3>
<p dir="auto">从对于单一软件或环境接口实现视角来看, 有点类似很多项目中的一键安装/配置脚本</p>
<p dir="auto">但区别是xlings的安装实现上是<strong>符合一个接口规范</strong>的, 这样才能<strong>为后面的复用提供可能性</strong>。并且使用者可以不用关心实现细节, 通过标准接口就可以使用对应的模块。</p>
<pre><code class="language-lua">function installed()
    return try {
        function()
            if os.host() == "windows" and (os.getenv("USERNAME") or ""):lower() == "administrator" then
                return os.isfile("C:\\Program Files\\Microsoft VS Code\\Code.exe")
            else
                -- os.exec("code --version") - windows cmd not support?
                common.xlings_exec("code --version") -- for windows
            end
            return true
        end, catch {
            function(e)
                return false
            end
        }
    }
end

function install()
    print("[xlings]: Installing vscode...")

    local url = vscode_url[os.host()]
    -- only windows administrator
    local use_winget_sys = (os.getenv("USERNAME") or ""):lower() == "administrator"

    if not os.isfile(vscode_file) and not use_winget_sys then
        common.xlings_download(url, vscode_file)
    end

    return try {
        function ()
            if os.host() == "windows" then
                print("[xlings]: runninng vscode installer, it may take some minutes...")
                if use_winget_sys then
                    os.exec("winget install vscode --scope machine")
                else
                    common.xlings_exec(vscode_file .. " /verysilent /suppressmsgboxes /mergetasks=!runcode")
                end
            elseif os.host() == "linux" then
                os.exec("sudo dpkg -i " .. vscode_file)
            elseif os.host() == "macosx" then
                -- TODO: install vscode on macosx
            end

            return true
        end, catch {
            function (e)
                os.tryrm(vscode_file)
                return false
            end
        }
    }
end
</code></pre>
<h2>二、递归安装依赖 - 复用&amp;依赖图</h2>
<p dir="auto">通过上面的接口规范化后, 实现软件依赖的自动递归安装和复用就相对简单了。只需要再增加一个用于描述依赖的接口</p>
<pre><code class="language-lua">function deps() -- pnpm
    return {
        windows = {
            "npm"
        },
        linux = {
            "npm"
        },
        macosx = {
            "npm" 
        }
    }
end
</code></pre>
<p dir="auto">以pnpm的实现为例, 只需要通过依赖描述添加npm, 而不需要关心npm是否安装。当执行pnpm安装的时候会自动的递归检查依赖并安装。从单个软件的依赖链来看像一个不严谨的树形结构, 如果绘制所有软件和依赖会是一个依赖图, 并且节点是可以复用的 -- <strong>软件安装复用</strong></p>
<p dir="auto"><img src="/assets/uploads/files/1732634285394-294e3f7e-3dd6-42a8-b75b-e87a27688abf-image.png" alt="294e3f7e-3dd6-42a8-b75b-e87a27688abf-image.png" class=" img-fluid img-markdown" /></p>
<h2>三、项目依赖管理 - 快速搭建项目开发环境</h2>
<p dir="auto">很多人在拿到一个不怎么熟悉的项目的时候, 往往要成功的去构建或运行这个项目要花不少时间去解决这个软件或库的依赖问题。所以xlings有了基础软件的安装功能, 就自然而然的想到当把一个项目从github上clone下来的时候能不能通过一行命令就自动配置好开发这个项目所需要的环境</p>
<p dir="auto">在有上面的基础后, 就可以通过一个简单的依赖描述文件来描述一个项目依赖。xlings只需要通过加载这个依赖文件, 然后通过解析出依赖项, 按照递归的方式逐个安装，就可以实现一键配置好一个项目的开发环境。</p>
<p dir="auto"><strong>config.xlings配置文件示例</strong></p>
<pre><code class="language-lua">xname = "ProjectName"
xdeps = {
    rust = "",
    python = "3.12",
    vs = "2022",
    nodejs = "",
    vscode = "",
    ...
    -- postprocess cmds
    xppcmds = {
        "cmd1",
        "cmd2",
    }
}
</code></pre>
<p dir="auto">在配置文件中<strong>通过xdeps来描述项目的直接依赖</strong>, 并且可以通过其中的xppcmds项来自定义安装项目依赖后的后处理命令</p>
<h2>四、统一的软件版本管理</h2>
<p dir="auto">目前xlings的下一步是期望能实现基于场景记忆的版本管理。例如当在一个特定的项目文件夹下 会使用不同的软件版本, 只不过这个还在规划中...</p>
<h2>Other</h2>
<ul>
<li><a href="https://forum.d2learn.org/category/9/xlings" rel="nofollow ugc">xlings论坛</a></li>
<li><a href="https://github.com/d2learn/xlings" rel="nofollow ugc">xlings开源仓库</a></li>
</ul>
]]></description><link>http://forum.d2learn.org/topic/48/xlings-跨平台一键安装功能设计与思考-多编程环境搭建-工具软件安装-项目依赖管理</link><generator>RSS for Node</generator><lastBuildDate>Wed, 12 Aug 2026 02:22:23 GMT</lastBuildDate><atom:link href="http://forum.d2learn.org/topic/48.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 26 Nov 2024 15:19:40 GMT</pubDate><ttl>60</ttl></channel></rss>