--- a/hglib.lua Fri Sep 09 12:21:28 2016 +0800
+++ b/hglib.lua Fri Sep 09 12:24:59 2016 +0800
local sizes = { i4 = 4, u4 = 4, c = 1 }
+local function write_u4(wh, value)
+ bytes = string.char(value % (2 ^ 8)) .. bytes
+ value = math.floor(value / (2 ^ 8))
local function read_u4(rh)
+local function write_block(wh, ...)
+ local block = table.concat({...}, '\0')
+function Client:runcommand(...)
+ if not self.capabilities.runcommand then
+ return nil, '', 'runcommand is not supported by this command server', ''
+ self.wh:write('runcommand\n')
+ write_block(self.wh, ...)
+ local channel, message = read_channel(self.rh)
+ return decode_i4(message), o, e, d
+ elseif channel == 'o' then
+ elseif channel == 'e' then
+ elseif channel == 'd' then
+ elseif channel:lower() ~= channel then
read_channel = read_channel,
+ write_block = write_block,
--- a/spec/hglib_spec.lua Fri Sep 09 12:21:28 2016 +0800
+++ b/spec/hglib_spec.lua Fri Sep 09 12:24:59 2016 +0800
assert.are_equal('string', type(encoding))
+ it('can use runcommand to request version', function()
+ local client = hglib.Client.open()
+ local code, o, e, d = client:runcommand('version')
+ assert.are_equal(0, code)
+ assert.is_not_nil(o:find('Mercurial Distributed SCM'))
+ assert.are_equal('', e)
+ assert.are_equal('', d)
+ it('can use runcommand to run nonexistent command', function()
+ local client = hglib.Client.open()
+ local code, o, e, d = client:runcommand('extirpate')
+ assert.are_equal(255, code)
+ assert.is_not_nil(o:find('use "hg help" for the full list of commands'))
+ assert.is_not_nil(e:find('unknown command'))
+ assert.are_equal('', d)