-
Notifications
You must be signed in to change notification settings - Fork 76
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
Provides updated PackageManager architecture #452
Conversation
- PackageDatabase works with repositories mentioned in a file - Adds methods to sync, load and save PackageDatabase - Adds RepositoryHandlers for handling Jenkins and custom repositories
Hooray Jenkins reported success with all tests good! |
- Package names need to be mentioned in sources.json file for tracking - Packages contains location field for locating their ZIPs
Hooray Jenkins reported success with all tests good! |
- Presents database as a list of package instances - Package instances provide isInstalled() method - Changes some PackageManager and RespositoryHandler methods for consistency
- Replaces TerasologyGameVersions instances with PackageManager in controllers - Minor changes to PackageManager API
Hooray Jenkins reported success with all tests good! |
- Uses DownloadUtils and FileUtils inside PackageManager to download and extract packages - Provides DownloadTask inside ApplicationController to observe installation progress - Moves directory name strings from PackageDatabase to PackageManager - PackageDatabase detects installed packages during sync()
Hooray Jenkins reported success with all tests good! |
- Modifies GameStarter to start games installed via PackageManager
Hooray Jenkins reported success with all tests good! |
- PackageManager directly installs the cached package if available - Disables combo-boxes while downloading
- PackageManager removes specified game package - Defines DeleteTask to perform delete operation asynchronously
Hooray Jenkins reported success with all tests good! |
- Copies the supplied sources.json file when it's absent in the local filesystem - Changes config directory structure - Removes all toAbsolutePath() calls during logging in PackageDatabase
- Prevents download button from getting buggy after closing settings menu - Binds package and version combo-boxes of both the controllers
Hooray Jenkins reported success with all tests good! |
Hooray Jenkins reported success with all tests good! |
The utility methods for directories are very specific for the launcher and even contain constants for the data directory name, cache directory, or application directory name. The new name should indicate this dedicated purpose. `FileUtils` are more general and not tightly coupled to launcher functionality. Some methods might be moved there in the future.
This is a replacement for `FileUtils.deleteDirectoryContent` which additionally ensures that the directory exists and is empty. The old method has been made private and is still used internally. - updated call to use `ensureEmptyDir` - added tests for `ensureEmptyDir`
…ls.ensureWritableDir` - introduce `LauncherManagedDirectory` enum for directories local to launcher installation path - introduce `DirectoryCreator` functional interface - refactor `getXYZDirectory` methods in the init task - make use of managed directory enum - make use of DirectoryCreator interface via method references - unify directory creation and error handling
Uh oh, something went wrong with the build. Need to check on that |
Hooray Jenkins reported success with all tests good! |
- use `!Files.exists(dir)` instead of `Files.notExists(dir)` like in ensureWritableDir - add `Files.isDirectory(dir)` check
Hooray Jenkins reported success with all tests good! |
if (!Files.isDirectory(directory)) { | ||
throw new IOException("Directory is not a directory! " + directory); | ||
} else { |
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.
I'm not entirely sure, if we want to put that here.
deleteDirectoryContent
will throw a NotDirectoryException
on calling Files.list(directory)
if directory
is not a directory. While this should be a well-understandable exception, I think it makes sense to check before-hand.
I put the check into ensureEmptyDir
to align it with ensureWritableDir
which includes this check as well, but maybe it would be better off in deleteDirectoryContent
...
@praj-foss @skaldarnar what do you think?
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 needs a revisit anyways. Some notes on the current state and where it might be headed:
Files.createDirectories(path)
will create directory (if possible) or return the directory if it exists. If it is no directory, it will throw an exception - pretty much what we are trying to do as a first step here and inensureWritableDir
. Maybe we can make better use of it.- I'm not really happy with the
void
return types and the exceptional behavior. Maybe we can hide that and instead exposeOptional<Path>
or the like for internal usage (as abstraction over the underlying file system operations). - Seems like we are building this up in multiple steps: (1) ensure directory exists, (2) ensure directory is writable, (3) ensure directory is empty, ... Not sure how we could build a nice functional interface for that, or whether it is actually worth it 🙄
- ... and file attributes: https://docs.oracle.com/javase/8/docs/api/java/nio/file/attribute/package-summary.html 🤷♂
Uh oh, something went wrong with the build. Need to check on that |
Hooray Jenkins reported success with all tests good! |
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.
@praj-foss @jdrueckert Left a bunch of comments such that we know where to continue 😉 Will hit that green button now and finally merge it, should make it easier to progress in smaller steps towards a new release.
private Path getLauncherDirectory(OperatingSystem os) throws LauncherStartFailedException { | ||
logger.trace("Init LauncherDirectory..."); | ||
final Path launcherDirectory = DirectoryUtils.getApplicationDirectory(os, DirectoryUtils.LAUNCHER_APPLICATION_DIR_NAME); | ||
private void initDirectory(Path dir, String errorLabel, DirectoryCreator... creators) |
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.
The whole set of methods dealing with directory creation, initialization, etc need to get a revisit. Cleaning up naming, adding Javadoc, refactoring (more) common code.
@@ -285,20 +275,6 @@ private Path getGameDataDirectory(OperatingSystem os, Path settingsGameDataDirec | |||
return gameDataDirectory; | |||
} | |||
|
|||
private TerasologyGameVersions getTerasologyGameVersions(Path launcherDirectory, Path gameDirectory, BaseLauncherSettings launcherSettings) { |
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.
Not sure whether this should be removed already (@praj-foss ?). I just threw it out because it was not used... Can re-add it easily from Git history if needed, though.
@@ -93,7 +93,7 @@ public synchronized TerasologyGameVersion getGameVersionForBuildVersion(GameJob | |||
} | |||
|
|||
public synchronized void loadGameVersionsFromPackageManager(GameSettings gameSettings, Path launcherDirectory, Path gameDirectory) { | |||
final Path cacheDirectory = launcherDirectory.resolve(DirectoryUtils.CACHE_DIR_NAME); | |||
final Path cacheDirectory = launcherDirectory.resolve(LauncherDirectoryUtils.CACHE_DIR_NAME); |
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.
I think all the launcher managed directories should be retrieved from the config/settings object, instead of resolving the path again and again.
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.
I agree with that.. It should look more sensible to have the PackageManager
directly depend on the settings object and resolve all required paths itself.
@@ -89,20 +90,100 @@ | |||
private static final long MB = 1024L * 1024; | |||
private static final long MINIMUM_FREE_SPACE = 200 * MB; |
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.
I guess this should more wide be used, or thrown out 🤔 maybe even a combination of (a) minimum absolute free space (e.g., 200mb) and (b) not more than 95% of disk space used...
@@ -89,20 +90,100 @@ | |||
private static final long MB = 1024L * 1024; | |||
private static final long MINIMUM_FREE_SPACE = 200 * MB; | |||
|
|||
private static final class DownloadTask extends Task<Void> implements ProgressListener { |
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.
Definitely needs Javadoc, and should probably live in its own class.
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.
+1 for Javadoc.. But won't this task be better encapsulated as an inner class, if it's not supposed to be used outside of ApplicationController
?
/** | ||
* Provides method to fetch all packages from a repository. | ||
*/ | ||
interface RepositoryHandler { |
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.
Should this be a @FunctionalInterface
?
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.
Sometimes I really forget that I'm on Java 8 😅
/** | ||
* Functional interface to abstract over directory creation. | ||
*/ | ||
public interface DirectoryCreator { |
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 have @FunctionalInterface
annotation
if (!Files.isDirectory(directory)) { | ||
throw new IOException("Directory is not a directory! " + directory); | ||
} else { |
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 needs a revisit anyways. Some notes on the current state and where it might be headed:
Files.createDirectories(path)
will create directory (if possible) or return the directory if it exists. If it is no directory, it will throw an exception - pretty much what we are trying to do as a first step here and inensureWritableDir
. Maybe we can make better use of it.- I'm not really happy with the
void
return types and the exceptional behavior. Maybe we can hide that and instead exposeOptional<Path>
or the like for internal usage (as abstraction over the underlying file system operations). - Seems like we are building this up in multiple steps: (1) ensure directory exists, (2) ensure directory is writable, (3) ensure directory is empty, ... Not sure how we could build a nice functional interface for that, or whether it is actually worth it 🙄
- ... and file attributes: https://docs.oracle.com/javase/8/docs/api/java/nio/file/attribute/package-summary.html 🤷♂
|
||
public static final String LAUNCHER_APPLICATION_DIR_NAME = "TerasologyLauncher"; | ||
public static final String GAME_APPLICATION_DIR_NAME = "Terasology"; | ||
public static final String GAME_DATA_DIR_NAME = "Terasology"; | ||
public static final String DOWNLOAD_DIR_NAME = "download"; | ||
public static final String TEMP_DIR_NAME = "temp"; | ||
public static final String CACHE_DIR_NAME = "cache"; |
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.
I think this can be removed .... thought I did it, now have to do it later 😅
@@ -75,6 +75,7 @@ message_error_loadSettings= | |||
message_error_operatingSystem= | |||
message_error_storeSettings= | |||
message_error_tempDirectory= | |||
message_error_cacheDirectory= |
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.
need to add actual text somewhere 🙄 double check if there is an error label w.r.t. to download
directory.
Summary
Provides an improved architecture for the PackageManager, adding features to support multiple online repositories and better handling of game packages. Fixes #451.
This architecture was inspired by classic Linux package managers like apt and pacman. The design was originally planned as shown in this diagram:
Testing
Coming soon
Outstanding before merging
PackageDatabase
supportPackageManager