33namespace CodedMonkey \Dirigent \Package ;
44
55use CodedMonkey \Dirigent \Composer \ComposerClient ;
6+ use CodedMonkey \Dirigent \Composer \ConfigFactory ;
67use CodedMonkey \Dirigent \Doctrine \Entity \Version ;
8+ use Composer \IO \BufferIO ;
9+ use Composer \Pcre \Preg ;
10+ use Composer \Util \Filesystem as ComposerFilesystem ;
11+ use Composer \Util \Git as GitUtility ;
12+ use Composer \Util \ProcessExecutor ;
13+ use Composer \Util \Url ;
714use Symfony \Component \DependencyInjection \Attribute \Autowire ;
815use Symfony \Component \Filesystem \Filesystem ;
916
1017readonly class PackageDistributionResolver
1118{
1219 private Filesystem $ filesystem ;
13- private string $ storagePath ;
20+ private string $ buildStoragePath ;
21+ private string $ distributionStoragePath ;
1422
1523 public function __construct (
1624 private ComposerClient $ composer ,
1725 #[Autowire(param: 'dirigent.storage.path ' )]
1826 string $ storagePath ,
27+ #[Autowire(param: 'dirigent.dist_builder.enabled ' )]
28+ private bool $ buildDistributions ,
29+ #[Autowire(param: 'dirigent.dist_builder.dev_packages ' )]
30+ private bool $ buildDevDistributions ,
1931 ) {
2032 $ this ->filesystem = new Filesystem ();
21- $ this ->storagePath = "$ storagePath/distribution " ;
33+ $ this ->buildStoragePath = "$ storagePath/distribution-builder " ;
34+ $ this ->distributionStoragePath = "$ storagePath/distribution " ;
2235 }
2336
2437 public function exists (string $ packageName , string $ packageVersion , string $ reference , string $ type ): bool
@@ -28,7 +41,7 @@ public function exists(string $packageName, string $packageVersion, string $refe
2841
2942 public function path (string $ packageName , string $ packageVersion , string $ reference , string $ type ): string
3043 {
31- return "{ $ this ->storagePath } / { $ packageName} / { $ packageVersion} - { $ reference} . { $ type} " ;
44+ return "$ this ->distributionStoragePath / $ packageName/ $ packageVersion- $ reference. $ type " ;
3245 }
3346
3447 public function resolve (Version $ version , string $ reference , string $ type ): bool
@@ -41,7 +54,13 @@ public function resolve(Version $version, string $reference, string $type): bool
4154 return true ;
4255 }
4356
44- if ($ reference !== $ version ->getDistReference () || $ type !== $ version ->getDistType ()) {
57+ if (
58+ !$ version ->getDist ()
59+ && $ this ->buildDistributions
60+ && (!$ version ->isDevelopment () || $ this ->buildDevDistributions )
61+ ) {
62+ return $ this ->build ($ version , $ reference , $ type );
63+ } elseif ($ reference !== $ version ->getDistReference () || $ type !== $ version ->getDistType ()) {
4564 return false ;
4665 }
4766
@@ -55,4 +74,37 @@ public function resolve(Version $version, string $reference, string $type): bool
5574
5675 return true ;
5776 }
77+
78+ private function build (Version $ version , string $ reference , string $ type ): bool
79+ {
80+ if ($ reference !== $ version ->getSourceReference () || $ type !== 'zip ' ) {
81+ return false ;
82+ }
83+
84+ $ package = $ version ->getPackage ();
85+ $ packageName = $ package ->getName ();
86+ $ packageVersion = $ version ->getNormalizedVersion ();
87+ $ repositoryUrl = $ package ->getRepositoryUrl ();
88+ $ distributionPath = $ this ->path ($ packageName , $ packageVersion , $ reference , $ type );
89+
90+ $ io = new BufferIO ();
91+ $ config = ConfigFactory::createForVcsRepository ($ repositoryUrl , $ package ->getRepositoryCredentials ());
92+
93+ $ gitUtility = new GitUtility (
94+ $ io ,
95+ $ config ,
96+ $ process = new ProcessExecutor ($ io ),
97+ new ComposerFilesystem ($ process ),
98+ );
99+
100+ $ cachePath = $ config ->get ('cache-vcs-dir ' ) . '/ ' . Preg::replace ('{[^a-z0-9.]}i ' , '- ' , Url::sanitize ($ repositoryUrl )) . '/ ' ;
101+
102+ $ this ->filesystem ->mkdir (dirname ($ distributionPath ));
103+
104+ $ gitUtility ->runCommands ([
105+ ['git ' , 'archive ' , '--format=zip ' , "--output= $ distributionPath " , $ reference ],
106+ ], $ repositoryUrl , $ cachePath );
107+
108+ return true ;
109+ }
58110}
0 commit comments