views:

148

answers:

2

I want to create ruby application (not rails). This is a console app which will need to persist some data. I'm using pstore as the database. I want to deploy this application as a gem.

My question is: where does my data live?

Currently I've created a data directory as a sibling to the bin directory in a standard gem layout. I would therefore, expect that the gem would be storing its data "inside itself" after it gets deployed. But when I do a local gem install to test, I find that the data is being stored locally to the project files, not somewhere inside the gems directory.

Of course it could be I simply mis-understand what "rake install_gem" is doing. Also, I am vaguely worried that if I need to sudo to install the gem, that it will actually be able to create the data file "inside itself" in the gem directory.

Can someone clarify this a little bit?

Thank you. John Schank

@makevoid - thanks for the reply. Here is the entirety of my main script. In /bin directory... (I added it to the main question because I'm not familiar with how to format content in a comment - and the pasted code looked awful.

#!/usr/bin/env ruby

$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'

require 'timesheet'

begin
  command_hash = TimesheetParser.parse
  store = YAML::Store.new("data/time_entries.yaml")
  tl = TimeLog.new(store)
  ts = Timesheet.new(tl)
  ts.process(command_hash)
rescue Exception => e
  raise if command_hash[:debug]
  puts e.message
+2  A: 

On Linux there are two common used locations for storing variable data.

/home/user/.application

If every user needs it's own storage this is usually done in the users home directory. The path for your storage in the users home directory should be

ENV["HOME"] + "/." + $application_name

/var/lib/application

If all users share the storage, or the application is intended to be run by only one user (most daemons), /var is the right place to store all kind of data.

  • /var/log for logs
  • /var/run for pid's
  • /var/lock for lock files
  • /var/www for httpservers
  • /var/tmp for not important but persistant data
  • /var/lib for all other data

The path for your storage in /var should be

"/var/lib/" + $application_name

Make sure, the permissions for this directory are such, that you don't have to let your application run as root.

johannes
I had thought of doing something like this, but I was concerned that it wouldn't work on windows. Is there a different twist on this theme to make it cross platform? or will this technique work on windows as well? (Does windows pre-define a "HOME" environment variable?)
jschank
Also, do I read that right, in that the appdata goes in a dotfile directory when in the user space, but in shared it goes in a non-dotfile folder for /var/lib? or should that be /var/lib/.application?Thanks!John
jschank
That's right. Dotfiles are hidden files in unix. So the user does normaly not see this configuration files in his home directory. There is no point in making them invisible in /var/lib.
johannes
Just the way i thought it should be when reading the question. However, the question regarding Windows made me curious. What would be a good practice there? I'm far away from Windows world.
Priit
A: 

You definitely don't want to store data inside the gem directory. The expected behaviour is that users can uninstall and reinstall gems without any problems. If you have data in your gem's installed directory, uninstalling the gem will destroy that data and piss off your users.

johannes has the right ideas for use on Linux. For a Mac the specific directories would be a little different. The same goes for Windows. You'll need to research what the right places are for each platform you want to target and have your code conditionally switch storage locations depending on what kind of host it runs on.

Don't forget to let users override your defaults. A way to do that will make them very happy :)

edebill
Hmm, about uninstalling, that makes sense.However, I'm not sure how to override the default in this case. Unless the user does something like set an environment variable. Because the app will create the data store in some location, and each command invoked would need to go back to that location. (and I don't want to have to specify the data store location with each command)Does anyone know how to determine the execution platform at runtime, in ruby?
jschank
there's a constant RUBY_PLATFORM that should let you determine platform. Environment variables are an excellent way to let people override the defaults. After all, if they're overriding defaults they should be a more sophisticated user who can handle something like that.
edebill