-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#786: Upgrade commandlet #957
base: main
Are you sure you want to change the base?
Conversation
…Easy into upgrade-commandlet
} | ||
|
||
// hardcoding the file extension seems wrong | ||
String fileName = artifactId + "-" + version + "-" + classifier + ".tar.gz"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right now just hardcoding the file extension, that means this doesnt work for every maven artifact
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simply add an extra parameter for the extension - it should default to .jar
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this method isn't an API (this method is only being used by the method download
, which retrieves the download link and downloads the tool), I added a param for extension and a param for a classifier to the download
method, so that when we want to download a tool and want to provide an extension and a classifier, we can do that directly through the download
method. This caused a couple more changes to the upper hierarchy.
public void testSnapshotVersionComparisons() { | ||
|
||
IdeTestContext context = newContext(PROJECT_BASIC); | ||
UpgradeCommandlet uc = context.getCommandletManager().getCommandlet(UpgradeCommandlet.class); | ||
|
||
assertThat(uc.isSnapshotNewer("2024.12.002-beta-12_18_02-SNAPSHOT", "2025.01.001-beta-20250118.022832-8")).isTrue(); | ||
assertThat(uc.isSnapshotNewer("2024.12.002-beta-01_01_02-SNAPSHOT", "2024.12.002-beta-20241218.023429-8")).isTrue(); | ||
assertThat( | ||
uc.isSnapshotNewer("2024.12.002-beta-12_18_02-SNAPSHOT", "2024.12.002-beta-20241218.023429-8")).isFalse(); | ||
assertThat(uc.isSnapshotNewer("SNAPSHOT", "2024.12.002-beta-20241218.023429-8")).isFalse(); | ||
assertThat(uc.isSnapshotNewer("someUnknownFormat1", "someUnknownFormat2")).isFalse(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only testing the snapshot comparison method as I cant really test the run method with all the download and the script launching and extraction and so on ..
String scriptContent = | ||
"@echo off\n" + "ping -n 4 127.0.0.1 > nul\n" + "C:\\Windows\\System32\\tar.exe -xzf \"%~1\" -C \"%~2\"\n" | ||
+ "del \"%~f0\""; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesnt seem like the most elegant bat file but works. The timeout
command doesnt work for some reason so using ping
, and I needed to get the whole path of the tar.exe
for it to extract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@salimbouch thanks for your PR. Very nice job solving the complex things of this story 👍
I left some review comments for improvement.
Please have a look.
private String getBaseUrl(String groupId, String artifactId) { | ||
|
||
if (isIdeasySnapshot(groupId, artifactId, IdeVersion.get())) { | ||
return MAVEN_SNAPSHOTS; | ||
} | ||
return MAVEN_CENTRAL; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this and its usage is wrong.
You implemented MavenRepository
specific for our use-case of downloading IDEasy.
IdeVersion.get()
needs to be used outside of this class to do the version comparison.
In getMetadata
you need to use the version
argument that you ignoring here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
// If it's a resolved snapshot version (contains timestamp), convert back to -SNAPSHOT format for the path | ||
if (pathVersion.matches(".*-\\d{8}\\.\\d{6}-\\d+")) { | ||
pathVersion = pathVersion.replaceAll("-\\d{8}\\.\\d{6}-\\d+", "-SNAPSHOT"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also misplaced here.
getMetadata(IDEASY_GROUP_ID, IDEASY_ARTIFACT_ID, VersionIdentifier.of("2024.12.002-beta"))
should give us
https://repo1.maven.org/maven2/com/devonfw/tools/IDEasy/ide-cli/2024.12.002-beta/ide-cli-2024.12.002-beta.jar
The variant getMetadata(IDEASY_GROUP_ID, IDEASY_ARTIFACT_ID, VersionIdentifier.of("2024.12.002-beta"), "windows-x64", ".tar.gz")
should give
https://repo1.maven.org/maven2/com/devonfw/tools/IDEasy/ide-cli/2024.12.002-beta/ide-cli-2024.12.002-beta-windows-x64.tar.gz
Where windows-x64
is called classifier
in maven terminology and .tar.gz
is the extension (aka type in maven POM but there excluding the dot if you want to make it POM compliant just pass tar.gz
with jar
as default and add the dot internally in method impl).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now getMetadata
behaves as you stated. However, I still can't really get rid of this regex. The passed version to the method getMetadata
if the version is a snapshot looks like this: 2025.01.001-beta-20250121.023134-9
.
We need to make a path out of it, that means we take that version and make 2025.01.001-beta-SNAPSHOT
out of it so that the download link is sonatype.org/..../2025.01.001-beta-SNAPSHOT/...2025.01.001-beta-20250121.023134-9...
SystemInfo sys = this.context.getSystemInfo(); | ||
String classifier = sys.getOs() + "-" + sys.getArchitecture(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this code is misplaced here and needs to be moved outside of MavenRepository
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, now passing the classifier as arg to the download
method.
Path tmpDownloadFile = createTempDownload(MAVEN_METADATA_XML); | ||
|
||
try { | ||
this.context.getFileAccess().download(metadataUrl, tmpDownloadFile); | ||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | ||
DocumentBuilder builder = factory.newDocumentBuilder(); | ||
Document doc = builder.parse(tmpDownloadFile.toFile()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not make sense to write the XML to the disc just to then read it.
We should directly load the file into XML in memory without writing temporary files to the disc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, not really sure if I used the right libraries for it, see method fetchXmlMetadata
.
String version = Optional.ofNullable(doc.getElementsByTagName("latest").item(0)).map(Element.class::cast) | ||
.map(Element::getTextContent).orElseGet( | ||
() -> Optional.ofNullable(doc.getElementsByTagName("release").item(0)).map(Element.class::cast) | ||
.map(Element::getTextContent) | ||
.orElseThrow(() -> new IllegalStateException("No latest or release version found in metadata"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't XPath help here to make the code more compact and elegant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
if (isIdeasySnapshot(groupId, artifactId, version)) { | ||
version = resolveSnapshotVersion(groupId, artifactId, version); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should also not be specific for IDEasy.
If someone provides a version ending with -SNAPSHOT
then you should resolve it the way you are doing that for any artifact no matter if IDEasy or not.
Outside when you use all this specific for IDEasy and you have version 2025.01.001-beta-01_21_02-SNAPSHOT
simply convert this back to 2025.01.001-beta-SNAPSHOT
what seems easy and pass that as version to this method to make it work.
Following Separation of Concerns this class should be generic and make sense for any maven artfact so we can reuse it also for gcviewer
, gcloganalyzer
, cobigen
, or whatever we like.
Everything that is specific for IDEasy and the way we build our version printed by ide -v
needs to go to UpgradeCommandlet
and related code outside of this repo
package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
} finally { | ||
this.context.getFileAccess().delete(tmpDownloadFile); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will also be pointless then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Path tmpDownloadFile = createTempDownload(MAVEN_METADATA_XML); | ||
|
||
try { | ||
this.context.getFileAccess().download(metadataUrl, tmpDownloadFile); | ||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | ||
DocumentBuilder builder = factory.newDocumentBuilder(); | ||
Document doc = builder.parse(tmpDownloadFile.toFile()); | ||
|
||
String timestamp = Optional.ofNullable(doc.getElementsByTagName("timestamp").item(0)).map(Element.class::cast) | ||
.map(Element::getTextContent) | ||
.orElseThrow(() -> new IllegalStateException("No timestamp found in snapshot metadata")); | ||
|
||
String buildNumber = Optional.ofNullable(doc.getElementsByTagName("buildNumber").item(0)) | ||
.map(Element.class::cast).map(Element::getTextContent) | ||
.orElseThrow(() -> new IllegalStateException("No buildNumber found in snapshot metadata")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here. Also this looks like code duplication that should be avoided by reusing code from a private method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
private boolean isIdeasySnapshot(String groupId, String artifactId, String version) { | ||
|
||
return IDEASY_GROUP_ID.equals(groupId) && IDEASY_ARTIFACT_ID.equals(artifactId) && version != null | ||
&& version.contains("SNAPSHOT"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As stated above
private boolean isIdeasySnapshot(String groupId, String artifactId, String version) { | |
return IDEASY_GROUP_ID.equals(groupId) && IDEASY_ARTIFACT_ID.equals(artifactId) && version != null | |
&& version.contains("SNAPSHOT"); | |
} | |
private boolean isSnapshotVersion(String version) { | |
return version.endsWith("-SNAPSHOT"); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@Override | ||
public Collection<ToolDependency> findDependencies(String groupId, String artifactId, VersionIdentifier version) { | ||
|
||
return Collections.emptyList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return Collections.emptyList(); | |
// We could read POM here and find dependencies but we do not want to reimplement maven here. | |
// For our use-case we only download bundled packages from maven central so we do KISS for now. | |
return Collections.emptyList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Pull Request Test Coverage Report for Build 12915070560Details
💛 - Coveralls |
Also changed the way I retrieve the latest version from |
fixes #786