willymacoy has asked for the wisdom of the Perl Monks concerning the following question:

How can I tell whether I am running a module in development, or it has been installed?

Here is my challenge: I want to read a config file that might be different in development than in production. And they might be on the same machine. I use File::Sharedir for my read-only files, and that returns a different location in each case. But that location is not really ideal for config files. It is too obscure.

File::UserConfig does want I want, but returns the same directory during development as after installation.

How do others manage dev/prod config files without defining them absolutely in code?

Replies are listed 'Best First'.
Re: Development config files
by moritz (Cardinal) on May 15, 2011 at 11:36 UTC

    This is my approach:

    I have one config file that the app always reads, independently of the current run mode.

    It's in JSON, but that's not really import - import is that you can have nested hashes. It looks like this, when written as Perl data structure:

    my $conf = { app_home => '/path/to/app/', other_key => 'other_value', dev => { app_home => '/other/path', }, prod => { other_key => 'foo bar', }, };

    Now when I ask my app for a config value, it first looks up in the sub hash of the same keys as the current run mode (dev, test, prod, staging, ...), and if it doesn't exist, it falls back to the same key at the top level hash.

    (This is roughly the same as having a general config file, and separate config files for each runmode, but it saves you the pain of having separate paths for them).

    I determine the run mode by environment variables, and for example the tests automatically set it test.

Re: Development config files
by John M. Dlugosz (Monsignor) on May 15, 2011 at 09:13 UTC
    I ran into a situation with Catalyst a few weeks ago. It reads a local config file if one is found. It has a different name. I don't put that file into the installer, but it holds different settings for the development environment.

      Thanks John

      How did you "I don't put that file into the installer"?

        I listed it in the MANIFEST.SKIP file.

        I actually got a little more complex since I may want to have "testing" settings on the test server. So I saved the file under a different name, which is in the manifest and is totally ignored by the app. To turn it on in developent, I made a symbolic link as the APP_local.conf file the app looks for. In a different environment (some test server) I can rename it to enable the testing settings.

        The app is written so the stuff in APP_local.conf overrides what's in APP.conf, if such a file is found. You might search for the discussion from a few weeks (or months?) ago.

Re: Development config files
by Corion (Patriarch) on May 15, 2011 at 08:22 UTC

    How do you differentiate between the two, as a human?

      I have sat here and asked myself that question. With no It Just Works answer.

      One way is have a file in my module-sharedir that doesn't get installed when I use File::ShareDir::Install. I would simply test for that file and I would know.

      I could put a file there, have Makefile.PL remove it, and replace it before exiting.

      If File::UserConfig gave different results like File::ShareDir does then I would be laughing.

        My setup is to have the configuration file passed on the command line. I have different shell scripts that (re)start the development and production process, and they supply the different configuration files to the program.

        Personally, I would hardcode/supply only a single, very basic configuration with the module itself. Provide the option to write a fresh configuration file based on the current environment. Almost all web frameworks provide such helper applications.

      TIL the perl has a -s command line switch.

      Thanks