1
0
mirror of https://github.com/danog/gift.git synced 2024-11-30 04:19:37 +01:00

Add basic support for reading git config

This commit is contained in:
Eric O'Connell 2013-10-05 15:29:34 -07:00
parent 9503fc8208
commit 9ef8c80096
5 changed files with 75 additions and 18 deletions

17
src/config.coffee Normal file
View File

@ -0,0 +1,17 @@
module.exports = C = (repo, callback) ->
repo.git "config", {list: true}, (err, stdout, stderr) ->
config = new Config repo
config.parse stdout
callback err, config
C.Config = class Config
constructor: (@repo) ->
# Internal: Parse the config from stdout of a `git config` command
parse: (text)->
@values = {}
for line in text.split("\n")
if line.length == 0
continue
[key, value] = line.split('=')
@values[key] = value

View File

@ -3,7 +3,7 @@ fs = require 'fs'
module.exports = Git = (git_dir, dot_git) -> module.exports = Git = (git_dir, dot_git) ->
dot_git ||= "#{git_dir}/.git" dot_git ||= "#{git_dir}/.git"
git = (command, options, args, callback) -> git = (command, options, args, callback) ->
[callback, args] = [args, callback] if !callback [callback, args] = [args, callback] if !callback
[callback, options] = [options, callback] if !callback [callback, options] = [options, callback] if !callback
@ -15,26 +15,26 @@ module.exports = Git = (git_dir, dot_git) ->
bash = "#{Git.bin} #{command} #{options} #{args}" bash = "#{Git.bin} #{command} #{options} #{args}"
exec bash, {cwd: git_dir}, callback exec bash, {cwd: git_dir}, callback
return bash return bash
# Public: Get a list of the remote names. # Public: Get a list of the remote names.
# #
# callback - Receives `(err, names)`. # callback - Receives `(err, names)`.
# #
git.list_remotes = (callback) -> git.list_remotes = (callback) ->
fs.readdir "#{dot_git}/refs/remotes", (err, files) -> fs.readdir "#{dot_git}/refs/remotes", (err, files) ->
callback err, (files || []) callback err, (files || [])
# Public: Get the ref data string. # Public: Get the ref data string.
# #
# type - Such as `remote` or `tag`. # type - Such as `remote` or `tag`.
# callback - Receives `(err, stdout)`. # callback - Receives `(err, stdout)`.
# #
git.refs = (type, options, callback) -> git.refs = (type, options, callback) ->
[callback, options] = [options, callback] if !callback [callback, options] = [options, callback] if !callback
prefix = "refs/#{type}s/" prefix = "refs/#{type}s/"
git "show-ref", (err, text) -> git "show-ref", (err, text) ->
matches = [] matches = []
for line in (text || "").split("\n") for line in (text || "").split("\n")
@ -43,7 +43,7 @@ module.exports = Git = (git_dir, dot_git) ->
if name.substr(0, prefix.length) == prefix if name.substr(0, prefix.length) == prefix
matches.push "#{name.substr(prefix.length)} #{id}" matches.push "#{name.substr(prefix.length)} #{id}"
return callback err, matches.join("\n") return callback err, matches.join("\n")
return git return git

View File

@ -2,6 +2,7 @@ _ = require 'underscore'
cmd = require './git' cmd = require './git'
Actor = require './actor' Actor = require './actor'
Commit = require './commit' Commit = require './commit'
Config = require './config'
Tree = require './tree' Tree = require './tree'
Diff = require './diff' Diff = require './diff'
Tag = require './tag' Tag = require './tag'
@ -184,6 +185,9 @@ module.exports = class Repo
status: (callback) -> status: (callback) ->
return Status(this, callback) return Status(this, callback)
config: (callback) ->
return Config(this, callback)
# Public: Get the repository's tags. # Public: Get the repository's tags.
# #

36
test/config.test.coffee Normal file
View File

@ -0,0 +1,36 @@
should = require 'should'
Config = require '../src/config'
GIT_CONFIG = """
user.name=John Doe
user.email=john.doe@git-scm.com
core.editor=pico
"""
GIT_CONFIG_DUPLICATE_KEYS = """
user.name=John Doe
user.email=john.doe@git-scm.com
core.editor=pico
user.email=john.doe@github.com
core.editor=emacs
"""
describe "Config", ->
describe "()", ->
describe "when there are no overlapping keys", ->
config = new Config.Config 'mock repo'
config.parse GIT_CONFIG
it "read the keys and values", ->
config.values['user.name'].should.equal 'John Doe'
config.values['user.email'].should.equal 'john.doe@git-scm.com'
config.values['core.editor'].should.equal 'pico'
describe "with overlapping keys", ->
config = new Config.Config 'mock repo'
config.parse GIT_CONFIG_DUPLICATE_KEYS
it "read the keys and values", ->
config.values['user.name'].should.equal 'John Doe'
config.values['user.email'].should.equal 'john.doe@github.com'
config.values['core.editor'].should.equal 'emacs'

View File

@ -22,10 +22,10 @@ describe "Status", ->
repo = fixtures.status repo = fixtures.status
status = new Status.Status repo status = new Status.Status repo
status.parse GIT_STATUS_CLEAN status.parse GIT_STATUS_CLEAN
it "is clean", -> it "is clean", ->
status.clean.should.be.true status.clean.should.be.true
describe "when there are changes", -> describe "when there are changes", ->
repo = fixtures.status repo = fixtures.status
status = new Status.Status repo status = new Status.Status repo
@ -37,25 +37,25 @@ describe "Status", ->
repo = fixtures.status repo = fixtures.status
status = new Status.Status repo status = new Status.Status repo
status.parse GIT_STATUS status.parse GIT_STATUS
it "has a modified staged file", -> it "has a modified staged file", ->
status.files["file.txt"].staged.should.be.true status.files["file.txt"].staged.should.be.true
status.files["file.txt"].type.should.eql "M" status.files["file.txt"].type.should.eql "M"
status.files["file.txt"].tracked.should.be.true status.files["file.txt"].tracked.should.be.true
it "has a modified unstaged file", -> it "has a modified unstaged file", ->
status.files["cheese.txt"].staged.should.be.false status.files["cheese.txt"].staged.should.be.false
status.files["cheese.txt"].type.should.eql "M" status.files["cheese.txt"].type.should.eql "M"
status.files["cheese.txt"].tracked.should.be.true status.files["cheese.txt"].tracked.should.be.true
it "has a deleted file", -> it "has a deleted file", ->
status.files["crackers.txt"].staged.should.be.true status.files["crackers.txt"].staged.should.be.true
status.files["crackers.txt"].type.should.eql "D" status.files["crackers.txt"].type.should.eql "D"
status.files["crackers.txt"].tracked.should.be.true status.files["crackers.txt"].tracked.should.be.true
it "has an untracked file", -> it "has an untracked file", ->
status.files["pickles.txt"].tracked.should.be.false status.files["pickles.txt"].tracked.should.be.false
should.not.exist status.files["pickles.txt"].type should.not.exist status.files["pickles.txt"].type
it "is not clean", -> it "is not clean", ->
status.clean.should.be.false status.clean.should.be.false