11// Copyright 2020 The Terasology Foundation
22// SPDX-License-Identifier: Apache-2.0
33package org.terasology.cli.managers
4- @GrabResolver (name = ' jcenter' , root = ' http://jcenter.bintray.com/' )
5- @Grab (group = ' org.ajoberstar' , module = ' grgit' , version = ' 1.9.3' )
6- import org.ajoberstar.grgit.Grgit
4+
75import org.terasology.cli.helpers.PropHelper
6+ import org.terasology.cli.scm.ScmGet
7+
8+ import static org.terasology.cli.helpers.KitchenSink.green
9+ import static org.terasology.cli.helpers.KitchenSink.yellow
810
911/**
1012 * Utility class for dealing with items managed in a developer workspace.
@@ -25,32 +27,37 @@ abstract class ManagedItem {
2527 File targetDirectory
2628 abstract File getTargetDirectory ()
2729
28- String githubTargetHome
30+ String targetGitOrigin
2931 abstract String getDefaultItemGitOrigin ()
3032
3133 ManagedItem () {
3234 displayName = getDisplayName()
3335 targetDirectory = getTargetDirectory()
34- githubTargetHome = calculateGitOrigin(null )
36+ targetGitOrigin = calculateGitOrigin(null )
3537 }
3638
3739 ManagedItem (String optionGitOrigin ) {
3840 displayName = getDisplayName()
3941 targetDirectory = getTargetDirectory()
40- githubTargetHome = calculateGitOrigin(optionGitOrigin)
42+ targetGitOrigin = calculateGitOrigin(optionGitOrigin)
4143 }
4244
45+ /**
46+ * Initializer for the target origin to get resources from - option, workspace setting, or a default.
47+ * @param optionOrigin an alternative if the user submitted a git option via CLI
48+ * @return the highest priority override or the default
49+ */
4350 String calculateGitOrigin (String optionOrigin ) {
4451 // If the user indicated a target Git origin via option parameter then use that (primary choice)
4552 if (optionOrigin != null ) {
46- println " We have an option set for Git origin so using that: " + optionOrigin
53+ green " We have an option set for Git origin so using that: " + optionOrigin
4754 return optionOrigin
4855 }
4956
5057 // Alternatively if the user has a global override set for Git origin then use that (secondary choice)
5158 String altOrigin = PropHelper . getGlobalProp(" alternativeGithubHome" )
5259 if (altOrigin != null ) {
53- println " There was no option set but we have a global proper override for Git origin: " + altOrigin
60+ green " There was no option set but we have a global proper override for Git origin: " + altOrigin
5461 return altOrigin
5562 }
5663
@@ -59,110 +66,65 @@ abstract class ManagedItem {
5966 return getDefaultItemGitOrigin()
6067 }
6168
62- // TODO: Likely everything below should just delegate to more specific classes to keep things tidy
63- // TODO: That would allow these methods to later just figure out exact required operations then delegate
64- // TODO: Should make it easier to hide the logic of (for instance) different Git adapters behind the next step
65-
6669 /**
67- * Tests a URL via a HEAD request (no body) to see if it is valid
68- * @param url the URL to test
69- * @return boolean indicating whether the URL is valid (code 200) or not
70+ * The Get command simply retrieves one or more resources in one go. Easy!
71+ * @param items to retrieve
7072 */
71- boolean isUrlValid (String url ) {
72- def code = new URL (url). openConnection(). with {
73- requestMethod = ' HEAD'
74- connect()
75- responseCode
73+ def get (List<String > items ) {
74+ for (String itemName : items) {
75+ println " Going to retrieve $displayName $itemName "
76+ getItem(itemName)
7677 }
77- return code. toString() == " 200"
7878 }
7979
80+ /**
81+ * More advanced version of the Get command that also retrieves any dependencies defined by the items.
82+ * @param items to retrieve
83+ * @return discovered dependencies from one round of processing (if used recursively)
84+ */
8085 List<String > recurse (List<String > items ) {
81- def dependencies = []
82- println " Going to retrieve the following items (recursively) : $items "
86+ List< String > dependencies = []
87+ println " Going to retrieve the following $d isplayName item(s) recursively : $items "
8388 for (String item : items) {
8489 // Check for circular dependencies - we should only ever act on a request to *retrieve* an item once
8590 if (itemsRetrieved. contains(item)) {
86- println " Uh oh, we got told to re-retrieve the same thing for $item - somebody oopsed a circular dependency? Skipping"
91+ yellow " Uh oh, we got told to re-retrieve the same thing for $item - somebody wrote a circular dependency? Skipping"
8792 } else {
8893 // We didn't already try to retrieve this item: get it (if we already have it then getItem will just be a no-op)
8994 getItem(item)
9095 // Then goes and checks the item on disk and parses the thing to see if it has dependencies (even if we already had it)
91- dependencies << ((DependencyProvider ) this ). parseDependencies(item)
96+ def newDependencyCandidates = ((DependencyProvider ) this ). parseDependencies(targetDirectory, item)
97+ println " Got new dependency candidates: " + newDependencyCandidates
98+ dependencies + = newDependencyCandidates - itemsRetrieved - dependencies
99+ println " Storing them without those already retrieved: " + dependencies
92100 }
93- // Mark this item as retrieved just in case somebody made a whoops and introduced a circular dependency
101+ // Mark this item as retrieved - that way we'll disqualify it if it comes up again in the future
94102 itemsRetrieved << item
95103 }
96104
105+ println " Finished recursively retrieving the following list: " + items
106+ dependencies - = itemsRetrieved
107+ println " After disqualifying any dependencies that were already in that list the following remains: " + dependencies
108+
97109 // If we parsed any dependencies, retrieve them recursively (and even if we already got them check them for dependencies as well)
98110 if (! dependencies. isEmpty()) {
99- println " Got dependencies to fetch: " + dependencies
111+ println " Got dependencies to fetch so we'll recurse and go again! "
100112 return recurse(dependencies)
101113 }
102114
103- println " Finally done recursing, both initial items and any parsed dependencies"
115+ green " Finally done recursing, both initial items and any parsed dependencies"
104116 return null
105117 }
106118
107- def get (List<String > items ) {
108- for (String itemName : items) {
109- getItem(itenName)
110- }
111- }
112-
113- def getItem (String item ) {
114- println " Going to get $item do we already have it? <logic to look for the dir existing>"
115- // Logic for a single retrieve, no dependency parsing involved
116- }
117-
118119 /**
119- * Primary entry point for retrieving items, kicks off recursively if needed.
120- * @param items the items we want to retrieve
121- * @param recurse whether to also retrieve dependencies of the desired items (only really for modules ...)
120+ * Simple one-item execution point for attempting to get a resource.
121+ * @param item the resource to get
122122 */
123- def retrieve (List<String > items , boolean recurse ) {
124- println " Now inside retrieve, user (recursively? $recurse ) wants: $items "
125- for (String itemName : items) {
126- println " Starting retrieval for $displayName $itemName , are we recursing? $recurse "
127- println " Retrieved so far: $itemsRetrieved "
128- retrieveItem(itemName, recurse)
129- }
130- }
123+ void getItem (String item ) {
124+ println " Processing get request for $item via SCM"
125+ // Logic for a single retrieve, no dependency parsing involved, nor Git origin tweaking - already handled
126+ ScmGet . cloneRepo(item, targetGitOrigin, targetDirectory, displayName)
131127
132- /**
133- * Retrieves a single item via Git Clone. Considers whether it exists locally first or if it has already been retrieved this execution.
134- * @param itemName the target item to retrieve
135- * @param recurse whether to also retrieve its dependencies (if so then recurse back into retrieve)
136- */
137- def retrieveItem (String itemName , boolean recurse ) {
138- File itemDir = new File (targetDirectory, itemName)
139- println " Request to retrieve $displayName $itemName would store it at $itemDir - exists? " + itemDir. exists()
140- if (itemDir. exists()) {
141- println " That $displayName already had an existing directory locally. If something is wrong with it please delete and try again"
142- itemsRetrieved << itemName
143- } else if (itemsRetrieved. contains(itemName)) {
144- println " We already retrieved $itemName - skipping"
145- } else {
146- itemsRetrieved << itemName
147- def targetUrl = " https://github.com/${ githubTargetHome} /${ itemName} "
148- if (! isUrlValid(targetUrl)) {
149- println " Can't retrieve $displayName from $targetUrl - URL appears invalid. Typo? Not created yet?"
150- return
151- }
152- println " Retrieving $displayName $itemName from $targetUrl "
153- if (githubTargetHome != getDefaultItemGitOrigin()) {
154- println " Doing a retrieve from a custom remote: $githubTargetHome - will name it as such plus add the ${ getDefaultItemGitOrigin()} remote as '$defaultRemote '"
155- Grgit . clone dir : itemDir, uri : targetUrl, remote : githubTargetHome
156- println " Primary clone operation complete, about to add the '$defaultRemote ' remote for the ${ getDefaultItemGitOrigin()} org address"
157- // addRemote(itemName, defaultRemote, "https://github.com/${getDefaultItemGitOrigin()}/${itemName}") //TODO: Add me :p
158- } else {
159- println " Cloning $targetUrl to $itemDir "
160- Grgit . clone dir : itemDir, uri : targetUrl
161- }
162- /*
163- // This step allows the item type to check the newly cloned item and add in extra template stuff - TODO? Same as the recurse fix?
164- //itemTypeScript.copyInTemplateFiles(itemDir)
165- */
166- }
128+ // TODO: Consider supporting copying in template files at this point if the type requests that
167129 }
168130}
0 commit comments