Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. PHP
Code

Thiết lập một bản sao cục bộ cho các package của Composer cùng Satis

by
Difficulty:IntermediateLength:LongLanguages:

Vietnamese (Tiếng Việt) translation by Andrea Ho (you can also view the original English article)

Việc cài đặt tất cả các thư viện PHP của bạn với Composer là cách tuyệt vời để tiết kiệm thời gian. Nhưng các dự án lớn hơn sẽ tự động được kiểm tra và chạy ở mỗi lần commit với hệ thống kiểm soát phiên bản phần mềm (SVC) của bạn sẽ mất nhiều thời gian để cài đặt tất cả các package cần thiết từ Internet. Bạn muốn chạy test ngay khi có thể thông qua hệ thống tích hợp liên tục (CI) để bạn có phản hồi nhanh và nhanh chóng tác động lại các thất bại. Trong hướng dẫn này, chúng tôi sẽ thiết lập bản sao cục bộ để ủy quyền tất cả các package của bạn được yêu cầu trong file composer.json của dự án. Điều này sẽ giúp CI của chúng tôi hoạt động nhanh hơn nhiều, cài đặt các package qua mạng cục bộ hoặc thậm chí được lưu trữ trên cùng một máy và đảm bảo chúng tôi luôn có sẵn phiên bản cụ thể của các package.


Satis là gì?

Satis là tên của ứng dụng mà chúng tôi sẽ sử dụng để nhân bản các repo khác nhau cho dự án của chúng tôi. Nó đóng vai trò như một proxy giữa Internet và composer của bạn. Giải pháp của chúng tôi sẽ tạo ra một bản sao cục bộ của một vài package và hướng dẫn composer của chúng tôi sử dụng nó thay vì các nguồn được tìm thấy trên Internet.

Nói có sách mách có chứng.

Architecture

Dự án của chúng tôi sẽ sử dụng composer như bình thường. Nó sẽ được cấu hình để sử dụng máy chủ Satis cục bộ làm nguồn chính. Nếu một package được tìm thấy ở đó, nó sẽ được cài đặt từ đó. Nếu không, chúng tôi sẽ cho phép composer sử dụng packagist.org mặc định để truy xuất package.


Lấy về Satis

Satis có sẵn thông qua composer, vì vậy việc cài đặt nó rất đơn giản. Trong kho lưu trữ mã nguồn đính kèm, bạn sẽ tìm thấy Satis được cài đặt trong thư mục Sources/Satis. Đầu tiên chúng ta cài đặt trình composer.

Sau đó, chúng tôi sẽ cài đặt Satis.


Cấu hình Satis

Satis được cấu hình bởi một file JSON rất giống với Composer. Bạn có thể sử dụng tên mà bạn muốn cho file của mình và chỉ định tên đó để sử dụng sau này. Chúng tôi sẽ sử dụng "mirrored-package.conf".

Hãy phân tích file cấu hình này.

  • name - đại diện cho một string sẽ được hiển thị trên giao diện web của máy nhân bản của chúng tôi.
  • homepage - là địa chỉ web sẽ lưu trữ các package của chúng tôi. Điều này không cho máy chủ web của chúng tôi sử dụng địa chỉ và cổng đó, nó chỉ là thông tin của cấu hình hoạt động. Chúng tôi sẽ thiết lập quyền truy xuất vào nó trên địa chỉ và cổng đó sau.
  • repositories - một danh sách các repo theo thứ tự ưu tiên. Trong ví dụ của chúng tôi, kho lưu trữ đầu tiên là một ngã ba Github của các thư viện ghi nhật ký độc thoại. Nó có một số sửa đổi và chúng tôi muốn sử dụng fork cụ thể đó khi cài đặt monolog. Loại repo này là "vcs". Repo thứ hai thuộc kiểu "composer". URL của nó là trang mặc định của packagist.org.
  • require - liệt kê các package chúng tôi muốn nhân bản. Nó có thể đại diện cho một package cụ thể với một phiên bản hoặc branch cụ thể hoặc phiên bản bất kỳ. Nó sử dụng cú pháp giống như "require" hoặc "require-dev" trong composer.json của bạn.
  • require-dependencies - là tùy chọn cuối cùng trong ví dụ của chúng tôi. Nó sẽ báo Satis sao chép các package chúng tôi đã chỉ định trong phần "require" và tất cả các phụ thuộc của chúng.

Để nhanh chóng thử các cài đặt của chúng tôi, trước tiên chúng tôi cần nói với Satis để tạo các bản sao. Chạy lệnh này trong thư mục bạn đã cài đặt Satis.

Trong khi quá trình đang diễn ra, bạn sẽ thấy Satis nhân bản từng phiên bản được tìm thấy của các package yêu cầu. Hãy kiên nhẫn vì có thể mất thời gian để xây dựng tất cả các package đó.

Satis yêu cầu date.timezone đó phải được xác định trong file php.ini, vì vậy hãy đảm bảo rằng nó được thiết lập và xét thành múi giờ địa phương của bạn. Nếu không, lỗi sẽ xuất hiện.

Sau đó, chúng ta có thể chạy một cá thể máy chủ PHP trong bảng điều khiển của chúng tôi trỏ đến repo được tạo gần đây. Bắt buộc bản PHP 5.4 hoặc mới hơn.

Và bây giờ chúng tôi có thể duyệt các package đã nhân đôi và thậm chí tìm kiếm các package cụ thể bằng cách trỏ trình duyệt web của chúng tôi tới http://localhost:4680:

MirrorWebpage

Hãy host (lưu) nó trên Apache

Nếu bạn có Apache đang chạy, việc tạo một máy chủ ảo cho Satis sẽ khá đơn giản.

Chúng tôi chỉ sử dụng một file .conf như thế này, đặt trong thư mục conf.d của Apache, thường là /etc/apache2/conf.d. Nó tạo ra một máy chủ ảo trên cổng 4680 và trỏ nó vào thư mục của chúng tôi. Tất nhiên bạn có thể sử dụng bất cứ cổng nào bạn muốn.


Cập nhật các bản sao của chúng tôi

Satis không thể tự động cập nhật các bản sao trừ khi chúng ta yêu cầu. Vì vậy, cách dễ nhất, trên bất kỳ hệ thống UNIX nào, là chỉ cần thêm một cron job (tác vụ đình kỳ) vào hệ thống của bạn. Điều đó sẽ rất dễ dàng và chỉ là script đơn giản để thực hiện lệnh cập nhật.

Hạn chế của giải pháp này là nó không thay đổi. Chúng tôi phải cập nhật thủ công mirrored-packages.conf mỗi khi chúng tôi bổ sung package khác vào composer.json của dự án. Nếu bạn là thành viên của một nhóm trong một công ty có dự án lớn và máy chủ tích hợp liên tục, bạn không thể trông cậy mọi người nhớ đến việc thêm các package trên máy chủ. Họ thậm chí có thể không có quyền truy xuất vào cơ sở hạ tầng CI.


Tự động cập nhật cấu hình Satis

Đã đến lúc thực hành TDD PHP. Nếu bạn chỉ muốn code của mình sẵn sàng và chạy, hãy xem mã nguồn được đính kèm với hướng dẫn này.

Như thường lệ, chúng tôi bắt đầu với một test, chỉ đủ để đảm bảo rằng chúng tôi có một framework kiểm tra hiệu quả. Bạn có thể nhận thấy rằng tôi có một dòng request_once khá lạ, điều này là do tôi muốn tránh phải cài đặt lại PHPUnit và Mockery cho mỗi dự án nhỏ. Vì vậy, tôi để chúng trong thư mục vendor trong thư mục gốc của NetTuts. Bạn chỉ nên cài đặt chúng với Composer và bỏ dòng request_once hoàn toàn.

Điều đó có vẻ đúng. Tất cả các trường ngoại trừ "require" là tĩnh. Chúng ta chỉ cần tạo các package. Các repo đang trỏ vào bản sao private git của chúng tôi và đến packagist khi cần thiết. Quản lý các repo đó là công việc có hơi hướng sysadmin hơn là một nhà phát triển phần mềm.

Tất nhiên điều này thất bại với:

Việc sửa đối chúng dễ dàng.

Tôi vừa thêm một phương thức rỗng với tên được yêu cầu là private, vào class test của chúng ta. Thật tuyệt, nhưng bây giờ chúng tôi có một lỗi khác.

Do đó, null không khớp với string của chúng tôi chứa tất cả cấu hình mặc định đó.

OK, hiệu quả. Tất cả bài test sẽ hoàn tất.

Nhưng chúng tôi đã giới thiệu một bản sao tệ hại. Tất cả các nội dung tĩnh ở hai nơi, viết từng chữ ở hai nơi khác nhau. Hãy sửa lỗi này:

À! Thế thì tốt hơn.

Tốt. Việc đó cũng qua rồi. Nhưng nó cũng nêu bật lên một số trùng lặp và phân bổ vô ích.

Chúng tôi đã gạch vào biến $expect. $actual cũng có thể được nội tuyến, nhưng tôi thích nó tốt hơn theo cách này. Nó duy trì tập trung vào những gì được test.

Bây giờ chúng tôi có một vấn đề khác. Bài test tiếp theo tôi muốn viết sẽ như thế này:

Nhưng sau khi viết cách triển khai đơn giản, chúng ta sẽ nhận thấy nó yêu cầu json_decode()json_encode(). Và tất nhiên các hàm này định dạng lại chuỗi của chúng tôi và việc tìm khớp chuỗi sẽ khó khăn nhất. Chúng ta phải chậm lại một chút.

Chúng tôi đã thay đổi phương thức xác nhận của mình để so sánh các chuỗi JSON và chúng tôi cũng đã mã hóa lại biến $actual của chúng tôi. ParseComposerConf() cũng được thay đổi đổi để sử dụng phương thức này. Bạn sẽ nhanh chóng nó có ích thế nào. Test tiếp theo của chúng tôi sẽ cụ thể hơn về JSON.

Và làm cho test này vượt qua, cùng với phần còn lại của các test, lại khá dễ dàng.

Chúng tôi lấy chuỗi JSON nhập vào, decode (giải mã) nó và nếu nó chứa field "require", chúng tôi sẽ sử dụng chuỗi đó trong file cấu hình Satis của chúng tôi. Nhưng chúng tôi có thể muốn sao chép tất cả các phiên bản của một package, không chỉ phiên bản cuối cùng. Vì vậy, có lẽ chúng tôi muốn sửa đổi test của mình để kiểm tra xem phiên bản có phải là "*" trong Satis hay không, bất kể phiên bản chính xác là gì trong composer.json.

Điều đó rõ ràng thất bại với một thông điệp tuyệt vời:

Bây giờ, chúng ta cần thực sự chỉnh sửa JSON của mình trước khi encode (mã hóa).

Để vượt qua test, chúng tôi phải lặp lại qua từng phần tử của mảng package được yêu cầu và đặt phiên bản của chúng thành '*'. Xem phương thức toAllVersion() để biết thêm chi tiết. Và để tăng tốc hướng dẫn này một chút, chúng tôi cũng trích xuất một số phương thức private trong cùng bước này. Bằng cách này, parseComoserConf() có tính mô tả và dễ hiểu. Chúng tôi cũng có thể nội tuyến $config vào các đối số của addNewRequires(), nhưng vì lý do thẩm mỹ, tôi đã bố trí nó trên hai dòng.

Nhưng còn "require-dev" trong composer.json thì sao?

Điều đó rõ ràng là thất bại. Chúng tôi có thể làm cho nó vượt qua chỉ bằng cách sao chép/dán nếu điều kiện if của chúng tôi trong addNewRequires():

Đúng, điều đó giúp nó vượt qua, nhưng điều đó trùng lặp nếu các mệnh đề if là khó chịu. Hãy xử lý chúng.

Chúng tôi có thể vui vẻ trở lại, các test có màu xanh và chúng tôi đã cấu trúc lại code của chúng tôi. Tôi nghĩ chỉ còn làm thêm một test. Điều gì xảy ra nếu chúng ta có cả hai phần "require" và "require-dev" trong composer.json?

Điều đó không thành công vì các package được thiết lập bởi "require-dev" sẽ ghi đè lên các package "require" và chúng tôi sẽ gặp lỗi:

Chỉ cần thêm một dấu cộng để hợp nhất các array, và chúng ta đã hoàn thành.

Các test sắp hoàn thành. Logic của chúng tôi đã hoàn tất. Tất cả những gì chúng ta phải làm là trích xuất các phương thức vào file và class của riêng chúng. Phiên bản cuối cùng của các test và class SatisUpdater có thể được tìm thấy trong mã nguồn đính kèm.

Bây giờ chúng ta có thể sửa đổi cron script của mình để tải trình phân tích cú pháp và chạy trên composer.json. Việc này áp dụng cụ thể cho các thư mục nhất định của dự án của bạn. Dưới đây là một ví dụ bạn có thể thích nghi vào hệ thống của bạn.


Khiến cho dự án của bạn sử dụng bản sao

Chúng tôi đã bàn về rất nhiều điều trong bài viết này, nhưng đã không đề cập đến cách mà chúng tôi sẽ hướng dẫn dự án của chúng tôi sử dụng bản sao thay vì Internet. Bạn biết đấy, có phải mặc định là packagist.org? Trừ khi chúng ta làm điều này:

Điều đó sẽ làm cho bản sao của bạn trở thành lựa chọn đầu tiên cho composer. Nhưng việc thêm nó vào composer.json trong dự án của bạn sẽ không vô hiệu hóa quyền truy cập vào packagist.org. Nếu không thể tìm thấy một package trên máy nhân bản, nó sẽ được tải xuống từ Internet. Nếu bạn muốn chặn tính năng này, bạn cũng có thể muốn thêm dòng sau vào phần repositories bên trên:


Tổng kết

Thế đấy. Bản sao cục bộ với các package tự động thích ứng và cập nhật. Đồng nghiệp của bạn sẽ không bao giờ phải chờ đợi lâu trong khi họ hoặc máy chủ CI cài đặt tất cả các yêu cầu của dự án của bạn. Chúc vui vẻ.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.