I'm interested in peoples' views on how best to store preferences and default settings in cross-platform applications.
I primarily work in node.js and Perl on *nix and Windows but I'm also interested in the bigger picture.
In the *nix world "dotfiles" (and directories) are very common with system-wide or application default settings generally residing in one path and user-specific settings in the home directory. Such files and dirs begin with a dot "." and are hidden by default from directory listings.
Windows has the registry which also has paths for defaults and per-user overrides.
Certain cross-platform apps do it their own way, Firefox uses JavaScript preference files.
Should a cross-platform app use one system across platforms or say dotfiles on *nix and registry on Windows? Does your favourite programming language have a library or module for accessing them in a standard way? Is there an emerging best practice or does everybody roll their own?
What about storing in DB? It is cluster-friendly and has been working great for us. In my last job we used to store them in a directory server.
Java has support in the form of Preferences API.
I am not a .Net guy but I think they have User Profiles.
Python specific discussion: What's the official way of storing settings for python programs?
Ruby on Rails: Rails: Best practice to store user settings?
I found
docs.python.org/lib/module-ConfigParser.html and
wxpython.org/docs/api/wx.ConfigBase-class.html
Related
With latest phpStorm 9 we have new feature called simultaneous tags editing.
This is generally very nice feature that i'd like to use, but i have one old project with very bad code with a lot of mixed PHP, HTML and JS code, where it breaks code.
I know i can disable this in settings->editor->General->simultaneous tag editing, but it disables this feature for whole phpStorm. Is there way to disable it only per one project?
Is there way to disable it only per one project?
Nope -- this is an IDE-wide setting.
The only possible solution I can think of is to have separate PhpStorm installation that will use custom folders to store IDE settings (look into idea.properties file from PhpStorm distribution, e.g. on Windows 7 it would typically be %PhpStorm-Install-Folder%\bin\idea.properties).
With IDE settings stored in different location you can now configure this installation with different settings (e.g. have that option turned off). Obviously, all settings here will be different to your original setup, unless you configure it the same way or will keep certain config files synced (e.g. Keymaps, Color, Web Servers, Live Templates and other things could easily be synced on file level).
Just remember to launch this installation when you want to work with that specific project.
Time and again I am faced with the issue of having multiple environments that must be configured individually for an application that would run in all of them (e.g. QA, regional production env's, dev, staging, etc.) and I am wondering what would be the best way to organize different configurations?
Would it be in the database? Different configuration files per environment? Or maybe the same file with different sections/xml tags? How would these be then deployed? Embedded within the app? Or put manually in after installation to be modified in-place?
This question is not technology-specific - I've worked with .net and Java, web-apps and desktop apps and this issue comes up time and again. I'm looking to learn different approaches to maybe adapt a hybrid to address this.
EDIT: There's one caveat that I must point out - when configuration is part of the deployed solution, it is generally installed under root user on the host. In large organizations developers usually don't have a root access to production hosts so any changes to the configuration require a new build and deployment. Needless to say this isn't the nicest approach - especially at organizations that have a very strict release process involving multiple teams and approval levels... (sigh I know!)
Borrowed from Jez Humble and David Farley's book "Continuous Delivery (page 41)", you can:
Your build scripts can pull configuration in and incorporate it into your binaries at build time.
Your packaging software can inject configuration at packaging time, such as when creating assemblies, ears, or gems.
Your deployment scripts or installers can fetch the necessary information or ask the user for it and pass it to your application at
deployment time as part of the installation process.
Your application itself can fetch configuration at startup time or run time.
It is considered bad practice by them to inject configuration files in build and compile times, because you should be able to deploy the same binary file to every environments.
My experience was that you could bake all configuration files for every environments (except sensitive information) to your deployment file (war, jar, zip, etc). And you design your application to take in an extra parameter when starts, to pickup the right sets of configuration files (from your extracted deployment file, or from local/remote file system if they are sensitive, or from a database) during application's startup time.
The question is difficult to answer because it's somewhat vague. There is no technology-agnostic approach to configuration as far as I know. Exactly how configuration is set up will depend on the language/technology in question.
I'm not familiar with .net but with java a popular approach is to have a maven build set up with different profiles. Each profile is specific to an environment. You can then define different properties files that have environment-specific values, an example from the above link is:
environment.properties - This is the default configuration and will be packaged in the artifact by default.
environment.test.properties - This is the variant for the test environment.
environment.prod.properties - This is basically the same as the test variant and will be used in the production environment.
You can then build your project as follows:
mvn -Pprod package
I have good news and bad news.
The good news is that Config4* (of which I am the maintainer) neatly addresses this issue with its support for adaptive configuration. Basically, this is the ability for a configuration file to adapt itself to the environment (including hostname, username, environment variables, and command-line options) in which it is running. Read Chapter 2 of the "Getting Started" manual for details. Don't worry: it is a short chapter.
The bad news is that, currently, Config4* implementations exist only for C++ and Java, so your .Net applications are out of luck. And even with C++ and Java applications, it won't make pragmatic sense to retrofit Config4* into an existing application. Because of this, I'd advise trying to use Config4* only in new applications.
Despite the bad news, I think it is worth your while to read the above-mentioned chapter of the Config4* documentation, because doing so may provide you with ideas that you can adapt to fit your needs.
Is there any API or tool that can automate software updating? It should take care of checking for updates from a URL for a provided list of files and downloading and replacing the ones that need updating. It would also be nice if it contained an authentication module so that only authorized parties could access the updates. It should be language-agnostic - takes a list of files without extra knowledge except their versions and replaces them with newly downloaded copies if on the site there are newer versions.
I'm specifically interested in something for the Windows platform, that would run on Win Xp to Win 7.
This makes me think about apt-get ...
take a look here, as well: Is there an auto-update framework for C++/Win32/MFC (like Sparkle)?
I did see some articles a while back about embedding subversion into your application to manage version control.
Edit:
http://svnbook.red-bean.com/en/1.5/svn.developer.html
Subversion has a modular design: it's implemented as a collection of libraries written in C. Each library has a well-defined purpose and application programming interface (API), and that interface is available not only for Subversion itself to use, but for any software that wishes to embed or otherwise programmatically control Subversion. Additionally, Subversion's API is available not only to other C programs, but also to programs written in higher-level languages such as Python, Perl, Java, and Ruby."
Just saw UpdateNode launching a pretty cool update and messaging system. It seems to be cross platform and free for Open Source.
UPDATE, did some further analysis on that, posted at: https://stackoverflow.com/a/22528011/3257300
For windows, I'd use Google Update, also known as omaha.
Since you didn't tag this question as windows, I'd also mention a UpdateEngine for Mac.
And (best of all) apt, which is available for free on all Debian-based Linux and BSD distributions, like Ubuntu
There is open source project WIPT inspired by APT of Debian Linux.
Head over to Launchpad and use a PPA: it is a Debian/Ubuntu repository management platform. Of course this is not really platform independent but it is language wise :-)
You should take a look at ClickThrough, I don't know much about it but it sounds similar to what you're looking for. As for authorization, I would imagine this to be handled by your webserver based on the URL.
InstallShield has an offering. Never used it but researched it a few years back but we decided on a roll your own solution.
InstallShield Update Manager
InstallShield Update Service
You didn't state what platform you needed this for. The easiest way I can think of doing this is with subversion using rsync.
The concept is to write a post-commit hook for subversion. This script would update a "working folder" on the repository machine and then use rsync to update the differences to another machine.
Data protection and authentication would be set up using rsync over ssh.
If this is for windows, you could try doing the same with cygwin installs on the two machines.
Good luck.
If you use .NET, I'm a happy customer of AppLife Update
CRONw is a scheduled execution service for Windows. (Sorry, I can't link it, I'm apparently limited to 1 as a new user. It's hosted on Sourceforge.)
Powershell is a Windows scripting language (Microsoft-official) that allows you to do most system administration operations you could conceivably want to do. It is very easy to pick up even if you haven't worked with it before.
I would say your best bet is to write a simple update script in Powershell and, optionally, set it up as a crontask so you don't have to manually execute it.
IIRC, Powershell is an optional install on XP, and CRONw requires you be running a 32-bit system. You didn't say, so I'd guess you're doing 32-bit, but the alternative bears mentioning.
And in all this, I'm assuming that the URLs you're describing are designed for this purpose - if they're not and you don't own them, it will rapidly become more suffering than you're willing to bear. (Making a computer navigate a human-readable website usually does.)
I want to enhance my browser-based web application with functionality that enables management of local files and folders. E.g. folder tree structures should be synchronized between local workstation and server via HTTP(S).
I am aware of security-related limitations in browser-based applications. However, there are some techniques that "work around" these issues:
Signed Java applets (full trust)
.NET Windows Forms browser controls (no joke, that works. Just the configuration is horrible)
ActiveX
My question is: What do you use/suggest, both technology and implementation practice? Key requirement is that the installation process is as simple as possible.
Thanks for your opinions!
Google Gears.
it lets you write Javascript applications with a much bigger platform support than the usual browser, and go 'unconnected' with local file access, cache and DB. and if/when connected it syncs to the central server.
available for several browsers on all platforms; but still under heavy evolution.
Both Gears and Adobe Air require the user to manually select a local file before you get any programmatic access. Very limited because of security considerations when it comes to local filesystem access, so no chance for any web based file sync type functionality there as far as I can see. Maybe I'm wrong about Adobe Air but this is definitely the case with gears. But If I'm wrong let me know!
Silverlight 4 (still in beta) allows file system access:
"Read and write files to the user’s MyDocuments, MyMusic, MyPictures and MyVideos folder (or equivalent for non-windows platforms) for example storage of media files and taking local copies of reports"
http://www.silverlight.net/getstarted/silverlight-4/
Definitely not ActiveX. No sense spending time on something that out-of-date.
Adobe AIR (essentially, Flash for the Desktop), is something that we considered in my last contract, as opposed to Java applets. Last I checked, though it's been several months, the installation of the AIR runtime environment was fast and easy
Your best bet might be to write a custom application that interacts with your web application. For example, Dropbox lets you synchronize files across computers by use of a background application that watches a Dropbox-enabled folder. It also lets you view your Dropbox files online through a web browser. The Dropbox web application then allows you to delete/move/copy files which is echoed in your local filesystem.
In the demo of Google Wave...
http://www.youtube.com/watch?v=v_UyVmITiYQ&fmt=18
...at 15:30 in, a group of img files are drag-and-dropped from the file system to the browser. The functionality is attributed to Google Gears. This seems a bit different from what Daniel OCallaghan and the official documentation suggest is possible.
Anybody know what's actually possible w/ Google Gear and the local file system?
To get an application installed on a new computer there seems to be two major approaches in current use:
Separate installer: Create a separate installer package
that creates all directories, files,
registry entries required by your
application (ie an MSI, InstallSheild etc) and then finally copies your application to the target computer.
Self installer: Include all required
installation steps in a component
that is part of your application. Then use this component to check and create required settings each time the main application executable is run. ie Just run the application to install.
I've used a few applications that corrupt their settings over time, and most had a separate installer. Therefore the only fix was to to re-install, sometimes with settings and even data being lost (very frustrating).
Also during software projects I've worked on, the separate installer approach often dictated spreading application specific knowledge across both the installer package and the actual application. Then, when code/functionality changes were made, both the installer and app needed to be updated. It always felt a bit too brittle and prone to human error.
So I'm currently leaning toward the self installer approach because of a simpler more robust installation/setup, ie just run the app. This self installing approach I feel would also lend itself a more robust application.
Integration with in application settings (options) would also be much more clean, in many cases the same component could perform both installation and settings management.
On the negative, however, performing these extra checks/steps each time the app starts might negatively impact startup times, and OS integration might be a bit more work then using a standard installer.
So which approach to people recommend and why?
(I'm most interested in installation of desktop rich client applications at present.)
There are pros and cons to both approaches:
Having an installer is the proper way to install necessary system components, like drivers, libraries, COM components and so on. Since many of these activities need elevated permissions the install may be performed by the administrator, while the application can be used by all users.
There may actually be requirements for a scriptable installation procedure in corporate environments.
Not having an installer opens the way to portable applications. If the program has everything in a directory, then this can simply be copied to a USB stick and be run on any system. This may of course not make sense for your particular kind of app, but that is for you to decide.
I'm not sure that the issue about corrupted settings is really important here. If settings are corrupted (why?) - how is the application to know what to do about it? OTOH the installer can of course also be written to not blindly overwrite any old settings. It all depends...
Edit: You write in your comment:
Even portable apps require certain configuration/settings, Isn't it better to have the main app check that settings are valid/exist on each startup, and only prompt the user when needed.
and again, it really depends on your needs. There are different types of configuration settings or preferences, and you have to decide individually:
Per-user configuration settings will be missing if the application is run for the first time by the current user. It can be helpful to show a message that it is missing, and how to create it. For example in FlameRobin (a database administration program for Firebird) we have a message that is shown when no registered servers and databases are found on program startup, and how to register them.
Per-user settings for UI behaviour will also be missing, but there are default values for them. The user will get the default behaviour of the application, and can later change things in the option dialog. Since it is best to minimize the number of such settings, and since the defaults should be what most users expect or what works best in the general case, there is also no need to bother the user at program startup.
Some configuration may be not per-user, but per-program. This is generally stored in a location where standard users have no write access, so checking for this and prompt the user to enter it is not really helpful. What could be done is to start an external program, asking the standard user for the account with sufficient privileges and its password.
Going with a separate installer is the "better" way from my point of view. Making an application self-installing does not only add additional workload to the application itself, it also "works around" any installer system of the underlying operating system (like MSI on windows).
And if the application corrupt its settings over time it's broken and need to be fixed. How should corrupt settings be handled by the self-installer? Just overwrite it with the defaults? Users will get annoyed by that too, so having them to run a separate installer and choosing a "repair" option makes this at least more transparent.
I would recommend a separate installer that can do the following:
Install a new installation
Repair an existing installation
Remove an existing installation
The reason I recommend these options is because that is what I have come to expect for installers in Windows environments.
The reasons I recommend separating installation and application logic into two different applications area:
There may be conflicts between dependencies used used by the installer and application.
I want to be sure my team don't inadvertently use classes in the dependencies from the installer framework when developing the application.
Thanks for your feedback. I'm starting to think something along these lines would be a good compromise approach:
Choose the self installer approach by creating an installer component (class library) that is referenced by the main application.
This component is a core part of the application and is responsible for ensuring all configuration/settings exist and are valid.
The main app. executable, on each run, asks this component to check existance/validity of settings, and only prompt the user when required. This could be easily done in a user friendly manner by grouping all setting issues and presenting them in a single GUI (avoids a sequence of annoying dialogues).
For OS integration, the installer component (in the case of Windows) ensures an entry is added to the "Add Remove Programs" list for the application, as well as any other OS required conventions.
Within the application the standard options/settings screen is also provided by the installer component. This avoids duplicating settings management code.
I've asked this question because I've met many non-technical users who ask why they cannot simply copy an application from one computer to another, they can do this with their data (eg photos, documents etc). It's an extremely valid question, in particular for GUI oriented desktop applications.
Separate installers are certainly "the way it's been done" on Windows for many years. For drivers/system components, obviously they are often a necessity. But for desktop GUI style applications I don't believe they are the best in terms of simplicity and realiability for the user/customer.