diff --git a/BrainPortal/app/models/tool_config.rb b/BrainPortal/app/models/tool_config.rb index b6c5ba068..87582254f 100644 --- a/BrainPortal/app/models/tool_config.rb +++ b/BrainPortal/app/models/tool_config.rb @@ -625,9 +625,13 @@ def self.register_descriptor(descriptor, tool_name, tool_version) #:nodoc: def self.registered_boutiques_descriptor(tool_name, tool_version) #:nodoc: @_descriptors_ ||= {} key = [ tool_name, tool_version ] # two strings + @_descriptors_[key] = @_descriptors_[key]&.reload_if_file_timestamp_changed @_descriptors_[key] end + # This method returns a +BoutiquesDescriptor+ object associated with the + # with tool config either from cache, or if a specific path given from the corresponding file + # is specified from that file def boutiques_descriptor path = boutiques_descriptor_path.presence if ! path diff --git a/BrainPortal/lib/boutiques_support.rb b/BrainPortal/lib/boutiques_support.rb index f293624fc..531f08357 100644 --- a/BrainPortal/lib/boutiques_support.rb +++ b/BrainPortal/lib/boutiques_support.rb @@ -151,6 +151,7 @@ class ContainerImage < RestrictedHash ; end class BoutiquesDescriptor attr_accessor :from_file # not a hash attribute; a file name, for info + attr_accessor :mtime_of_file # not a hash attribute, a file timestamp, for caching def initialize(hash={}) @@ -175,10 +176,22 @@ def self.new_from_string(text) def self.new_from_file(path) obj = self.new_from_string(File.read(path)) - obj.from_file = path + obj.from_file = path + obj.mtime_of_file = File.mtime(path) obj end + # Refreshes the descriptor from the file if the file has changed. + # Returns self if the file has not changed, or a new descriptor + # if the file has changed. This is useful for quickly updating the descriptor(s) + # for small corrections or updates. Presently it is used only for the + # boutiques present in boutiques-descriptor subdirectories. + def reload_if_file_timestamp_changed + filepath = self.from_file + return self if filepath.blank? || (File.mtime(filepath) - self.mtime_of_file ).abs < 1 + self.class.new_from_file(filepath) + end + def validate BoutiquesSupport.validate(self) # amazingly, the JSON validator also work with our descriptor class end @@ -186,7 +199,8 @@ def validate # When dup'ing, also copy the from_file attribute def dup #:nodoc: copy = super - copy.from_file = self.from_file + copy.from_file = self.from_file + copy.mtime_of_file = self.mtime_of_file copy end