我们的情况如下:
我们有3个不同的Laravel项目,所有3个项目都依赖于我们的核心项目。该核心项目是一个单独的Laravel包,托管在我们的私人回购协议上,并用作其他项目的依赖项。
以前,每当Core项目发生变化时,我们只需在我们的服务器上为每个项目运行一个作曲家更新我们的供应商/ourcorepack来拉入核心更改。然而,由于最近作曲家似乎遭受严重的内存问题,当我们试图运行更新我们的数字海洋暂存环境与512 MB内存。见:https://github.com/composer/composer/issues/1898
我经常遇到的解决方案是,人们说您应该始终在生产服务器上运行composer install。我可以从安全性的角度考虑这一点,因为如果您更新到某个第三方软件包的新版本,可能会破坏您的代码,这可能会很危险。但是在我们的例子中,我们只更新我们自己的核心包,这样我们就知道我们在做什么,但是这个内存问题迫使我们使用composer安装方法,因为它对内存的要求比较低。
基本上这就是我们目前的工作流程:
>
当我们的核心包发生变化时,我们需要在每个本地项目上运行composer update ourvendor/ourpackage,这将生成一个composer。锁定文件
我们委托作曲家。在我们的回购中锁定文件
在每个项目的服务器上,我们运行一个git拉和运行一个作曲家安装。这只会更新我们的核心包,运行速度更快,没有内存问题
然而,这种解决方案提出了两个问题:
那我该在这里做什么?在服务器上删除composer.lock文件之前?我们应该如何处理composer.lock文件的合并冲突?
遗憾的是,作曲家更新遇到了内存问题,因为这种方法似乎更符合逻辑。只需更新你想要的包,没有composer.lock文件的麻烦。
请建议我们如何使用GIT和composer创建正确的工作流,以及如何解决上述冲突?
非常感谢你的意见
有时作曲家更新会破坏一些东西。我所做的是。
composer上的所有更改。锁定
另一种方法(不进行编写器更新
):
composer.json
复制新的(和删除的)行到一个单独的文本文件中。composer.json
和composer.lock
文件。 安装作曲家
作曲家需要供应商/包:版本
作曲家删除供应商/包
此方法将保留来自远程分支(可能是master
或developer
分支)的锁,并且只更新您的新包。
如果开发人员自己不执行此步骤,如何测试核心更新(或任何其他更新的依赖项)不会破坏使用它的项目中的内容?
这就是为什么通常的工作流程期望作曲家更新
在具有足够内存的开发机器上运行(例如,可能超过1GB的PHP内存限制),并且更新应该由开发人员手动触发(如果自动触发通过持续集成构建,内存需求也适用于此机器)。
没有办法解决这个内存需求。只安装了512 MB RAM的web服务器可能能够在几乎没有并发用户的情况下充当临时服务器,但不应使用它来更新Composer依赖项。
我个人修复了编写器中的合并冲突。使用非常简单的系统锁定
:删除锁定文件并运行编写器更新
。这将把所有依赖项更新为满足版本要求的最新版本,并创建一个新的工作编写器。锁定合并期间提交的get文件。
我不怕可能会更新所有内容,因为要么它按预期工作,要么我的测试会很快发现错误。
我确实仔细选择了我使用的第三方软件包:
他们必须标记自己的版本,最好使用语义版本控制
我不在发布版本中使用任何分支(很少有人在开发过程中使用它们是痛苦的)
- 如果进行了向后不兼容的更改,则应发布新的主要版本
- 本地开发的软件包也遵循这些要求
这与我们本地SATS实例所服务的大约270个包一起工作(可能也是试图减少内存占用时考虑的因素)-只有作曲者已知的包可以存储在内存中:比较PayAgist.Org在270个本地包上潜在的一万个包。270个软件包中的60个由20名开发者在本地开发,并随机发布新版本。过去2年中的更新失败非常罕见,应该像处理其他错误一样处理:如果检测到标记的版本不兼容,我们将发布一个修复错误的版本来恢复更改,如果需要不兼容的更改,则使用新的主要版本来标记原始更改。
因此,您要求的工作流可能如下所示:
任何时候,任何开发人员都应该能够在他们的本地机器上运行作曲家更新
。
- 他们应该能够检测到这是否破坏了他们本地机器上的东西。
- 如果没有任何损坏,他们提交的更改,包括
composer.lock
文件到Git - 暂存服务器只运行
作曲家安装
,并且将完全使用开发人员在其机器上使用的版本。 - 如果舞台上没有任何问题,这个版本就可以在生产中使用了。
在另一台开发人员机器上合并已提交的版本可能会显示与
composer.lock
的合并冲突。
解决所有其他文件上的冲突
作曲家。锁定
文件应被删除
从这里开始,工作流程如下所示,即:
- 开发人员应该能够在其本地计算机上运行
composer update
- 他们应该能够检测到这是否破坏了他本地机器上的东西
- 如果什么都没破。。。等等
在布朗运动的例子中,若增加点的数目,例如n = 300及s = .02, 运动就不是很流畅了;完成每一步要花太多时间。这时,如果保存预定数目的画面为位图并以电影方式回放则会比较有效。 首先,确定画面数,譬如 nframes = 50; 然后,跟往前一样设定第一幅图,不是用默认的EraseMode (正态). x = rand(n,1)-0.5; y = rand(n,1)-0.5; h = pl
create 当你刚起步或者只是想要测试一些东西时,倾向于从 create() 操作符入手。它接收一个有 observer 参数的函数。在前面的一些章节中已提及过,比如 Observable 包装章节。函数签名如下: Rx.Observable.create([fn]) 示例如下: Rx.Observable.create(observer => { observer.next( 1 );
Timer 创建一个Observable,它在一个给定的延迟后发射一个特殊的值。 Timer操作符创建一个在给定的时间段之后返回一个特殊值的Observable。 RxJava将这个操作符实现为timer函数。 timer返回一个Observable,它在延迟一段给定的时间后发射一个简单的数字0。 timer操作符默认在computation调度器上执行。有一个变体可以通过可选参数指定Schedu
Start 返回一个Observable,它发射一个类似于函数声明的值 编程语言有很多种方法可以从运算结果中获取值,它们的名字一般叫functions, futures, actions, callables, runnables等等。在Start目录下的这组操作符可以让它们表现得像Observable,因此它们可以在Observables调用链中与其它Observable搭配使用。 Start操
Repeat 创建一个发射特定数据重复多次的Observable Repeat重复地发射数据。某些实现允许你重复的发射某个数据序列,还有一些允许你限制重复的次数。 RxJava将这个操作符实现为repeat方法。它不是创建一个Observable,而是重复发射原始Observable的数据序列,这个序列或者是无限的,或者通过repeat(n)指定重复次数。 repeat操作符默认在trampoli
Range 创建一个发射特定整数序列的Observable Range操作符发射一个范围内的有序整数序列,你可以指定范围的起始和长度。 RxJava将这个操作符实现为range函数,它接受两个参数,一个是范围的起始值,一个是范围的数据的数目。如果你将第二个参数设为0,将导致Observable不发射任何数据(如果设置为负数,会抛异常)。 range默认不在任何特定的调度器上执行。有一个变体可以通过