@@ -29,27 +29,29 @@ class SplitCommand {
2929 public function handle (Args $ args , IO $ io ) {
3030 $ yaml = new Yaml ();
3131
32- $ configfile = $ args ->getArgument ('config ' );
32+ $ configfile = $ this ->getConfigFilePath ($ args );
33+
3334 $ config_secrets = str_replace (".yml " , "_secrets.yml " , $ configfile );
3435 if ($ content = file_get_contents ($ configfile )) {
3536 $ config = $ yaml ->parse ($ content );
3637 }
3738 if ($ content = file_get_contents ($ config_secrets )) {
3839 $ config = array_merge ($ config , $ yaml ->parse ($ content ));
3940 }
41+
4042 $ this ->github_username = $ config ['github_username ' ];
4143 $ this ->github_orgname = $ config ['github_orgname ' ];
4244 $ this ->github_teamid = $ config ['github_teamid ' ];
4345 $ this ->project = $ config ['project_to_split ' ];
4446
47+ $ this ->alterPath ();
48+
4549 $ this ->upstream = "https://git.drupalcode.org/project/ {$ this ->project }.git " ;
4650
4751
48- $ packagist_api_client = new GuzzleClient (['base_uri ' => 'https://packagist.org/api/ ' ]);
4952 $ directory = 'upstream-current ' ;
5053
5154 $ github_apikey = $ config ['github_api_token ' ];
52- $ packagist_apitoken = $ config ['packagist_api_token ' ];
5355
5456 // Update/checkout local repository.
5557 $ this ->updateRepository ($ directory , $ args ->getArgument ('branch ' ));
@@ -59,6 +61,10 @@ public function handle(Args $args, IO $io) {
5961 // That contains a composer.json is a split candidate.
6062 //
6163 $ subtrees = $ this ->getSubtrees ($ directory );
64+
65+ // Make sure all 'core-' subtrees are ordered first.
66+ uksort ($ subtrees , [$ this , 'comparePackageNames ' ]);
67+
6268 // For each subtree,
6369 // 1. determine if a github repo exists for it
6470 // 2. if not, create a github repo
@@ -75,68 +81,90 @@ public function handle(Args $args, IO $io) {
7581 $ paginator = new ResultPager ($ client );
7682 $ parameters = array ($ this ->github_orgname );
7783 $ repositories = $ paginator ->fetchAll ($ userApi , 'repositories ' , $ parameters );
84+ $ reponames = [];
7885 foreach ($ repositories as $ repo ) {
7986 $ reponames [] = $ repo ['name ' ];
8087 }
81- $ packagist_client = new PackagistClient ();
8288 foreach ($ subtrees as $ subtree_name => $ subtree_data ) {
89+ $ io ->writeLine ("----------------------------------------------------- " );
8390 $ io ->writeLine ("Processing $ {subtree_name}" );
8491 if (!in_array ($ subtree_name , $ reponames )) {
8592 $ io ->writeLine ("Creating $ {subtree_name}" );
8693 $ client ->api ('repo ' )
8794 ->create ($ subtree_name , $ subtree_data ['description ' ], "http://drupal.org/project/ {$ this ->project }" , TRUE , $ this ->github_orgname , FALSE , FALSE , TRUE , $ this ->github_teamid , FALSE );
8895 }
89- // Update branch.
90- $ this ->splitBranch ($ directory , $ args ->getArgument ('branch ' ), $ github_apikey , $ subtree_data ['path ' ], $ subtree_name );
91- // Update tags.
92- exec ('git ls-remote --tags ' . $ this ->upstream , $ upstream_tags );
93- exec ("git ls-remote --tags https:// {$ this ->github_username }: {$ github_apikey }@github.com/ {$ this ->github_orgname }/ {$ subtree_name }.git " , $ downstream_tags );
94-
95- $ upstream_tags = Utility::filterValidTags ($ upstream_tags , $ args ->getArgument ('branch ' ));
96- $ downstream_tags = Utility::filterValidTags ($ downstream_tags , $ args ->getArgument ('branch ' ));
97-
98- // Tags which are not in the downstream repo.
99- $ tags = array_diff ($ upstream_tags , $ downstream_tags );
100- $ walkdata = [
101- 'directory ' => $ directory ,
102- 'name ' => $ subtree_name ,
103- 'path ' => $ subtree_data ['path ' ],
104- 'key ' => $ github_apikey ,
105- ];
106- array_walk ($ tags , function ($ tag ) use ($ walkdata ,$ github_apikey ) {
107- $ this ->splitTag ($ walkdata ['directory ' ], $ tag , $ walkdata ['key ' ], $ walkdata ['path ' ], $ walkdata ['name ' ]);
108- });
109-
110- // Check if package exists:
111- $ packagename = 'drupal/ ' . $ subtree_name ;
112- $ body =
'{"repository":{"url":"[email protected] : ' .
$ this ->
github_orgname .
'/ ' .
$ subtree_name .
'.git"}} ' ;
113- try {
114- $ packagist_client ->get ($ packagename );
115- $ endpoint = 'update-package ' ;
116- }
117- catch (Exception $ e ) {
118- // Package doesnt exist at packagist: needs to be created.
119- $ endpoint = 'create-package ' ;
120- }
121-
122- try {
123- $ packagist_api_client ->request ('POST ' , $ endpoint , [
124- 'body ' => $ body ,
125- 'headers ' => ['Content-Type ' => 'application/json ' ],
126- 'query ' => [
127- 'username ' => "$ this ->github_username " ,
128- 'apiToken ' => $ packagist_apitoken ,
129- ],
130- ]);
96+ $ ref = $ args ->getArgument ('branch ' );
97+ if (preg_match ('#\.x$# ' , $ ref )) {
98+ $ io ->writeLine ("Update branch $ ref " );
99+ // Update branch.
100+ $ this ->splitBranch ($ directory , $ ref , $ github_apikey , $ subtree_data ['path ' ], $ subtree_name );
131101 }
132- catch (GuzzleException $ e ) {
133- // There. handled.
102+ else {
103+ $ io ->writeLine ("Update tag $ ref " );
104+ // Update tag.
105+ $ this ->splitTag ($ directory , $ ref , $ github_apikey , $ subtree_data ['path ' ], $ subtree_name );
134106 }
135107
108+ $ this ->updatePackagist ($ config , $ subtree_name );
136109 }
137110 passthru ("rm -rf {$ directory }" );
138111 }
139112
113+ protected function updatePackagist ($ config , $ subtree_name ) {
114+ if (!isset ($ config ['packagist_api_token ' ])) {
115+ return ;
116+ }
117+
118+ $ packagist_client = new PackagistClient ();
119+ $ packagist_apitoken = $ config ['packagist_api_token ' ];
120+
121+ // Check if package exists:
122+ $ packagename = 'drupal/ ' . $ subtree_name ;
123+ $ body =
'{"repository":{"url":"[email protected] : ' .
$ this ->
github_orgname .
'/ ' .
$ subtree_name .
'.git"}} ' ;
124+ try {
125+ $ packagist_client ->get ($ packagename );
126+ $ endpoint = 'update-package ' ;
127+ }
128+ catch (Exception $ e ) {
129+ // Package doesnt exist at packagist: needs to be created.
130+ $ endpoint = 'create-package ' ;
131+ }
132+
133+ $ packagist_api_client = new GuzzleClient (['base_uri ' => 'https://packagist.org/api/ ' ]);
134+
135+ try {
136+ $ packagist_api_client ->request ('POST ' , $ endpoint , [
137+ 'body ' => $ body ,
138+ 'headers ' => ['Content-Type ' => 'application/json ' ],
139+ 'query ' => [
140+ 'username ' => "$ this ->github_username " ,
141+ 'apiToken ' => $ packagist_apitoken ,
142+ ],
143+ ]);
144+ }
145+ catch (GuzzleException $ e ) {
146+ // There. handled.
147+ }
148+ }
149+
150+ protected function getConfigFilePath ($ args ) {
151+ return $ args ->getArgument ('config ' )
152+ ?? $ this ->checkFileExists ('config.yml ' )
153+ ?? 'config.yml.dist ' ;
154+ }
155+
156+ protected function checkFileExists ($ path ) {
157+ return file_exists ($ path ) ? $ path : NULL ;
158+ }
159+
160+ protected function alterPath () {
161+ // We run whatever splitsh-lite we can find in the $PATH. Add the current
162+ // directory to the end of the path so that we will always find the one
163+ // at the project root if there isn't one already in the path.
164+ $ path = getenv ('PATH ' );
165+ putenv ("PATH= $ path:. " );
166+ }
167+
140168 protected function updateRepository ($ directory , $ branch ) {
141169 if (!file_exists ($ directory )) {
142170 passthru ("git clone {$ this ->upstream } {$ directory }" );
@@ -146,15 +174,19 @@ protected function updateRepository($directory, $branch) {
146174
147175 protected function splitBranch ($ directory , $ ref , $ token , $ prefix = 'core ' , $ name = 'core ' ) {
148176 passthru ("cd {$ directory } && git checkout --force {$ ref } && git reset --hard origin/ {$ ref }" );
149- passthru ("./ splitsh-lite --progress --prefix= {$ prefix }/ --origin=origin/ {$ ref } --path= {$ directory } --target=HEAD " );
177+ passthru ("splitsh-lite --progress --prefix= {$ prefix }/ --origin=origin/ {$ ref } --path= {$ directory } --target=HEAD " );
150178 passthru ("cd {$ directory } && git push https:// {$ this ->github_username }: {$ token }@github.com/ {$ this ->github_orgname }/ {$ name }.git HEAD: {$ ref }" );
151179 }
152180
153181 protected function splitTag ($ directory , $ ref , $ token , $ prefix = 'core ' , $ name = 'core ' ) {
154- passthru ("cd {$ directory } && git fetch --tags " );
155- passthru ("./splitsh-lite --progress --prefix= {$ prefix }/ --origin=tags/ {$ ref } --path= {$ directory } --target=tags/ {$ ref }" );
156- passthru ("cd {$ directory } && git push --delete https:// {$ this ->github_username }: {$ token }@github.com/ {$ this ->github_orgname }/ {$ name }.git {$ ref }" );
157- passthru ("cd {$ directory } && git push https:// {$ this ->github_username }: {$ token }@github.com/ {$ this ->github_orgname }/ {$ name }.git {$ ref }" );
182+ $ split_directory = 'upstream-split-source ' ;
183+ passthru ("git clone $ directory $ split_directory " );
184+ passthru ("cd {$ split_directory } && git fetch --tags " );
185+ passthru ("splitsh-lite --progress --prefix= {$ prefix }/ --origin=tags/ {$ ref } --path= {$ split_directory } --target=tags/ {$ ref }" );
186+ passthru ("cd {$ split_directory } && git push --delete https:// {$ this ->github_username }: {$ token }@github.com/ {$ this ->github_orgname }/ {$ name }.git {$ ref }" );
187+ passthru ("cd {$ split_directory } && git push https:// {$ this ->github_username }: {$ token }@github.com/ {$ this ->github_orgname }/ {$ name }.git {$ ref }" );
188+ passthru ("cd {$ split_directory } && git tag --delete $ ref " );
189+ passthru ("rm -rf {$ split_directory }" );
158190 }
159191
160192 /**
@@ -174,10 +206,36 @@ protected function getSubtrees($directory) {
174206 if ($ file ->getRelativePath () == "" ) {
175207 continue ;
176208 };
177- $ subtree_projectname = str_replace ("drupal/ " , "" , json_decode ($ file ->getContents ())->name );
178- $ subtrees [$ subtree_projectname ] = ['path ' => $ file ->getRelativePath (), 'description ' => json_decode ($ file ->getContents ())->description ];
209+ $ json = json_decode ($ file ->getContents ());
210+ $ subtree_projectname = str_replace ("drupal/ " , "" , $ json ->name );
211+ $ subtrees [$ subtree_projectname ] = ['path ' => $ file ->getRelativePath (), 'description ' => $ json ->description ];
179212 }
180213 return $ subtrees ;
181214 }
182215
216+ protected function comparePackageNames ($ a , $ b ) {
217+ return strcasecmp ($ this ->packageNameForComparison ($ a ), $ this ->packageNameForComparison ($ b ));
218+ }
219+
220+ /**
221+ * Prepends two spaces for 'core-' and one for 'core' itself.
222+ *
223+ * @param string $name
224+ * Package name to compare.
225+ *
226+ * @return string
227+ * Prefix to add before comparing.
228+ */
229+ protected function packageNameForComparison ($ name ) {
230+ $ name = trim ($ name );
231+ $ space = ' ' ;
232+ if (substr ($ name , 0 , 5 ) == 'core- ' ) {
233+ return "$ space$ space$ name " ;
234+ }
235+ if (substr ($ name , 0 , 4 ) == 'core ' ) {
236+ return "$ space$ name " ;
237+ }
238+ return $ name ;
239+ }
240+
183241}
0 commit comments