<commit_before>require 'sinatra/base'
require 'debugger'

class CapitalGit < Sinatra::Base

  before do
    content_type :json
    env = ENV['RACK_ENV'] || 'development'
    config_path = File.expand_path('repos.yml', File.dirname(__FILE__))
    @@repos = {}
    YAML::load(File.read(config_path))[env].each do |repo|
      @@repos[repo['slug']] = {:path => repo['path'], :dir => repo['dir']}
    end
  end

  get '/:repo' do
    resp = {}
    resp[:items] = []


    @repo = @@repos[params[:repo]]
    repo = Rugged::Repository.new(@repo[:path])
    
    repo.lookup(repo.head.target).tree.walk_blobs do |root,entry|
      if root[0,5] == @repo[:dir]
        path = File.join(root, entry[:name])
        resp[:items] << {:entry => entry, :path => path}
      end
    end

    return resp.to_json
  end

  get '/:repo/*' do |repo, path|
    resp = {}
    resp[:attributes] = {}

    @repo = @@repos[params[:repo]]
    repo = Rugged::Repository.new(@repo[:path])

    repo.lookup(repo.head.target).tree.walk_blobs do |root,entry|
      if root[0,5] == @repo[:dir]
        if File.join(root, entry[:name]) == path
          blob = repo.read(entry[:oid])
          resp[:attributes][:text] = blob.data.force_encoding('UTF-8')
          resp[:entry] = entry
        end
      end
    end

    return resp.to_json
  end

  put '/:repo/*' do |repo, path|
    resp = {}

    putdata = JSON.parse(request.env["rack.input"].read)
    text = putdata["attributes"]["text"]
    committer = { :email => putdata["committer"]["email"], :name => putdata["committer"]["name"], :time => Time.now }
    message = putdata["message"] || ""

    repo = Rugged::Repository.new(@@repos[params[:repo]][:path])

    options = {}
    updated_oid = repo.write(text.force_encoding("UTF-8"), :blob)
    tree = repo.lookup(repo.head.target).tree

    options[:tree] = update_tree(repo, tree, path, updated_oid)
    options[:author] = committer
    options[:committer] = committer
    options[:message] ||= message
    options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
    options[:update_ref] = 'HEAD'

    commit = Rugged::Commit.create(repo, options)

    if !repo.bare?
      repo.reset(commit, :hard)
      repo.push("origin", [repo.head.name])
    end

    return options.to_json
  end

  # recursively updates a tree.
  # returns the oid of the new tree
  def update_tree repo, tree, path, blob_oid
    segments = path.split("/")
    if segments.length > 1
      segment = segments.shift
      rest = segments.join("/")
      builder = Rugged::Tree::Builder.new(tree)
      original_tree = repo.lookup(builder[segment][:oid])<commit_msg>make sure an origin exists before trying to push to it<commit_after>require 'sinatra/base'
require 'debugger'

class CapitalGit < Sinatra::Base

  before do
    content_type :json
    env = ENV['RACK_ENV'] || 'development'
    config_path = File.expand_path('repos.yml', File.dirname(__FILE__))
    @@repos = {}
    YAML::load(File.read(config_path))[env].each do |repo|
      @@repos[repo['slug']] = {:path => repo['path'], :dir => repo['dir']}
    end
  end

  get '/:repo' do
    resp = {}
    resp[:items] = []


    @repo = @@repos[params[:repo]]
    repo = Rugged::Repository.new(@repo[:path])
    
    repo.lookup(repo.head.target).tree.walk_blobs do |root,entry|
      if root[0,5] == @repo[:dir]
        path = File.join(root, entry[:name])
        resp[:items] << {:entry => entry, :path => path}
      end
    end

    return resp.to_json
  end

  get '/:repo/*' do |repo, path|
    resp = {}
    resp[:attributes] = {}

    @repo = @@repos[params[:repo]]
    repo = Rugged::Repository.new(@repo[:path])

    repo.lookup(repo.head.target).tree.walk_blobs do |root,entry|
      if root[0,5] == @repo[:dir]
        if File.join(root, entry[:name]) == path
          blob = repo.read(entry[:oid])
          resp[:attributes][:text] = blob.data.force_encoding('UTF-8')
          resp[:entry] = entry
        end
      end
    end

    return resp.to_json
  end

  put '/:repo/*' do |repo, path|
    resp = {}

    putdata = JSON.parse(request.env["rack.input"].read)
    text = putdata["attributes"]["text"]
    committer = { :email => putdata["committer"]["email"], :name => putdata["committer"]["name"], :time => Time.now }
    message = putdata["message"] || ""

    repo = Rugged::Repository.new(@@repos[params[:repo]][:path])

    options = {}
    updated_oid = repo.write(text.force_encoding("UTF-8"), :blob)
    tree = repo.lookup(repo.head.target).tree

    options[:tree] = update_tree(repo, tree, path, updated_oid)
    options[:author] = committer
    options[:committer] = committer
    options[:message] ||= message
    options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
    options[:update_ref] = 'HEAD'

    commit = Rugged::Commit.create(repo, options)

    if !repo.bare?
      repo.reset(commit, :hard)
      if repo.remotes.map {|r| r.name}.include? "origin"
        repo.push("origin", [repo.head.name])
      end
    end

    return options.to_json
  end

  # recursively updates a tree.
  # returns the oid of the new tree
  def update_tree repo, tree, path, blob_oid
    segments = path.split("/")
    if segments.length > 1
      segment = segments.shift
      rest = segments.join("/")
      builder = Rugged::Tree::Builder.new(tree)
      original_tree = repo.lookup(builder[segment][:oid])
{'fraction_non_alphanumeric': 0.17374301675977655, 'fraction_numerical': 0.0026070763500931097, 'mean_word_length': 3.053584905660377, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '54677', 'n_tokens_mistral': 1824, 'n_tokens_neox': 1765, 'n_words': 367}