diff --git a/BrainPortal/app/models/tool_config.rb b/BrainPortal/app/models/tool_config.rb index 8f85347cc..3c6f7c08d 100644 --- a/BrainPortal/app/models/tool_config.rb +++ b/BrainPortal/app/models/tool_config.rb @@ -593,15 +593,21 @@ 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 def boutiques_descriptor + if @_descriptor_ + @_descriptor_ = @_descriptor_.reload_if_file_timestamp_changed + key = [ self.tool.name, self.version_name ] # two strings + @_descriptors_[key] = @_descriptor_ + return @_descriptor_ + end path = boutiques_descriptor_path.presence if ! path return self.class.registered_boutiques_descriptor(self.tool.name, self.version_name) end - return @_descriptor_ if @_descriptor_ path = Pathname.new(path) path = Pathname.new(CBRAIN::BoutiquesDescriptorsPlugins_Dir) + path if path.relative? @_descriptor_ = BoutiquesSupport::BoutiquesDescriptor.new_from_file(path) diff --git a/BrainPortal/lib/boutiques_support.rb b/BrainPortal/lib/boutiques_support.rb index 84196a35c..4ca6a2e9d 100644 --- a/BrainPortal/lib/boutiques_support.rb +++ b/BrainPortal/lib/boutiques_support.rb @@ -52,8 +52,9 @@ def self.validate(json) # initialize above (top_prop_names etc). BoutiquesDescriptor = Class.new(RestrictedHash) do |klass| - allowed_keys top_prop_names # 'name', 'author' etc - attr_accessor :from_file # not a hash attribute; a file name, for info + allowed_keys top_prop_names # 'name', 'author' etc + 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 Input = Class.new(RestrictedHash) { allowed_keys input_prop_names } OutputFile = Class.new(RestrictedHash) { allowed_keys output_prop_names } @@ -89,10 +90,17 @@ 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 + def reload_if_file_timestamp_changed() + filepath = self.from_file + return self if filepath.blank? || File.mtime(filepath) == self.mtime_of_file + self.class.new_from_file(filepath) + end + def validate BoutiquesSupport.validate(self) # amazingly, the JSON validator also work with our descriptor class end @@ -100,7 +108,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