satis搭建composer包仓库

本文主要包含几个部分

  • Composer仓库讲述
  • 为什么要搭建私有的Composer仓库
  • 如何开发composer包
  • satis搭建私有仓库
  • satis的UI界面重构思路
  • 参考文档

一、Composer仓库

  • Composer

    Composer是 PHP 用来管理依赖(dependency)关系的工具。你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer 会帮你安装这些依赖的库文件

  • Composer仓库

    Composer仓库是用来管理以及存储php拓展包的一个集合。如packagist.org.

  • php拓展包的形式
    • php底层语言编写的:一般使用pecl安装或采取源码安装方式。
    • php编写的:一般可通过pear安装 或 Composer安装 或 手动引入
    • 典型的例子:phpredis 与 predis

二、为什么要搭建私有的Composer仓库

  • 首先列举几个很熟悉的场景

    • 在项目当中不可避免的会用到一些常见的函数,比如说一个获取客户端ip的代码。一般开发会选择去百度、谷歌,然后一顿ctrl c + v ...接着就拷贝到各个项目当中,跑起来能用,ok没问题。但是过了一段时间,咦,原来这段代码有一个bug。A项目改一下、B项目也改一下,C项目忘记改了...
    • 在公司内部的项目里,我们经常会发现多个项目之间会存在一些公用的模块。如,公司内部有多个C端,但是都有一个统一的数据接口模块。那么多个项目之间都会写重复调用这个模块接口的代码。我们可以在A项目中写了,拷贝到B、C....,但此时如果数据模块接口发生了变化,那就...
    • 公司项目之间,前后端业务层甚至模型层,重复的代码很多,但是用的框架都是一样的...
    • ...
  • 上面说了这几个场景,在实际的开发工作当中很常见,总结来说存在以下几个问题:

    • 代码质量角度:常用的函数,重用的模块代码,大家习惯了拷贝,代码质量很自然的少关注
    • 开发效率角度:项目之间应用了重复的代码,拷贝接入效率低 或者 根本就不知道其他项目中有存在的轮子
    • 维护成本角度:重复的代码使用,假如出现了bug或者需要迭代以适应新的需求,需要在一个个项目中调整 甚至还可能出现忘记的情况
    • 开源角度:在工作当中,我们所开发的很多东西是不方便开源的

ps:其实上面说了那么多,最迫切需要搭建私有仓库的是最后一点...

  • 针对上述的问题有几个初步方案:
    • 在packagist上发布包:开源不符合,私有需要付费
    • 直接composer.json中通过声明内部vcs的 respository:符合,但管理不方便,查找不方便
    • 搭建一个私有的Composer仓库:符合,需要花点时间搭建维护
      • toran proxy:不开源,有便捷操作的UI界面
      • satis:开源,有UI界面,但是不是很方便操作,需要美化一下

PS:pear包同样也是php的包,但是已过时了,composer正值壮年。

三、如何开发composer包

上面讲了很多为什么要模块化、为什么要做composer包、为什么要搭建私有composer仓库,那么接下来我们首先看下怎么做一个自己的composer包以及回顾一下有哪些知识。

1.composer.json中一些常用的参数

  • name
    • 包名,一般包含两部分[vendor/name]。“/”前面代码发行的一个单位或大板块,后面的是包名字
  • type
    • 包的类型
      • libray:拓展库,默认类型,最常用的(安装完默认会在root包中vendor目录下,什么是root包下面再说)
      • project:项目,比如说laravel等一些框架提供了一些出事话项目的命令 composer create-project ...(此时发包就是定义这种类型,安装完就是一个root包)
      • metapackage:当一个空的包,包含依赖并且需要触发依赖的安装,这将不会对系统写入额外的文件。因此这种安装类型并不需要一个 dist 或 source(官方说明)
      • composer-plugin:一个安装类型为 composer-plugin 的包,它有一个自定义安装类型,可以为其它包提供一个 installler。详细请查看 自定义安装类型(官方说明)
  • description
    • 包的描述,告诉别人这个包用来干嘛的
  • license
    • 包的许可协议
  • authors
    • 发行机构(个人)信息
  • repositories
    • 自定义资源库(默认情况下,composer会按照顺序进行资源查找,最后才检测默认的资源库)
      • type:资源库类型
        • path:本地资源包(支持绝对路劲、相对路径)
        • vcs:git、svn等版本控制的资源包
        • composer:composer资源镜像仓库下的资源包,如https://mirrors.aliyun.com/composer/、packagist.org
        • package
  • require
    • 项目必须安装的依赖包
  • require-dev
    • 项目开发或测试环境下需要安装的依赖包
  • autoload
    • 自动加载映射定义,支持四种类型映射定义(在开发包时,可直接通过修改autoload配置进行包的引入进行调试)
      • psr-0:支持psr-4命名空间到目录的映射、精确到文件的映射
      • psr-4:支持psr-4命名空间到目录的映射、精确到文件的映射
      • classmap:支持指定路径的文件映射扫描,也支持精确到文件
      • files:指定加载文件,一般用于函数库加载
  • autoload-dev:
    • 测试环境下使用的自动加载映射定义,同上支持四种类型映射定义
  • scripts
    • 自定义脚本(仅root包中运作。在composer运行的生命周期当中触发的一些钩子脚本,跟git上面hook是一个道理。详细的可到官方文档中去查)
  • config
    • 配置项(composer的一些局部配置项,常用的比如composer config secure-http false)
  • extra
    • 额外的一些配置参数(配合scripts中使用)

2.composer的常用命令

  • composer install

    • 说明:安装包依赖以及自动加载映射相关文件。存在composer.lock文件的情况下,此命令会按照composer.lock中锁定的依赖包版本号等信息直接安装,否则即按照composer.json中声明的一来信息进行安装
    • 常用可选参数
      • --no-dev:忽略composer.json下声明的require-dev包
      • --dev:安装composer.json下声明的包
      • --optimize-autoloader:将psr0/psr4规范下的自动加载转化为classmap的方式
      • --no-scripts:跳过 composer.json 文件中定义的脚本
    • 应用场景
      • 一般用于项目初始化
  • composer update

    • 说明:根据composer.json文件中的声明进行项目依赖更新、自动加载映射。
    • 常用可选参数
      • --no-dev:忽略composer.json下声明的require-dev包
      • --dev:安装composer.json下声明的包
      • --optimize-autoloader:将psr0/psr4规范下的自动加载转化为classmap的方式
      • --no-scripts:跳过 composer.json 文件中定义的脚本
    • 应用场景
      • 特定的依赖包需要更新。==请谨慎直接使用composer update,这会导致所有依赖包升级至依赖的最高版本,可能会对项目造成不可预估的损害==
  • composer require package_name[:version]:

    • 说明:安装新包
    • 常用可选参数:
      • --dev: 安装 require-dev 字段中列出的包。
      • --no-update: 禁用依赖关系的自动更新(在确保项目能运作的情况下,可使用此命令)
    • 应用场景:
      • 引入新包
  • composer dumpautoload:

    • 说明:重新生成各依赖包的自动加载映射文件
    • 常用可选参数:
      • --optimize (-o): 转换 PSR-0/4 autoloading 到 classmap 获得更快的载入速度。这特别适用于生产环境,但可能需要一些时间来运行,因此它目前不是默认设置。
      • --no-dev: 禁用 autoload-dev 规则。
  • 常用的全局参数

    • -v:表示正常输出
    • -vv:表示更详细的输出
    • -vvv:debug级别的信息(一般装包时候,卡住了,不知道什么原因,可以加上此命令看看)
//来个示例说明一下
{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=7.0.0",
        "barryvdh/laravel-debugbar": "^3.2",
        "bkqw_tech/ucenter": "^2.0",
        "encore/laravel-admin": "^1.6",
        "fideloper/proxy": "~3.3",
        "intervention/image": "^2.4",
        "jacobcyl/ali-oss-storage": "^2.1",
        "laravel/framework": "5.5.*",
        "laravel/tinker": "~1.0",
        "maatwebsite/excel": "~2.1.0",
        "mrgoon/aliyun-sms": "dev-master",
        "overtrue/laravel-wechat": "^4.0",
        "predis/predis": "^1.1",
        "simplesoftwareio/simple-qrcode": "^2.0",
        "topthink/think-helper": "^1.0"
    },
    "require-dev": {
        "filp/whoops": "~2.0",
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "~1.0",
        "phpunit/phpunit": "~6.0",
        "symfony/thanks": "^1.0"
    },
    "autoload": {
        "files": [
            "app/Support/Helpers/common.php"
        ],
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "extra": {
        "laravel": {
            "dont-discover": [
            ]
        }
    },
    "scripts": {
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate"
        ],
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover"
        ]
    },
    "config": {
        "preferred-install": "dist",
        "sort-packages": true,
        "optimize-autoloader": true,
        "secure-http": false
    },
    "repositories": {
        "ucenter": {
            "type": "composer",
            "url": "http://10.1.11.88:7075/"
        }
    }
}


ps:大家可以了解一下vendor目录下composer文件夹的大概结构,大概了解一下composer的原理。知道原理能让我们做起来更加得心应手。

3.初始化composer包

  • 命令行初始化
image
  • 手动创建composer.json文件
    {
        "name": "adam/composertest",
        "description": "这是一个测试包",
        "type": "library",
        "authors": [
            {
                "name": "Adam",
                "email": "[email protected]"
            }
        ],
        "require": {}
    }
    
    

包的结构就不用多说了,只要符合几种composer的自动加载机制就可以了,没什么特别限制

4.发布包

这里说一下在packagist上发布一个包,下面再说搭自己的私有仓库
1.先把自己的项目发布到vcs的一个托管平台,如github,gitee
2.注册一个packagist账号
3.进入https://packagist.org,点击submit,提交,完事

就这么简单,关于包的版本管理,可以拓展研究一下

5.安装包

直接composer require :dev-master。这里说下composer安装包的几种方式声明

(1).本地安装声明

{
    "name": "adam/project",
    "description": "这是一个测试包",
    "type": "project",
    "authors": [{
        "name": "Adam",
        "email": "[email protected]"
    }],
    "require": {},
    "repositories": {
        "composertest": {
            "type": "path",
            "url": "packages1/composertest"//相对路径或绝对路径
        }
    }
}

(2).vcs安装声明

{
    "name": "adam/project",
    "description": "这是一个测试项目",
    "type": "project",
    "authors": [{
        "name": "Adam",
        "email": "[email protected]"
    }],
    "require": {},
    "repositories": {
        "easywechat": {
            "type": "vcs",//vcs、git、svn
            "url": "https://github.com/w7corp/easywechat.git"//远程版本仓库地址
        }
    }
}

(3).composer安装声明

{
    "name": "adam/project",
    "description": "这是一个测试项目",
    "type": "project",
    "authors": [{
        "name": "Adam",
        "email": "[email protected]"
    }],
    "require": {},
    "repositories": {
        "easywechat": {
            "type": "composer",
            "url": "https://packagist.org/"//composer仓库地址
        }
    }
}

(4).其他安装方式声明

{
    "name": "adam/project",
    "description": "这是一个测试项目",
    "type": "project",
    "authors": [{
        "name": "Adam",
        "email": "[email protected]"
    }],
    "require": {},
    "repositories": {
        "easywechat": {
            "type": "composer",
            "url": "https://packagist.org/"//composer仓库地址
        }
    }
}

四、satis搭建私有仓库

1.安装satis

  • git安装:git clone https://github.com/composer/satis.git
  • composer安装:composer create-project composer/satis --stability=dev

2.配置公钥

如果将要引入的依赖包是一个私有vcs项目,请务必进行配置。如果你引入的包都是公有项目可以跳过此步骤(参考配置文档:https://gitee.com/help/articles/4181)。

ssh-keygen -t rsa -C "[email protected]"  
# Generating public/private rsa key pair...

cat ~/.ssh/rsa_id.pub
# 将公钥复制到你的托管平台ssh公钥设置里面

3.初始化satis

  • 在项目根目录运行 php bin/build init
    • 根据提示输入自己的仓库名以及原地址首页(后续再webpage上可以看到安装包的json展示的即homepage地址)
    {
        "name": "adam's composer repository",
        "homepage": "http://composer.cc",
        "repositories": [],
        "require-all": true
    }

4.构建satis UI界面

(1) 构建:
  • 方式一:

    • 修改satis.json文件
    {
        "name": "adam",
        "homepage": "https://adamoba.com",
        "repositories": [
            { "type": "vcs", "url": "http://10.1.11.88:8024/bkqw_tech/ucenter.git" }
        ],
        "require-all":true,
        "config":{
            "secure-http":false
        }
    }
    
    • 运行构建命令
    php bin/satis build --repository-url http://10.1.11.88:8024/bkqw_tech/ucenter.git satis.json ./web
    
  • 方式二:

    • 修改satis.json文件
    {
        "name": "adam",
        "homepage": "https://adamoba.com",
        "repositories": [
            { "type": "vcs", "url": "http://10.1.11.88:8024/bkqw_tech/ucenter.git" }
        ],
        "require":{
            "bkqw_tech/ucenter":"*"
        },
        "config":{
            "secure-http":false
        }
    }
    
    • 运行构建命令
    php bin/satis build --repository-url http://10.1.11.88:8024/bkqw_tech/ucenter.git satis.json ./web
    

    如果源中包含了http协议,需增加secure-http为false的配置项

    说明:

    • 如果直接build,不加入repository-url或者不修改require-all参数的情况下,satis会扫描所有的respositories(包括composer的默认源,不清楚原因),会导致构建非常非常慢
    • 如果加入了repository-url的情况下,satis只会扫描指定的vcs地址
(2)配置一个php运行环境,运行时目录指向到web目录下(示例域名:http://composer.cc)
(3) 访问:http://composer.cc,看到如下界面,即成功
image

4.发布包到satis

(1)修改配置文件:
  • 命令行
    php bin/satis add http://10.1.11.88:8024/bkqw_tech2/ucenter2.git
    
  • 编辑配置文件:
    {
    "name": "adam",
    "homepage": "https://adamoba.com",
    "repositories": [
        { "type": "vcs", "url": "http://10.1.11.88:8024/bkqw_tech/ucenter.git" },
        { "type": "vcs", "url": "http://10.1.11.88:8024/bkqw_tech2/ucenter2.git" }
    ],
    "require-all":all
    "config":{
        "secure-http":false
    }
}
(2) 构建
  • 命令行 php bin/satis build --repository-url http://10.1.11.88:8024/bkqw_tech2/ucenter2.git satis.json ./web
  • 访问:http://composer.cc

6.在项目中引入satis的包

//这一段即http://composer.cc种,add repositories那一段展开json
{
  "repositories": [{
    "type": "composer",
    "url": "https://composer.cc"
  }]
}

//或通过命令行进行局部配置 composer config repositories.ucenter composer https://adamoba.com

{
    "repositories": {
        "ucenter":{
            "type": "composer",
            "url": "http://composer.cc"
        }
    }
}
// 因为此处repository的里面的包基本都是http协议,所以外加如一行
{
    "config":{
        "secure-http":false
    }
}
// 或通过命令行 composer conifg secure-http false
// 接着composer require xxx 
//(如果项目没有打上标签,composer require package_name:dev-master)

关于satis命令如何使用,直接在运行php bin/satis 就可以查看到相关的说明了。

image

五、satis改造:可视化操作添加源

如果公司内部成员都会发布一些包到这个satis站点里面,让大家都去熟悉satis可能不那么理想。那接下来就通过对satis项目的进行一些调整,以达到可视化操作添加源的目的(如packagist.com中,只需要贴入地址就可以,提交一个源到其中过了)

  • 思路
    • 打开satis目录下的views文件夹,找到index.html.twig(这个是satis首页的模板)
    • 增加前端页面:
      • 每一个包的item增加删除按钮、更新按钮
      • 增加发布新包页面(为了便捷,我拷贝了一下packagis.com的页面)
    • 增加后端处理脚本:
      • 删除包:通过php的exec函数调用 “php bin/satis purge xxxx”,再php调用satis build
      • 更新包:通过php的exec函数执行“php bin/satis build --respository-url=url_name satis.json ./web pacakage_name”
      • 增加包:通过php的exec函数执行“php bin/satis add --respository-url=url_name --type=vcs --name=package_name”,最后执行更新包的命令

另外的思路实现vcs包添加与更新:以gitlab为例,配置gitlab的webhook,在每次接收到新推送时,触发对应的satis url,检测到包存在则执行更新命令,包不存在则执行新增命令

六、参考文档

  • 基于 Composer 的 PHP 模块化开发
    • https://learnku.com/articles/5333/modular-development-of-php-based-on-composer
  • 正确的 Composer 扩展包安装方法
    • https://learnku.com/php/t/1901/correct-method-for-installing-composer-expansion-pack
  • composer.json的基础架构
    • https://docs.phpcomposer.com/04-schema.html
  • composer命令行的使用
    • https://docs.phpcomposer.com/03-cli.html
  • satis简介
    • https://docs.phpcomposer.com/articles/handling-private-packages-with-satis.html

你可能感兴趣的:(satis搭建composer包仓库)