class Nucleon::Plugin::Project

Public Class Methods

build_info(type, data) click to toggle source
# File lib/core/plugin/project.rb, line 877
def self.build_info(type, data)  
  data = data.split(/\s*,\s*/) if data.is_a?(String)
  super(type, data)
end
collection() click to toggle source
# File lib/core/plugin/project.rb, line 14
def self.collection
  @@projects
end
open(directory, provider, options = {}) click to toggle source
# File lib/core/plugin/project.rb, line 21
def self.open(directory, provider, options = {})
  config    = Config.ensure(options)    
  directory = File.expand_path(Util::Disk.filename(directory))
  
  if ! @@projects.has_key?(directory) || config.get(:reset, false)
    logger.info("Creating new project at #{directory} with #{provider}")
    
    return Nucleon.project(config.import({
      :name      => directory,
      :directory => directory
    }), provider)
    
  else
    logger.info("Opening existing project at #{directory}")
  end
  
  @@projects[directory]
end
translate(data) click to toggle source
# File lib/core/plugin/project.rb, line 884
def self.translate(data)
  options = super(data)
  
  case data        
  when String
    options = { :url => data }
  when Hash
    options = data
  end
  
  if options.has_key?(:url)
    if matches = translate_reference(options[:url])
      options[:provider] = matches[:provider]
      options[:url]      = matches[:url]
      options[:revision] = matches[:revision] unless options.has_key?(:revision)
      
      logger.debug("Translating project options: #{options.inspect}")  
    end
  end
  options
end
translate_reference(reference, editable = false) click to toggle source
# File lib/core/plugin/project.rb, line 908
def self.translate_reference(reference, editable = false)
  # ex: github:::username/project[branch/revision]
  if reference && reference.match(/^\s*([a-zA-Z0-9_-]+):::([^\]\s]+)\s*(?:\[\s*([^\]\s]+)\s*\])?\s*$/)
    provider = $1
    url      = $2
    revision = $3
    
    logger.debug("Translating project reference: #{provider}  #{url}  #{revision}")
    
    if provider && Nucleon.loaded_plugins(:project).keys.include?(provider.to_sym)
      klass        = Nucleon.class_const([ :nucleon, :project, provider ])          
      expanded_url = klass.send(:expand_url, url, editable) if klass.respond_to?(:expand_url)
    end
    expanded_url = url unless expanded_url
    
    info = {
      :provider  => provider,
      :reference => url,
      :url       => expanded_url,
      :revision  => revision
    }
    
    logger.debug("Project reference info: #{info.inspect}")
    return info
  end
  nil
end

Public Instance Methods

add_remote_url(name, url, options = {}) { |config, url| ... } click to toggle source
# File lib/core/plugin/project.rb, line 705
def add_remote_url(name, url, options = {})
  if can_persist?
    localize do
      config = Config.ensure(options)
    
      if url = extension_set(:add_remote_url, url, { :name => name, :config => config })
        url = translate_edit_url(url) if name == :edit && config.get(:translate, true)
        
        logger.info("Adding project remote url #{url} to #{name}")    
        yield(config, url) if block_given?
      end
    end
  else
    logger.warn("Project #{self.name} does not meet the criteria for persistence and can not have remotes") 
  end
end
add_subproject(path, url, revision, options = {}) { |config| ... } click to toggle source
# File lib/core/plugin/project.rb, line 539
def add_subproject(path, url, revision, options = {})    
  success = true
  
  if can_persist?
    localize do
      config = Config.ensure(options).import({ :path => path, :url => url, :revision => revision })
    
      if extension_check(:add_project, { :config => config })
        logger.info("Adding a sub project to #{config[:path]} from #{config[:url]} at #{config[:revision]}")
    
        success = yield(config) if block_given?
      
        if success
          extension(:add_project_success, { :config => config })
        
          config.init(:files, '.')
          config.init(:message, "Adding project #{config[:url]} to #{config[:path]}")
        
          commit(config[:files], { :message => config[:message] })          
          update_subprojects
        end
      else
        success = false
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects")   
  end
  success
end
cache() click to toggle source
# File lib/core/plugin/project.rb, line 139
def cache
  @cache
end
can_persist?() click to toggle source
# File lib/core/plugin/project.rb, line 99
def can_persist?
  return top?(directory) if directory
  false
end
checkout(revision) { |success| ... } click to toggle source
# File lib/core/plugin/project.rb, line 414
def checkout(revision)
  success = false
  
  if can_persist?
    localize do      
      if extension_check(:checkout, { :revision => revision })
        logger.info("Checking out project #{name} revision: #{revision}")
    
        success = true
        success = yield(success) if block_given?
      
        if success
          set(:revision, revision)
        
          extension(:checkout_success, { :revision => revision })
          load_subprojects
        end
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can not checkout a revision")
  end
  success
end
commit(files = '.', options = {}) { |config, time, user, message| ... } click to toggle source
# File lib/core/plugin/project.rb, line 441
def commit(files = '.', options = {})
  success = false
  
  if can_persist?
    localize do
      config = Config.ensure(options)
    
      if extension_check(:commit, { :files => files, :config => config })
        logger.info("Committing changes to project #{name}: #{files.inspect}")
    
        time     = Time.new.strftime("%Y-%m-%d %H:%M:%S")
        user     = config.delete(:user, ENV['USER'] + '@' + fact(:fqdn))
    
        message  = config.get(:message, '')
        message  = 'Saving state: ' + ( files.is_a?(Array) ? "\n\n" + files.join("\n") : files.to_s ) if message.empty?
    
        user = 'UNKNOWN' unless user && ! user.empty?
    
        logger.debug("Commit by #{user} at #{time} with #{message}")          
        success = yield(config, time, user, message) if block_given?
      
        if success
          load_revision
        
          extension(:commit_success, { :files => files })
    
          if ! parent.nil? && config.get(:propogate, true)
            logger.info("Commit to parent as parent exists and propogate option given")
      
            parent.load_revision
            parent.commit(directory, config.import({
              :message => "Updating #{path}: #{message}"
            }))
          end
        end
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can be committed to")                
  end
  success     
end
config(name, options = {}) { |config| ... } click to toggle source
# File lib/core/plugin/project.rb, line 269
def config(name, options = {})
  localize do
    config = Config.ensure(options)
    can_persist? && block_given? ? yield(config) : nil
  end
end
delete_config(name, options = {}) { |config| ... } click to toggle source
# File lib/core/plugin/project.rb, line 292
def delete_config(name, options = {})
  localize do
    config = Config.ensure(options)
  
    if can_persist? && extension_check(:delete_config, { :name => name, :config => config })
      logger.info("Removing project #{self.name} configuration: #{name}")
  
      yield(config) if block_given?
    end
  end
end
delete_remote(name) { || ... } click to toggle source
# File lib/core/plugin/project.rb, line 753
def delete_remote(name)
  if can_persist?
    localize do
      if extension_check(:delete_remote, { :name => name })
        logger.info("Deleting project remote #{name}")  
        yield if block_given?
      end
    end
  else
    logger.warn("Project #{self.name} does not meet the criteria for persistence and can not have remotes") 
  end
end
delete_subproject(path) { |config| ... } click to toggle source
# File lib/core/plugin/project.rb, line 572
def delete_subproject(path)    
  success = true
  
  if can_persist?
    localize do
      config = Config.new({ :path => path })
    
      if extension_check(:delete_project, { :config => config })
        logger.info("Deleting a sub project at #{config[:path]}")
    
        success = yield(config) if block_given?
      
        if success
          extension(:delete_project_success, { :config => config })
        
          config.init(:files, '.')
          config.init(:message, "Removing project at #{config[:path]}")
        
          commit(config[:files], { :message => config[:message] })      
          update_subprojects
        end
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects") 
  end
  success
end
directory(default = nil) click to toggle source
# File lib/core/plugin/project.rb, line 206
def directory(default = nil)
  get(:directory, default)
end
each() { |path, project| ... } click to toggle source
# File lib/core/plugin/project.rb, line 628
def each
  if can_persist?
    localize do
      logger.info("Iterating through all sub projects of project #{name}")
    
      subprojects.each do |path, project|
        extension(:process_project, { :project => project })
      
        logger.debug("Running process on sub project #{path}")
        yield(path, project)  
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects") 
  end
end
edit_url(default = nil) click to toggle source
# File lib/core/plugin/project.rb, line 188
def edit_url(default = nil)
  get(:edit, default)
end
full_path(local_path) click to toggle source
# File lib/core/plugin/project.rb, line 991
def full_path(local_path)
  File.join(directory, local_path)
end
ignore(files) { || ... } click to toggle source
# File lib/core/plugin/project.rb, line 486
def ignore(files)
  return unless directory && manage_ignore?
  
  @@ignore_lock.synchronize do
    files = nil
    files = yield if block_given?
    commit(files, { :message => "Adding project ignores." }) if files
  end
end
init_project() click to toggle source
# File lib/core/plugin/project.rb, line 76
def init_project
  init_auth
  init_parent
  init_remotes
  load_revision
end
local_path(file_path) click to toggle source
# File lib/core/plugin/project.rb, line 985
def local_path(file_path)
  file_path.gsub(directory + File::SEPARATOR, '')  
end
localize(path = nil) { || ... } click to toggle source
# File lib/core/plugin/project.rb, line 969
def localize(path = nil)
  prev_directory = Dir.pwd
  path           = directory if path.nil?
  
  Dir.chdir(path)
  
  result = safe_exec(true) do
    yield  
  end
  
  Dir.chdir(prev_directory)
  result
end
manage_ignore=(ignore) click to toggle source
# File lib/core/plugin/project.rb, line 128
def manage_ignore=ignore
  set(:manage_ignore, ignore)
end
manage_ignore?() click to toggle source
# File lib/core/plugin/project.rb, line 132
def manage_ignore?
  get(:manage_ignore, false)
end
normalize(reload) click to toggle source
# File lib/core/plugin/project.rb, line 43
def normalize(reload)
  super
  
  set_directory(Util::Disk.filename(get(:directory, Dir.pwd)))
  register
  
  set_url(get(:url)) if get(:url, false)
  
  myself.plugin_name = path if ! plugin_name || plugin_name == plugin_provider
  
  ui.resource = plugin_name
  logger      = plugin_name
  
  if keys = delete(:keys, nil)
    set(:private_key, keys[:private_key])
    set(:public_key, keys[:public_key])
  end
  
  extension(:normalize)
  
  init_project
  extension(:init)
  
  pull if get(:pull, false)
  
  unless reload
    @cache = Util::Cache.new(directory, Nucleon.sha1(plugin_name), '.project_cache')
    init_cache
  end
end
parent(default = nil) click to toggle source
# File lib/core/plugin/project.rb, line 251
def parent(default = nil)
  get(:parent, default)
end
path() click to toggle source
# File lib/core/plugin/project.rb, line 212
def path
  if parent.nil?
    return directory  
  end
  directory.gsub(parent.directory + File::SEPARATOR, '')
end
private_key() click to toggle source
# File lib/core/plugin/project.rb, line 151
def private_key
  get(:private_key, nil)
end
private_key_str() click to toggle source
# File lib/core/plugin/project.rb, line 155
def private_key_str
  return Util::Disk.read(private_key) if private_key
  nil
end
public_key() click to toggle source
# File lib/core/plugin/project.rb, line 160
def public_key
  get(:public_key, nil)
end
public_key_str() click to toggle source
# File lib/core/plugin/project.rb, line 164
def public_key_str
  return Util::Disk.read(public_key) if public_key
  nil
end
pull(remote = :origin, options = {}) { |config, remote| ... } click to toggle source
# File lib/core/plugin/project.rb, line 769
def pull(remote = :origin, options = {})
  config  = Config.ensure(options).import({ :remote => remote })
  success = false
  
  if can_persist?
    localize do      
      if extension_check(:pull, { :directory => directory, :config => config })
        remote = config.delete(:remote)
            
        if remote(remote)
          logger.info("Pulling from #{remote} into #{directory}") 
          success = yield(config, remote) if block_given?
        end
        
        if success
          update_subprojects
           
          extension(:pull_success, { :directory => directory, :remote => remote, :config => config })          
           
          if ! parent.nil? && config.get(:propogate, true)
            logger.debug("Commit to parent as parent exists and propogate option was given")
      
            parent.commit(directory, config.import({
              :message     => "Pulling updates for subproject #{path}",
              :allow_empty => true
            }))
          end
        end
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can not pull from remotes")       
  end
  success
end
push(remote = :edit, options = {}) { |config, push_remote| ... } click to toggle source
# File lib/core/plugin/project.rb, line 807
def push(remote = :edit, options = {})
  config  = Config.ensure(options).import({ :remote => remote })
  success = false
  
  push_project = lambda do |push_remote|
    logger.info("Pushing to #{push_remote} from #{directory}") 
    success = yield(config, push_remote) if block_given? && pull(push_remote, config)  
  end
  
  if can_persist?
    localize do     
      if extension_check(:push, { :directory => directory, :config => config })
        remote = config.delete(:remote)
        tries  = config.delete(:tries, 5)
      
        # TODO: Figure out a better way through specialized exception handling
        if remote(remote)
          begin
            success = push_project.call(remote)
            raise unless success
            
          rescue
            tries -= 1
            retry if tries > 0
          end
        end
        
        if success
          config.delete(:revision)
        
          extension(:push_success, { :directory => directory, :remote => remote, :config => config })  
    
          if config.get(:propogate, true)
            unless parent.nil?
              propogate_up = config.get(:propogate_up, nil)
              
              if propogate_up.nil? || propogate_up
                logger.debug("Commit to parent as parent exists and propogate option was given")
                parent.push(remote, Config.new(config.export.dup).import({ 
                  :propogate_up   => true, 
                  :propogate_down => false 
                }))
              end
            end
            
            logger.debug("Pushing sub projects")
            
            propogate_down = config.get(:propogate_down, nil)
      
            if propogate_down.nil? || propogate_down
              each do |path, project|
                project.push(remote, Config.new(config.export.dup).import({ 
                  :propogate_up   => false, 
                  :propogate_down => true 
                }))
              end
            end
          end
        end
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can not push to remotes") 
  end
  success
end
reference() click to toggle source
# File lib/core/plugin/project.rb, line 145
def reference
  get(:reference, nil)
end
register() click to toggle source
# File lib/core/plugin/project.rb, line 86
def register
  super
  if directory
    lib_path = File.join(directory, 'lib')
    if File.directory?(lib_path)
      Nucleon.register(lib_path)
    end
  end
end
remote(name) { || ... } click to toggle source
# File lib/core/plugin/project.rb, line 669
def remote(name)
  url = nil
  if can_persist?
    localize do
      logger.info("Fetching remote url for #{name}")
      url = yield if block_given?
    end
  end
  url
end
revision(default = nil) click to toggle source
# File lib/core/plugin/project.rb, line 263
def revision(default = nil)
  get(:revision, default).to_s
end
set_config(name, value, options = {}) { |config, value| ... } click to toggle source
# File lib/core/plugin/project.rb, line 278
def set_config(name, value, options = {})
  localize do
    config = Config.ensure(options) 
  
    if can_persist? && value = extension_set(:set_config, value, { :name => name, :config => config })
      logger.info("Setting project #{self.name} configuration: #{name} = #{value.inspect}")
  
      yield(config, value) if block_given?
    end
  end
end
set_edit_url(url) click to toggle source
# File lib/core/plugin/project.rb, line 194
def set_edit_url(url)
  url = url.strip
  if url && url = extension_set(:set_edit_url, url)      
    logger.info("Setting project #{name} edit url to #{url}")
    
    set(:edit, url)
    set_remote(:edit, url)
  end
end
set_host_remote(name, hosts, path, options = {}) click to toggle source
# File lib/core/plugin/project.rb, line 724
def set_host_remote(name, hosts, path, options = {})
  if can_persist?
    localize do
      config = Config.ensure(options).import({ :path => path, :translate => false })
      hosts  = array(hosts)
    
      unless hosts.empty?
        if hosts = extension_set(:set_host_remote, hosts, { :name => name, :config => config })
          unless ! hosts || hosts.empty?
            path = config.delete(:path)
        
            logger.info("Setting host remote #{name} for #{hosts.inspect} at #{path}") 
            set_remote(name, translate_url(hosts.shift, path, config.export), config)
      
            hosts.each do |host|
              logger.debug("Adding remote url to #{host}")
              add_remote_url(name, translate_url(host, path, config.export), config)
            end
          end
        end
      end
    end
  else
    logger.warn("Project #{self.name} does not meet the criteria for persistence and can not have remotes") 
  end
end
set_location(directory) { || ... } click to toggle source
# File lib/core/plugin/project.rb, line 241
def set_location(directory)
  set_directory(directory)
      
  yield if block_given?
  
  init_project
end
set_remote(name, url, options = {}) { |url| ... } click to toggle source
# File lib/core/plugin/project.rb, line 682
def set_remote(name, url, options = {})
  config = Config.ensure(options)
  
  if can_persist?
    localize do
      unless url.strip.empty? 
        if url = extension_set(:set_remote, url, { :name => name })
          delete_remote(name)
          
          url = translate_edit_url(url) if name == :edit && config.get(:translate, true)
  
          logger.info("Setting project remote #{name} to #{url}")
          yield(url) if block_given?
        end
      end
    end
  else
    logger.warn("Project #{self.name} does not meet the criteria for persistence and can not have remotes") 
  end
end
set_url(url) click to toggle source
# File lib/core/plugin/project.rb, line 177
def set_url(url)
  if url && url = extension_set(:set_url, url.strip)      
    logger.info("Setting project #{name} url to #{url}")
    
    set(:url, url)
    set_remote(:origin, url)
  end
end
subproject?(path) click to toggle source
# File lib/core/plugin/project.rb, line 113
def subproject?(path)
  false
end
subprojects(default = nil) click to toggle source
# File lib/core/plugin/project.rb, line 257
def subprojects(default = nil)
  get(:subprojects, default)
end
top?(path) click to toggle source
# File lib/core/plugin/project.rb, line 106
def top?(path)
  return true if File.directory?(path)
  false
end
translate_edit_url(url, options = {}) { |config| ... } click to toggle source
# File lib/core/plugin/project.rb, line 957
def translate_edit_url(url, options = {})
  config = Config.ensure(options)
  
  if block_given?
    temp_url = yield(config)
    url      = temp_url if temp_url
  end
  url
end
translate_reference(reference, editable = false) click to toggle source
# File lib/core/plugin/project.rb, line 938
def translate_reference(reference, editable = false)
  myself.class.translate_reference(reference, editable)
end
translate_url(host, path, options = {}) { |config| ... } click to toggle source
# File lib/core/plugin/project.rb, line 944
def translate_url(host, path, options = {})
  config = Config.ensure(options)
  url    = "#{host}/#{path}"
  
  if block_given?
    temp_url = yield(config)
    url      = temp_url if temp_url
  end
  url
end
url(default = nil) click to toggle source
# File lib/core/plugin/project.rb, line 171
def url(default = nil)
  get(:url, default)
end

Protected Instance Methods

init_auth() { || ... } click to toggle source
# File lib/core/plugin/project.rb, line 333
def init_auth
  if can_persist?
    localize do
      logger.info("Initializing project #{name} authorization")
      yield if block_given?
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence can not be authorized")
  end
end
init_cache() click to toggle source
# File lib/core/plugin/project.rb, line 326
def init_cache
  # Override in providers if needed
end
init_parent() click to toggle source
# File lib/core/plugin/project.rb, line 347
def init_parent
  delete(:parent)
  
  logger.info("Initializing project #{name} parents")
      
  if top?(directory)
    logger.debug("Project #{name} has no parents to initialize")
  else
    search_dir = directory
    last_dir   = nil
    
    while File.directory?((search_dir = File.expand_path('..', search_dir)))
      logger.debug("Scanning directory #{search_dir} for parent project")
      
      unless last_dir.nil? || last_dir != search_dir
        break
      end
      if project_directory?(search_dir)
        logger.debug("Directory #{search_dir} is a valid parent for this #{plugin_provider} project")
        
        project = myself.class.open(search_dir, plugin_provider)
        
        extension(:init_parent, { :parent => project })
        
        set(:parent, project)
        logger.debug("Setting parent to #{parent.inspect}")
        break;
      end
      last_dir = search_dir        
    end      
  end
end
init_remotes() { || ... } click to toggle source
# File lib/core/plugin/project.rb, line 648
def init_remotes
  if can_persist?
    localize do
      logger.info("Initializing project #{name} remotes")
    
      origin_url = url
      origin_url = yield if block_given?
    
      if origin_url && origin_url = extension_set(:init_remotes, origin_url).to_s.strip
        set(:url, origin_url)
        set_edit_url(translate_edit_url(url))
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can not have remotes")
  end
end
load_revision() { || ... } click to toggle source
# File lib/core/plugin/project.rb, line 383
def load_revision
  if can_persist?
    localize do
      logger.info("Loading project #{plugin_name} revision")
      
      specified_revision = get(:revision, nil)
      
      current_revision = revision.to_s
      current_revision = yield if block_given?
      
      if current_revision && extended_revision = extension_set(:load_revision, specified_revision).to_s.strip
        if extended_revision.empty?
          extended_revision = current_revision  
        end
        
        set(:revision, extended_revision)
        checkout(extended_revision) if current_revision != extended_revision     
         
        logger.debug("Loaded revision: #{revision}")
    
        load_subprojects
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and has no revision")
  end
end
load_subprojects(options = {}) { |project_path, data| ... } click to toggle source
# File lib/core/plugin/project.rb, line 499
def load_subprojects(options = {})
  subprojects = {}
  
  if can_persist?
    config = Config.ensure(options)
    
    logger.info("Loading sub projects for project #{name}")
    
    subproject_config(config).each do |path, data|
      project_path = File.join(directory, path)
      
      if File.directory?(project_path)
        logger.debug("Checking if project path #{project_path} is a valid sub project")
         
        add_project = true
        add_project = yield(project_path, data) if block_given?
        
        if add_project
          logger.debug("Directory #{project_path} is a valid sub project for this #{plugin_provider} project")
          
          project = myself.class.open(project_path, plugin_provider)
          
          extension(:load_project, { :project => project })
          subprojects[path] = project
        else
          logger.warn("Directory #{project_path} is not a valid sub project for this #{plugin_provider} project")   
        end
      else
        logger.warn("Sub project configuration points to a location that is not a directory: #{project_path}")  
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects")    
  end
  set(:subprojects, subprojects)
end
project_directory?(path, require_top_level = false) click to toggle source
# File lib/core/plugin/project.rb, line 119
def project_directory?(path, require_top_level = false)
  path = File.expand_path(path)    
  return true if File.directory?(path) && (! require_top_level || top?(path))
  false
end
set_directory(directory) click to toggle source
# File lib/core/plugin/project.rb, line 221
def set_directory(directory)
  if Util::Data.empty?(directory)
    current_directory = Dir.pwd
  else
    current_directory = File.expand_path(Util::Disk.filename(directory))
  end
  
  if current_directory = extension_set(:set_directory, current_directory)
    logger.info("Setting project #{name} directory to #{current_directory}")
    
    @@projects.delete(get(:directory)) if get(:directory)
    @@projects[current_directory] = myself
  
    set(:directory, current_directory)
  end
end
subproject_config(options = {}) { |config| ... } click to toggle source
# File lib/core/plugin/project.rb, line 306
def subproject_config(options = {})    
  result = {}
  
  localize do
    if can_persist?
      config = Config.ensure(options)
      result = yield(config) if block_given?
        
      extension(:subproject_config, { :config => result })
  
      logger.debug("Subproject configuration: #{result.inspect}")
    end
  end
  result
end
update_subprojects(options = {}) { |config| ... } click to toggle source
# File lib/core/plugin/project.rb, line 603
def update_subprojects(options = {})
  if can_persist?
    localize do
      config = Config.ensure(options)
      
      if extension_check(:update_projects)
        logger.info("Updating sub projects in project #{name}")
    
        success = false
        success = yield(config) if block_given?
      
        if success
          extension(:update_projects_success)
          load_subprojects
        end
      end
    end
  else
    logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects") 
  end
end