国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

絕版-打造composer離線倉庫

Ace華

應(yīng)用場景

本腳本適用于無互聯(lián)網(wǎng)環(huán)境,若你的開發(fā)環(huán)境有互聯(lián)網(wǎng),可以退出了。
情景:之前通過互聯(lián)網(wǎng)離線導(dǎo)入了一個項目A,已經(jīng)安裝好全部依賴了,比如 webman/admin依賴。但在離線環(huán)境下,我又想在新的項目B中也安裝webman/admin,通過這個腳本,你可以輕松做到,腳本代碼會在最后全部貼出。

本工具的作用就是將之前已經(jīng)安裝好依賴的composer項目中的依賴提取出來,放到指定目錄下,供其他目錄離線安裝使用

注意,一定要有其他項目已經(jīng)安裝好依賴的,也就是說,目錄下一定要有 composer.lock和vendor目錄

思路

因為無互聯(lián)網(wǎng),無法使用composer require來安裝需要的包,之前的項目下載的包在vendor目錄下是沒有version信息的,但版本信息保存在了 composer.lock 文件中。
所以,本腳本的目標(biāo)就是,將 composer.lock文件中的版本信息提取出來,寫入每個包的composer.json文件中,并且通過下面命令,將每一個包都壓縮成zip文件。

composer archive --format=zip --dir=$dest

打成zip后,就可以搭配上在composer.json中配置離線倉庫就可以使用這些zip的包。

一個包打成zip格式之前,如果json文件中沒有版本信息的話,在使用離線安裝的時候不能做到像有互聯(lián)網(wǎng)那樣遞歸安裝依賴所依賴的其他依賴。

操作使用

總體就是先提取其他項目的依賴,到指定目錄,新項目需要安裝依賴時,可以直接使用composer require XX 來安裝包,方便快捷

1.腳本源碼

將以下代碼復(fù)制保存到php文件,這里叫 generate_repositories.php

<?php

main(); // 執(zhí)行main()方法

function main()
{
    // 因為倉庫是離線的,composer.json 中沒有帶version信息,需要根據(jù)composer.lock中提取版本信息,寫到每個包的composer.json中去,再執(zhí)行 composer archive 操作
    // 將每個庫打包成zip包放到zips目錄下
    // 會將composer.lock目錄下的vendor包全部拷貝到目標(biāo)目錄下再進(jìn)行修改composer.json,源目錄下的composer.json文件保持不變

    $lock_file = "D:/4.PHP/Code/wfdemo/composer.lock"; // 修改為已安裝好依賴項目根目錄下的composer.lock絕對路徑,注意\要改為/
    $zip_dest_dir = "D:/4.PHP/Code/wfdemo_repos";// 修改為離線倉庫目錄,再次運行舊的不會清空
    run($lock_file, $zip_dest_dir);
}

// 讀取文件內(nèi)容
function read_file($file)
{
    return !is_file($file) ? '' : @file_get_contents($file);
}

// 遞歸創(chuàng)建文件夾
function mk_dirs($path, int $mode = 0777)
{
    if (!is_dir(dirname($path))) {
        mk_dirs(dirname($path));
    }

    if (!file_exists($path)) {
        return mkdir($path, $mode);
    }

    return true;
}
// 寫文件
function write_file($file, $content)
{
    $dir = dirname($file);
    if (!is_dir($dir)) {
        mk_dirs($dir);
    }
    return @file_put_contents($file, $content);
}
// 目錄拷貝
function copy_dir(string $source, string $dest, bool $overwrite = false)
{
    if (is_dir($source)) {
        if (!is_dir($dest)) {
            mkdir($dest);
        }
        $files = scandir($source);
        foreach ($files as $file) {
            if ($file !== "." && $file !== "..") {
                copy_dir("$source/$file", "$dest/$file", $overwrite);
            }
        }
    } else if (file_exists($source) && ($overwrite || !file_exists($dest))) {
        copy($source, $dest);
    }
}
//  刪除目錄
function remove_dir(string $dir)
{
    if (is_link($dir) || is_file($dir)) {
        return unlink($dir);
    }
    $files = array_diff(scandir($dir), array('.', '..'));
    foreach ($files as $file) {
        (is_dir("$dir/$file") && !is_link($dir)) ? remove_dir("$dir/$file") : unlink("$dir/$file");
    }
    return rmdir($dir);
}

/**
 * @param string $lock_file composer.lock文件絕對地址
 * @param string $zip_dest_dir zip文件目標(biāo)目錄,沒有會自動生成
 * @return void
 */
function run(string $lock_file, string $zip_dest_dir)
{
    $src = dirname($lock_file) . "/vendor";
    $json_content = json_decode(read_file($lock_file), true);
    $packages = $json_content["packages"];
    foreach ($packages as $package) {
        $name = $package["name"];
        $version = $package["version"];
        $target_dir = $zip_dest_dir . "/vendor-temp/$name"; // 在目標(biāo)文件夾下創(chuàng)建vendor-temp緩存目錄
        mk_dirs($target_dir);

        echo "start -- package name is $name,version is $version \n";
        $filenames = glob("$src/$name/composer.json");
        foreach ($filenames as $filename) {
            if (is_file($filename)) {
                $lib_src_dir = dirname($filename);
                copy_dir($lib_src_dir, $target_dir, true);
                $filename = "$target_dir/composer.json";
                writeOneVersion($filename, $version);
                archiveOne($filename, $zip_dest_dir);
            }
        }
        echo "end -- package name is $name,version is $version \n\n";
        // break;
    }

    chdir($zip_dest_dir); // 必須切換當(dāng)前目錄,否則remove_dir刪除不了
    remove_dir($zip_dest_dir . "/vendor-temp"); // 全部結(jié)束后,刪除vendor-temp目錄
}

/**
 * 給一個composer.json文件寫入版本信息
 * @param string $filename
 * @param string $version
 * @return void
 */
function writeOneVersion(string $filename, string $version)
{
    $obj = json_decode(read_file($filename));
    $obj->version = $version;

    $str = json_encode($obj, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
    write_file($filename, $str);
}

/**
 * 打包一個包到目標(biāo)目錄
 * @param string $filename 包目錄的composer.json
 * @param string $dest 目標(biāo)目錄
 * @return void
 */
function archiveOne(string $filename, string $dest)
{
    $dir = dirname($filename);
    chdir($dir);
    echo "current dir is " . getcwd() . "\n";
    passthru("composer archive --format=zip --dir=$dest");
}

2.生成離線倉庫

  • 添加composer 到環(huán)境變量中

  • 修改 php 文件中的main方法的參數(shù)地址

  • 其中,$lock_file 是 composer.lock文件絕對地址,用于提取包的版本信息

  • $zip_dest_dir 是存放離線zip文件的目錄

    修改完后運行php

php generate_repositories.php

生成的zip目錄中,vendor-temp目錄是臨時用于寫入版本信息的,每次生成都會被同一個包的不同版本重新覆蓋,只有zip目錄下的包才是不重復(fù)的,因為生成時會區(qū)分版本信息。

3.其他項目使用

其他項目修改 composer.json文件,需要配置離線倉庫目錄,
composer.json 離線配置參考,重點是 repositories 配置

{
  "minimum-stability": "dev",
  "require": {
    "php": ">=8.0",
    "workerman/webman-framework": "^1.5.0",
    "monolog/monolog": "^2.0",
    "ext-pdo": "*",
    "webman/admin": "^0.6.24",
    "webman/console": "^1.3"
  },
  "repositories": [
    {
      "packagist.org": false
    },
    {
      "type": "artifact",
      "url": "D:/3PHP/repos/zips/"
    }
  ]
}

"packagist.org": false 關(guān)閉去互聯(lián)網(wǎng)請求
下面就是配置剛才生成的zip包目錄地址

然后,就可以使用正常的
composer require webman/admin
來安裝依賴了

常見故障

生成zip包失敗

如果遇到某些包沒有不成功的,就是剛才生成zip時,沒有生成成功,大概是因為那個包的composer.json文件寫的不規(guī)范,導(dǎo)致 composer
archive 不成功
可以查看輸出時報紅的信息,current package name is 這個包后面的就是當(dāng)前錯誤的包,然后手動去這個包目錄下執(zhí)行

composer archive --format=zip

就會提示錯誤信息,對應(yīng)修改 composer.json 文件即可,生成后,手動復(fù)制到 zip目標(biāo)目錄下。

598 2 1
2個評論

釋永戰(zhàn)

不錯的思路,學(xué)習(xí)一下

  • 暫無評論
軟飯工程師

我之前也有這樣的場景,是在有網(wǎng)環(huán)境把擴(kuò)展安裝好,然后帶進(jìn)無網(wǎng)環(huán)境,替換composer.lock 文件和vendor 目錄下

  • Ace華 2025-05-07

    你這樣,每個項目都要重新拷貝整個項目目錄,無法做到項目之間的依賴重復(fù)使用。而且,后期開發(fā)要新增依賴時,又要重新拷貝整個依賴項目。

Ace華

830
積分
0
獲贊數(shù)
0
粉絲數(shù)
2023-02-14 加入
??