-
-
Notifications
You must be signed in to change notification settings - Fork 75
Allow specifying which files should be updated instead of all outdated files. #24
Comments
Not really. Maybe explain the context so I can think of an alternative.
|
I'm planning to use update4j as installer as well, so all business application files are downloaded in first run. My app has multiple files that users might make edits to, and usually I don't want them updated, but if the files are missing completely I want them downloaded. I think a flag "overwrite" that defaults true could be useful. I could of course make this in business app side by building the editable files from by making a copy on first run if they are missing, but it would be simpler and could be useful in other scenarios as well if it was included in update4j. Example config: Thank you by the way for update4j, this makes my life so much easier. I was thinking of building an updater from scratch but update4j has basically everything and much more than I need for update part. |
Wow! update4j as an installer is a cute idea I myself never thought about. The framework wasn't designed with this in mind. Nevertheless, you might still get it to work beautifully.
Let me clarify: You have a single global entry-point into your app, on initial run it actually does an installation but subsequent runs start the application.
Preferably -- but not strictly required by my solutions -- the app has some way to know whether it is the first run or not.
If this is the case, I have 3 working solutions. But first correct me if i'm wrong above.
One more question, how do you load the config in on the client-side? Do you just use default bootstrap? If yes, only one of the 3 solutions can work. The other 2 require custom bootstrap apps.
|
Yes, subsequent runs start the application, or update and then start if updates are required. I might be doing it all wrong, but so far on the client side I have completely separate update JAR I'm getting conf xml from URL input stream reader, doing Configuration.read, building a DSA public key object and generating a new custom UpdateHandler that is communicating with user update GUI. Then if updates are required I pass public key and custom update handler to config.update and start business jar if everything goes smoothly. |
So far you do it exactly as it should; namely, the updating logic should be kept in a separate jar. Before I post an answer to your initial question, let me tell you about configurable fields, which might be vital for installers and will help you understand one of the solutions: Say you want to install your app but first show a dialog and let the user choose an installation location. In update4j, this is the base path, but given the nature of the There are 2 ways of doing this: Refer the base path to a system property. Many config fields support property placeholders, which first lookup user listed properties then falls back to system properties and last to environment variables. The value is read when the config file is read. Say we have a config with the base path like: <base path=${my.base.path}> The code in the client-side updater: String myBasePath = letUserChoosePath();
System.setProperty("my.base.path", myBasePath);
// Only *after* setting system property we can read
Configuration config = letsReadTheConfig(); The problem with this approach is you cannot set anything after being read; here's where the other approach comes in: Create dynamic configuration. You can create dynamic configurations in code from scratch, or continue with an existing and modify fields via the Let's see how we can make a small modification. Say the base path was set to some default value and the user want's to change it: Configuration config = letsReadTheConfig();
String myBasePath = letUserChoosePath();
ConfigMapper mapper = config.generateXmlMapper();
// we can use this instance to hand modify the xml
mapper.basePath = myBasePath;
// now create a new with the modified value
Config newConfig = Configuration.parse(mapper); |
Now to answer your question: Create dynamic configuration reading the file comments. The Let's use it to create your own <file path="/editable.grf" size="9702" checksum="dccc1abd" comment="dontOverwrite" /> Now in your bootstrap app (what you call updater) we can dynamically create a new config with these files stripped if present on client machine: Configuration config = letsReadTheConfig();
Configuration actualConfig = modifyConfig(config);
private Configuration modifyConfig(Configuration config) throws IOException {
List<Integer> removeIndex = new ArrayList<>();
// I can't use enhanced for-loop since I need the index
for(int i = 0; i < config.getFiles().size(); i++)) {
FileMetadata file = config.getFiles().get(i);
if("dontOverwrite".equals(file.getComment()) && Files.exists(file.getPath())) {
removeIndex.add(i);
}
}
ConfigMapper mapper = config.generateXmlMapper();
// go from reverse so indices don't get messed up
for(int i = mapper.files.size() - 1; i >=0 ; i--) {
if(removeIndex.contains(i)) {
mapper.files.remove(i);
}
}
return Configuration.parse(mapper);
} This is a quite hacky solution, but is the closest I could get to your requirement. The other solutions are simpler but requires keeping track of 2 configs. Use different configs for installation and update. Probably the best way here. Simply put, if your application knows whether it is installing or updating you can have the bootstrap read a complete different config for the different tasks. Simple, isn't it? Installation config overwrites itself. A bit more complicated, but you only have one config at a time and is the only solution that work's with the default bootstrap. One of the file entries in the installer config is the config file itself. When the installation finishes you no longer need the original config so it will overwrite itself with the regular update config. This solution does not require you know if you are installing or updating, the config files do the magic themselves. |
At the moment I'm leaning towards keeping it simple and keep track of installation status and use different config after installation. I thank you for in-depth answer! |
I'm planning to add a feature to allow the user to skip files from being updated. Re-opening this issue. |
Is there a way to add some kind of flag to the configs to sync a file only if it missing from the client path, but if already present not to update even if the file is changed?
The text was updated successfully, but these errors were encountered: