lib/ghtorrent/ghtorrent.rb
def ensure_repo(user, repo, recursive = false)

      repos = db[:projects]
      curuser = ensure_user(user, false, false)

      if curuser.nil?
        warn "Could not find user #{user}"
        return
      end

      currepo = repos.first(:owner_id => curuser[:id], :name => repo)

      unless currepo.nil?
        debug "Repo #{user}/#{repo} exists"
        return refresh_repo(user, repo, currepo)
      end

      r = retrieve_repo(user, repo, true)

      if r.nil?
        warn "Could not retrieve repo #{user}/#{repo}"
        return
      end

      if r['owner']['login'] != curuser[:login]
        info "Repo changed owner from #{curuser[:login]} to #{r['owner']['login']}"
        curuser = ensure_user(r['owner']['login'], false, false)
      end

      repos.insert(:url => r['url'],
                   :owner_id => curuser[:id],
                   :name => r['name'],
                   :description => unless r['description'].nil? then r['description'][0..254] else nil end,
                   :language => r['language'],
                   :created_at => date(r['created_at']),
                   :updated_at => date(Time.now),
                   :etag => unless r['etag'].nil? then r['etag'] end)

      unless r['parent'].nil?
        parent_owner = r['parent']['owner']['login']
        parent_repo = r['parent']['name']

        parent = ensure_repo(parent_owner, parent_repo)

        if parent.nil?
          warn "Could not find repo #{parent_owner}/#{parent_repo}, parent of: #{user}/#{repo}"
          repos.filter(:owner_id => curuser[:id], :name => repo).update(:forked_from => -1)
        else
          repos.filter(:owner_id => curuser[:id], :name => repo).update(:forked_from => parent[:id])
          info "Repo #{user}/#{repo} is a fork of #{parent_owner}/#{parent_repo}"

          unless ensure_fork_point(user, repo).nil?
            warn "Could not find fork point for #{user}/#{repo}, fork of #{parent_owner}/#{parent_repo}"
          end
        end
      end

      if recursive and not ensure_repo_recursive(user, repo)
        warn "Could retrieve #{user}/#{repo} recursively"
        return nil
      end

      info "Added repo #{user}/#{repo}"
      return repos.first(:owner_id => curuser[:id], :name => repo)
    end
def ensure_repo(user, repo, recursive = false)

      repos = db[:projects]
      curuser = ensure_user(user, false, false)

      if curuser.nil?
        warn "Could not find user #{user}"
        return
      end

      currepo = repos.first(:owner_id => curuser[:id], :name => repo)

      unless currepo.nil?
        debug "Repo #{user}/#{repo} exists"
        return refresh_repo(user, repo, currepo)
      end

      r = retrieve_repo(user, repo, true)

      if r.nil?
        warn "Could not retrieve repo #{user}/#{repo}"
        return
      end

      if r['owner']['login'] != curuser[:login]
        info "Repo changed owner from #{curuser[:login]} to #{r['owner']['login']}"
        curuser = ensure_user(r['owner']['login'], false, false)
      end

      repos.insert(:url => r['url'],
                   :owner_id => curuser[:id],
                   :name => r['name'],
                   :description => unless r['description'].nil? then r['description'][0..254] else nil end,
                   :language => r['language'],
                   :created_at => date(r['created_at']),
                   :updated_at => date(Time.now),
                   :etag => unless r['etag'].nil? then r['etag'] end)

      unless r['parent'].nil?
        parent_owner = r['parent']['owner']['login']
        parent_repo = r['parent']['name']

        parent = ensure_repo(parent_owner, parent_repo)

        if parent.nil?
          warn "Could not find repo #{parent_owner}/#{parent_repo}, parent of: #{user}/#{repo}"
          repos.filter(:owner_id => curuser[:id], :name => repo).update(:forked_from => -1)
        else
          repos.filter(:owner_id => curuser[:id], :name => repo).update(:forked_from => parent[:id])
          info "Repo #{user}/#{repo} is a fork of #{parent_owner}/#{parent_repo}"

          unless ensure_fork_point(user, repo).nil?
            warn "Could not find fork point for #{user}/#{repo}, fork of #{parent_owner}/#{parent_repo}"
          end
        end
      end

      if recursive and not ensure_repo_recursive(user, repo)
        warn "Could retrieve #{user}/#{repo} recursively"
        return nil
      end

      info "Added repo #{user}/#{repo}"
      return repos.first(:owner_id => curuser[:id], :name => repo)
    end
Ensure that a repo exists, or fetch its latest state from Github

 ==Parameters:
 [user]  The email or login name to which this repo belongs
 [repo]  The repo name

 == Returns:
  If the repo can be retrieved, it is returned as a Hash. Otherwise,
  the result is nil