NYAOSの更新をするコマンドを修正しました

NYAOSの更新作業を補助するLuaスクリプトです。以前に作ったもの*1が動かなくなっていたので修正しました。

つかいかた

  1. 実行には wgetコマンドunzipコマンド が必要です。パスの通った場所に置いてください。
  2. _nyaなどでsourceを使って下記のソースを読み込む。
  3. update_nyaos コマンドを実行する。すると自動で新しいバージョンを探して、ある場合はインストールできます。

ソースコード

-- nya_update.lua
-- MIT License (http://d.hatena.ne.jp/wantora/20101212/1292141801)

local function wget(url, output)
	local command = 'wget --no-check-certificate --user-agent="" -O "'..output..'" "'..url..'"'
	
	if output == "-" then
		local f = io.popen(command .. '2> NUL')
		local out = f:read("*a")
		f:close()
		return out
	else
		return os.execute(command)
	end
end

local function confirm(message, chars)
	local key
	
	io.write(message)
	repeat key = nyaos.getkey() until chars:find(key) ~= nil
	io.write(key.."\n")
	return key
end

local function fileread(filename)
	local f = io.open(filename, "rb")
	local body = f:read("*a")
	f:close()
	return body
end

local function check_mod(nyapath, zippath)
	local s, old = pcall(fileread, nyapath.."\\_nya")
	if s == false then return false end
	local new = nyaos.eval('unzip -cp "'..zippath..'" _nya')
	return (old:gsub("%s+$", "") ~= new:gsub("%s+$", ""))
end

local function setupdate(nyapath, zippath)
	local opt = ""
	if check_mod(nyapath, zippath) then
		if confirm("_nyaファイルを上書きしますか?(y/n)", "yn") == "n" then
			opt = "-x _nya"
		end
	end
	nyaos.goodbye.update_nyaos = function()
		nyaos.exec([[%COMSPEC% /c start %COMSPEC% /c "ping localhost -n 2 > nul & unzip -o "]]..zippath..[[" -d "]]..nyapath..[[" ]]..opt..[[ & pause"]])
	end
end

function nyaos.command.update_nyaos()
	local nyapath = nyaos.argv[0]:gsub("\\[^\\]+$", "")
	local html = wget("https://bitbucket.org/zetamatta/nyaos3000/downloads", "-")
	local url, name, version
	
	version = ""
	for u,n,v in html:gmatch('<td class="name"><a class="execute" href="([^"]*/([^"]-%-([^"]-)%-win%.zip))"') do
		if v > version then
			url, name, version = "https://bitbucket.org"..u, n, v
		end
	end
	
	if html == "" or url == nil then
		print("update_nyaos: ページの取得に失敗しました")
		return
	end
	
	if version > nyaos.version then
		if confirm(nyaos.version.." から "..version.." に更新しますか?(y/n)", "yn") == "y" then
			local zippath = nyapath.."\\"..name
			wget(url, zippath)
			setupdate(nyapath, zippath)
			print("NYAOS終了時に更新します")
		end
	else
		print("NYAOSは最新版です")
	end
end

NYAOSでhgやgemなどのサブコマンドを補完するスクリプト、の修正版

昔作ったスクリプト*1の修正版です。前回からの変更点は以下の通り。

  • NYAOSエイリアスへの簡易的な対応
  • hgのコマンド一覧取得にhg debugcompleteを使用するようにした

それと、git用の補完スクリプトを書いて下さった方がいたので紹介。gitコマンドの補完、サブモジュールの削除nyaosスクリプト · GitHubから見ることが出来ます。

-- complete.lua  Copyright (c) 2011 wantora
-- MIT License (http://d.hatena.ne.jp/wantora/20101212/1292141801)

local function clean_cmd(str)
	return str:gsub('%s+$', ''):gsub('^(%S+)%.[^/\\.]+$', '%1')
end

local completes_cache = {}
local completes = {
	hg = function()
		local cmds = {}
		for name in nyaos.eval('hg debugcomplete'):gmatch('[^\n]+') do
			table.insert(cmds, name)
		end
		return cmds
	end,
	gem = function()
		local cmds = {}
		for line in nyaos.eval('gem help commands'):gmatch('[^\n]+') do
			local name = line:match('^    ([^%s]*)')
			if #cmds > 0 and (not name) then break end
			if name and #name > 0         then table.insert(cmds, name) end
		end
		return cmds
	end,
}

function nyaos.complete(basestring, pos, misc)
	local cmd = clean_cmd(misc.text:sub(1, pos))
	
	if nyaos.alias[cmd] then
		cmd = clean_cmd(nyaos.alias[cmd])
	end
	
	for name, comp in pairs(completes) do
		if cmd == name then
			if not completes_cache[name] then completes_cache[name] = comp() end
			return completes_cache[name]
		end
	end
	
	return nyaos.default_complete(basestring, pos)
end

*1:id:wantora:20100612:1276302763

NYAOSをアップデートするスクリプト(NYAOS 3.1.4_0版)

最新版がNYAOSの更新をするコマンドを修正しました - メモ:wantoraにあります。
2011-01-04 cmd.exeに渡すコマンドの「&&」を「&」に変更。*1

NYAOS 3.1.4_0にてluaからNYAOSのパスとバージョンを取得できるようになったので、それを利用しNYAOSをアップデートするスクリプトを作った - メモ:wantoraを改良しました。

また、_nyaファイルを上書きするか確認するように変更しました。

つかいかた

  1. NYAOSupdate_nyaos とタイプすると新しいバージョンを確認し、あれば更新します。
  2. 実行には wgetunzip が必要なので、無い場合はダウンロードしてPATHを通して下さい。
-- MIT License (http://d.hatena.ne.jp/wantora/20101212/1292141801)

local function wget(url, output)
	return nyaos.eval('wget -nc --user-agent="" -O "'..output..'" "'..url..'" 2>&-')
end

local function confirm(message, chars)
	local key
	
	io.write(message)
	repeat key = nyaos.getkey() until chars:find(key) ~= nil
	io.write(key.."\n")
	return key
end

local function fileread(filename)
	local f = io.open(filename, "rb")
	local body = f:read("*a")
	f:close()
	return body
end

local function check_mod(nyapath, zippath)
	local s, old = pcall(fileread, nyapath.."\\_nya")
	if s == false then return false end
	local new = nyaos.eval('unzip -cp "'..zippath..'" _nya')
	return (old:gsub("%s+$", "") ~= new:gsub("%s+$", ""))
end

local function setupdate(nyapath, zippath)
	local opt = ""
	if check_mod(nyapath, zippath) then
		if confirm("_nyaファイルを上書きしますか?(y/n)", "yn") == "n" then
			opt = "-x _nya"
		end
	end
	nyaos.goodbye.update_nyaos = function()
		nyaos.exec([[%COMSPEC% /c start %COMSPEC% /c "ping localhost -n 2 > nul & unzip -o "]]..zippath..[[" -d "]]..nyapath..[[" ]]..opt..[[ & pause"]])
	end
end

function nyaos.command.update_nyaos()
	local nyapath = nyaos.argv[0]:gsub("\\[^\\]+$", "")
	local html = wget("http://www.nyaos.org/index.cgi?p=NYAOS+3000", "-")
	local url, name, version = html:match(
		'<a href="(/index%.cgi%?p=NYAOS%+3000;f=(nyaos%-(.-)%-win.zip))"')
	
	if html == "" or url == nil then
		print("update_nyaos: ページの取得に失敗しました")
		return
	end
	
	if version:gsub("[._]", "") > nyaos.version:gsub("[._]", "") then
		if confirm(nyaos.version.." から "..version.." に更新しますか?(y/n)", "yn") == "y" then
			local zippath = nyapath.."\\"..name
			wget("http://www.nyaos.org"..url, zippath)
			setupdate(nyapath, zippath)
			print("NYAOS終了時に更新します")
		end
	else
		print("NYAOSは最新版です")
	end
end

*1:「&&」だと途中でコマンドが失敗した場合にその先へ進まなくなってしまう。でも実際にはそんな事はあまり無いと思う。

NYAOSをアップデートするスクリプトを作った

最新版がNYAOSの更新をするコマンドを修正しました - メモ:wantoraにあります。
最新版がNYAOSをアップデートするスクリプト(NYAOS 3.1.4_0版) - メモ:wantoraにあります。

NYAOS 3.1.3_0のリリース記念(?)にアップデートを自動化するスクリプトを作りました。

今回、NYAOSのバージョンがluaから取得できないので、マニュアルから取得するというあまりスマートでない方法を使っています。NYAOSのパスとバージョンを取得する機能があるといいのですが。

新機能の $Wn は同じ名前のディレクトリがある時に便利ですね。

つかいかた

  1. まず、 nyaos_path をNYAOSが置いてあるパスに書き換えます。
  2. NYAOSで update_nyaos とタイプすると、最新版を確認後新しいバージョンであれば更新します。注意! _nyaファイルも上書きされます。
  3. 実行には wgetunzip が必要なので、無い場合はダウンロードしてPATHを通して下さい。
-- MIT License (http://d.hatena.ne.jp/wantora/20101212/1292141801)

local nyaos_path = [[ここにNYAOSのパスを入力]]
local nyaos_version
do
	local f = io.open(nyaos_path .. "\\nyaos_en.txt")
	local version = nil
	for line in f:lines() do
		if line == "History" then break end
	end
	for line in f:lines() do
		version = line:match("^([%d._]+) ")
		if version then break end
	end
	f:close()
	nyaos_version = version
end


local function wget(url, output)
	return nyaos.eval('wget -nc --user-agent="" -O "'..output..'" "'..url..'" 2>&-')
end

local function confirm(message, chars)
	local key
	
	io.write(message)
	repeat key = nyaos.getkey() until chars:find(key) ~= nil
	io.write(key.."\n")
	return key
end

local function update_nyaos(url, zippath)
	wget(url, zippath)
	nyaos.goodbye.update_nyaos = function()
		nyaos.exec([[%COMSPEC% /c start %COMSPEC% /c "ping localhost -n 2 > nul && unzip -fo "]]..zippath..[[" -d "]]..nyaos_path..[[" && pause"]])
	end
	print("NYAOS終了時に更新します")
end

function nyaos.command.update_nyaos()
	local html = wget("http://www.nyaos.org/index.cgi?p=NYAOS+3000", "-")
	local url, name, version = html:match(
		'<a href="(/index%.cgi%?p=NYAOS%+3000;f=(nyaos%-(.-)%-win.zip))"')
	
	if html == "" or url == nil then
		print("update_nyaos: ページの取得に失敗しました")
		return
	end
	
	if version:gsub("[._]", "") > nyaos_version:gsub("[._]", "") then
		if confirm(nyaos_version.." から "..version.." に更新しますか?(y/n)", "yn") == "y" then
			update_nyaos("http://www.nyaos.org"..url, nyaos_path.."\\"..name)
		end
		return
	end
	
	print("NYAOSは最新版です")
end

NYAOSでshebang

NYAOS 3.1.1_0がリリースされたようです。

今回はnyaos.filter3という機能が追加されました。その例として書かれているshebangを実現するスクリプトを改良してみました。変更点は下記の通り。

NYAOSは色々いじれるようになってきて楽しいですね。かゆい所に手が届くようになってきた。

-- MIT License (http://d.hatena.ne.jp/wantora/20101212/1292141801)

-- MSYSのパスはインストールした場所に変更してください。
-- MSYSを使っていない場合はdirmapを空にすれば無効になります。
local dirmap = {
	['/bin/'] = 'C:/msys/1.0/bin/',
	['/usr/bin/'] = 'C:/msys/1.0/bin/',
}

local cmdutils = {}
-- nnstring.cppのNnString::splitToより
function cmdutils.split(cmdline, sep)
    local quote = false
    local pos = 1
    
    while pos <= #cmdline do
        local s = cmdline:sub(pos, pos)
        
        if s == '"' then
            quote = not quote
        elseif s:match('^[\129-\159\224-\252]$') then
            pos = pos + 1
        elseif (not quote) and s:match(sep) then
            break
        end
        
        pos = pos + 1
    end
    
    return cmdline:sub(1, pos - 1), cmdline:sub(pos + 1), cmdline:sub(pos, pos)
end

local function append_ext(name)
	if nyaos.access(name, 0) then return name end
	if nyaos.access(name .. '.exe', 0) then return name .. '.exe' end
	if nyaos.access(name ..  '.com', 0) then return name .. '.com' end
	return name
end

local function namefilter(name)
	for prefix, path in pairs(dirmap) do
		if name:sub(1, #prefix) == prefix then
			return path .. name:sub(#prefix + 1)
		end
	end
	return name
end

local function drop_first_token(args)
	local _, param, sep = cmdutils.split(args, '%s')
	return sep .. param
end

function nyaos.filter3.shebang(name, param)
	local suffix = string.lower(string.sub(name, #name - 3))
	
	if suffix ~= '.exe' and suffix ~= '.com' then
		local f = io.open(name, 'r')
		if f:read(2) == '#!' then
			local shebang = f:read():gsub('^%s*', '')
			f:close()
			
			local new_name = append_ext(namefilter(cmdutils.split(shebang, '%s')))
			local new_param = shebang .. ' ' .. name .. drop_first_token(param)
			return new_name, new_param
		else
			f:close()
		end
	end
end

NYAOS 3000でいろんなコマンドのサブコマンドを補完する

NYAOSでhgやgemなどのサブコマンドを補完するスクリプト、の修正版 - メモ:wantoraに修正版があります。

NYAOS-3000 2.98_0が公開された。今回の更新には個人的に嬉しい機能がある。

一つはバッチファイルの拡張子を省略出来るようになったこと、もう一つはnyaos.completeに第三引数が追加され、コマンドラインの文字列が取得できるようになったこと。

特にnyaos.completeの第三引数追加はnyaos.keyhookを併用する必要がなくなった。

NYAOS 3000でMercurialのサブコマンドを補完する - メモ:wantoraのサブコマンド補完はMercurialだけだが、今回のスクリプトは変数completesにテーブルを返す関数をコマンド名のキーに追加すれば、様々なコマンドに対応できる。

-- MIT License (http://d.hatena.ne.jp/wantora/20101212/1292141801)

local completes_cache = {}
local completes = {
	hg = function()
		local cmds = {}
		local function insert_cmd(str)
			for line in (str:match('\nlist of commands:\n\n(.-)\n\n') or ''):gmatch('[^\n]+') do
				local name = line:match('^ ([^%s:,]+)')
				if name then table.insert(cmds, name) end
			end
		end
		local HGPLAIN = os.getenv('HGPLAIN') or ''
		nyaos.exec('set HGPLAIN=1')
		
		h = nyaos.eval('hg help -v')
		insert_cmd(h)
		for line in (h:match('\nenabled extensions:\n\n(.-)\n\n') or ''):gmatch('[^\n]+') do
			insert_cmd(nyaos.eval('hg help '..line:match('^ ([^%s]*)')..' -v'))
		end
		
		nyaos.exec('set HGPLAIN='..HGPLAIN)
		return cmds
	end,
	gem = function()
		local cmds = {}
		for line in nyaos.eval('gem help commands'):gmatch('[^\n]+') do
			local name = line:match('^    ([^%s]*)')
			if #cmds > 0 and (not name) then break end
			if name and #name > 0         then table.insert(cmds, name) end
		end
		return cmds
	end,
}

function nyaos.complete(basestring, pos, misc)
	local cmd = misc.text:sub(1, pos):gsub('%s+$', ''):gsub('^(%S+)%.[^/\\.]+$', '%1')
	
	for name, comp in pairs(completes) do
		if cmd == name then
			if not completes_cache[name] then completes_cache[name] = comp() end
			return completes_cache[name]
		end
	end
	
	return nyaos.default_complete(basestring, pos)
end

NYAOS 3000でMercurialのサブコマンドを補完する

6/12: 2010-06-12 - メモ:wantoraに最新版があります。

nyaos.completeを使ってMercurialのサブコマンドを補完するスクリプトを作ってみた。

nyaos.completeでは補完対象の文字列は取得できるが、補完対象の文字列の前にある文字列が取得できないので、nyaos.keyhookを併用してそれを実現している。

-- MIT License (http://d.hatena.ne.jp/wantora/20101212/1292141801)

local command_text = nil
local hgcomplete = nil

local function get_hgcomplete()
	local hgcmds = {}
	for line in nyaos.eval('hg help'):gmatch('[^\n]+') do
		local name = line:match('^ ([^%s]+)')
		if #hgcmds > 0 and (not name) then break end
		if name                       then table.insert(hgcmds, name) end
	end
	return hgcmds
end

function nyaos.keyhook(t)
	command_text = t.text
	return nil
end

function nyaos.complete(basestring, pos)
	if command_text:sub(1, pos):gsub('^hg%.%w*', 'hg'):match('^hg%s*$') then
		if not hgcomplete then
			hgcomplete = get_hgcomplete()
		end
		return hgcomplete
	end
	
	return nyaos.default_complete(basestring, pos)
end