RubyでScalaスクリプトをコンパイル補助するツールを作成する。

仕様

ツール1 タイムスタンプスナップ機能

フォルダ内の.scalaファイルのタイプスタンプのスナップを取得する。

ツール2 更新ファイル抽出機能

既存のタイムスタンプと現在のファイルのタイムスタンプを比較し更新されたファイルを取得しコンパイル可能なバッチファイルを生成する

scalacc.batの例

BASEが2回出てきているが、どちらも自動的にJarファイルを読み込みたいフォルダである。下記の例のように追加したいフォルダの数だけ繰り返し記述するとよいでしょう。

@echo off
setlocal ENABLEDELAYEDEXPANSION
set CP=.
set BASE=C:\scala\lib
for %%f in (%BASE%\*) do set CP=!CP!;%%f
set BASE=C:\scala\lib\user
for %%f in (%BASE%\*) do set CP=!CP!;%%f
SET SCALA_DOC_HOME="C:\scala\doc"
ECHO %CP%
scalac -classpath %CP% %1

ツール1 タイムスタンプスナップ機能

rubyのディレクトリ関連の処理

ディレクトリ中のファイル一覧を取得する

ワイルドカードにマッチしたファイル全てに処理を行う

ファイルのタイムスタンプを取得する

snap_timestamp.rb

path=ARGV[0].gsub("\\","/")
ext="scala"
outfile="timestamp.txt"

buffer = ""
# **は再帰的検索。\0は複数パターンの区切り。.*は隠しファイル取得
Dir.glob("#{path}/**/*\0#{path}/**/.*" + ext).each{|name|
   puts name
   buffer = buffer + name + "\n"
   
	s = File.stat(name)
	timestamp = File.mtime(fname).strftime("%Y/%m/%d %H:%M:%S") # 最終更新時刻
	puts timestamp
	buffer = buffer + timestamp + "\n"
	
} 

# タイムスタンプスナップを上書き更新します。
file = File.open(path + "/" + outfile, "w");
# 書き込む
file.write(buffer);
file.close

snap_timestamp_diff.rb

更新したファイルを出力する

#第一引数はフォルダ名
path=ARGV[0].gsub("\\","/")
ext=/.*\.scala$/
outfile="timestamp.txt"

current={}

# **は再帰的検索。\0は複数パターンの区切り。.*は隠しファイル取得
Dir.glob("#{path}/**/*\0#{path}/**/.*" ).each{|name|
	if ext =~ name
		s = File.stat(name)
		current.store(name,File.mtime(name).strftime("%Y/%m/%d %H:%M:%S"))
	end
}

# タイムスタンプ保存用ファイル読み込み
before={}
file = open(path+"/"+outfile)
buffer = file.read().split("\n");
file.close

#2行を1つの配列にまとめた配列を作成
newItem=""
newItem = nil
buffer.each{|line|
	if newItem == nil
		newItem=line
	else
		if ext =~ newItem
			before.store(newItem,line)
		end
		newItem = nil
	end
} 


#タイムスタンプの比較 更新・新規追加したファイルを出力
current.each{|filepath, timestamp|
	if timestamp != before.fetch(filepath)
		puts filepath
	end
}

備考

RubyをWindowsのDOSで動作させるとRubyからバッチファイルを動作させる際に使用する
システムのShellが使用している

Scala でコマンドの実行結果を文字列として取得

「java -version」を実行する例

	Runtime r = Runtime.getRuntime();
	Process p = r.exec("java -version");

複数の引数の指定方法

	Runtime r = Runtime.getRuntime();
	Process p = r.exec(new String[] {
		"C:\\Program Files\\Java\\j2re1.4.2_13\\bin\\java",
		"-version" });

「echo zzz」を実行する例

	Runtime r = Runtime.getRuntime();
	Process p = r.exec("cmd /c echo zzz");
//	Process p = r.exec(new String[]{ "cmd", "/c", "echo", "zzz" });

環境変数の指定

	String[] env = new String[2];
	env[0] = "TEST=サンプル";
	env[1] = "PATH=" + System.getProperty("java.library.path");
	Runtime r = Runtime.getRuntime();
	Process p = r.exec("cmd /c echo %TEST%", env);

参考URL 外部プロセス起動

http://www.ne.jp/asahi/hishidama/home/tech/java/process.html#Runtime

Javaで,子プロセスを使うときの注意点

http://isolinear.info/wiki/index.php/Java/Tips/Java%A4%C7%A1%A4%BB%D2%A5%D7%A5%ED%A5%BB%A5%B9%A4%F2%BB%C8%A4%A6%A4%C8%A4%AD%A4%CE%C3%ED%B0%D5%C5%C0.html

外部プロセスを実行し標準出力と標準エラーを取得する。

Actorをつかってスレッドプログラムを置き換えてみる

上記で紹介した外部プロセス起動のスレッドを使ったコードはこちら

import java.io.*;
import java.util.*;

/**
 * InputStreamを読み込むスレッド
 */
public class InputStreamThread extends Thread {

	private BufferedReader br;

	private List<String> list = new ArrayList<String>();

	/** コンストラクター */
	public InputStreamThread(InputStream is) {
		br = new BufferedReader(new InputStreamReader(is));
	}

	/** コンストラクター */
	public InputStreamThread(InputStream is, String charset) {
		try {
			br = new BufferedReader(new InputStreamReader(is, charset));
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void run() {
		for (;;) {
			try {
				String line = br.readLine();
				if (line == null) 	break;
				list.add(line);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}

	/** 文字列取得 */
	public List<String> getStringList() {
		return list;
	}
}
トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS