[PATCH v2 01/44] Add support for ruby commands

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Felipe Contreras <felipe.contreras@xxxxxxxxx>
---

Notes:
    With this support, third parties would be able to write scripts more easily and
    access libgit facilities.
    
    Also, it could help developers by allowing easier prototyping
    
      git ruby > actual <<EOF &&
      for_each_ref() do |name, sha1, flags|
        puts "%s: %s" % [name, sha1_to_hex(sha1)]
      end

 .gitignore       |  1 +
 Makefile         | 19 ++++++++++++++++++-
 git-rb-setup.rb  | 11 +++++++++++
 ruby.c           | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 t/t10000-ruby.sh | 42 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 128 insertions(+), 1 deletion(-)
 create mode 100644 git-rb-setup.rb
 create mode 100644 ruby.c
 create mode 100755 t/t10000-ruby.sh

diff --git a/.gitignore b/.gitignore
index 6b1fd1b..51b04be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -139,6 +139,7 @@
 /git-rev-parse
 /git-revert
 /git-rm
+/git-ruby
 /git-send-email
 /git-send-pack
 /git-sh-i18n
diff --git a/Makefile b/Makefile
index 3588ca1..2fdee15 100644
--- a/Makefile
+++ b/Makefile
@@ -491,6 +491,8 @@ SCRIPT_PERL += git-svn.perl
 SCRIPT_PYTHON += git-remote-testpy.py
 SCRIPT_PYTHON += git-p4.py
 
+SCRIPT_RUBY += git-rb-setup.rb
+
 NO_INSTALL += git-remote-testgit
 NO_INSTALL += git-remote-testpy
 
@@ -502,6 +504,7 @@ SCRIPT_PYTHON_GEN = $(patsubst %.py,%,$(SCRIPT_PYTHON))
 SCRIPT_SH_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_SH_GEN))
 SCRIPT_PERL_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_PERL_GEN))
 SCRIPT_PYTHON_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_PYTHON_GEN))
+SCRIPT_RUBY_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_RUBY))
 
 # Individual rules to allow e.g.
 # "make -C ../.. SCRIPT_PERL=contrib/foo/bar.perl build-perl-script"
@@ -511,13 +514,15 @@ build-perl-script: $(SCRIPT_PERL_GEN)
 build-sh-script: $(SCRIPT_SH_GEN)
 build-python-script: $(SCRIPT_PYTHON_GEN)
 
-.PHONY: install-perl-script install-sh-script install-python-script
+.PHONY: install-perl-script install-sh-script install-python-script install-ruby-script
 install-sh-script: $(SCRIPT_SH_INS)
 	$(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
 install-perl-script: $(SCRIPT_PERL_INS)
 	$(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
 install-python-script: $(SCRIPT_PYTHON_INS)
 	$(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
+install-ruby-script: $(SCRIPT_RUBY_INS)
+	$(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
 
 .PHONY: clean-perl-script clean-sh-script clean-python-script
 clean-sh-script:
@@ -530,6 +535,7 @@ clean-python-script:
 SCRIPTS = $(SCRIPT_SH_INS) \
 	  $(SCRIPT_PERL_INS) \
 	  $(SCRIPT_PYTHON_INS) \
+	  $(SCRIPT_RUBY_INS) \
 	  git-instaweb
 
 ETAGS_TARGET = TAGS
@@ -1502,6 +1508,12 @@ ifneq (,$(XDL_FAST_HASH))
 	BASIC_CFLAGS += -DXDL_FAST_HASH
 endif
 
+ifndef NO_RUBY
+	RUBY_LIBS = $(shell pkg-config --libs ruby-2.0)
+	RUBY_CFLAGS = $(shell pkg-config --cflags ruby-2.0)
+	PROGRAM_OBJS += ruby.o
+endif
+
 ifeq ($(TCLTK_PATH),)
 NO_TCLTK = NoThanks
 endif
@@ -2059,6 +2071,11 @@ git-http-push$X: revision.o http.o http-push.o GIT-LDFLAGS $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 		$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
 
+git-ruby$X: BASIC_CFLAGS += $(RUBY_CFLAGS)
+git-ruby$X: ruby.o GIT-LDFLAGS $(GITLIBS)
+	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) $(RUBY_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
+		$(LIBS) $(RUBY_LIBS)
+
 git-remote-testsvn$X: remote-testsvn.o GIT-LDFLAGS $(GITLIBS) $(VCSSVN_LIB)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) \
 	$(VCSSVN_LIB)
diff --git a/git-rb-setup.rb b/git-rb-setup.rb
new file mode 100644
index 0000000..969278a
--- /dev/null
+++ b/git-rb-setup.rb
@@ -0,0 +1,11 @@
+#!/usr/bin/env ruby
+
+def die(*args)
+  fmt = args.shift
+  $stderr.printf("fatal: %s\n" % fmt, *args)
+  exit 128
+end
+
+def sha1_to_hex(sha1)
+  sha1.unpack('H*').first
+end
diff --git a/ruby.c b/ruby.c
new file mode 100644
index 0000000..ee6a0e7
--- /dev/null
+++ b/ruby.c
@@ -0,0 +1,56 @@
+#include "cache.h"
+#include "exec_cmd.h"
+#include "refs.h"
+
+#undef NORETURN
+#undef PATH_SEP
+
+#include <ruby.h>
+
+static inline VALUE sha1_to_str(const unsigned char *sha1)
+{
+	return rb_str_new((const char *)sha1, 20);
+}
+
+static int for_each_ref_fn(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
+{
+	VALUE r;
+	r = rb_yield_values(3, rb_str_new2(refname), sha1_to_str(sha1), INT2FIX(flags));
+	return r == Qfalse;
+}
+
+static VALUE git_rb_for_each_ref(void)
+{
+	int r;
+	r = for_each_ref(for_each_ref_fn, NULL);
+	return INT2FIX(r);
+}
+
+static void git_ruby_init(void)
+{
+	rb_define_global_function("for_each_ref", git_rb_for_each_ref, 0);
+}
+
+static int run_ruby_command(const char *cmd, int argc, const char **argv)
+{
+	static char buf[PATH_MAX + 1];
+	void *node;
+	struct stat st;
+
+	ruby_init();
+	git_ruby_init();
+
+	node = ruby_options(argc, (char **)argv);
+
+	ruby_script(cmd);
+	snprintf(buf, PATH_MAX, "%s/%s", git_exec_path(), "git-rb-setup.rb");
+	if (!stat(buf, &st))
+		rb_load(rb_str_new2(buf), 0);
+
+	return ruby_run_node(node);
+}
+
+int main(int argc, const char **argv)
+{
+	return run_ruby_command(argv[1], argc, argv);
+}
diff --git a/t/t10000-ruby.sh b/t/t10000-ruby.sh
new file mode 100755
index 0000000..eb03706
--- /dev/null
+++ b/t/t10000-ruby.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# Copyright (c) 2013 Felipe Contreras
+#
+
+test_description='test ruby support'
+
+. ./test-lib.sh
+
+test_expect_success 'basic support' '
+	git ruby > actual <<-EOF &&
+	puts "hello world"
+	EOF
+	echo "hello world" > expected &&
+	test_cmp expected actual
+'
+
+test_expect_success 'argument passing' '
+	cat > script <<-"EOF" &&
+	p($0)
+	p(ARGV)
+	EOF
+	git ruby script foo bar > actual &&
+	cat > expected <<-EOF &&
+	"script"
+	["foo", "bar"]
+	EOF
+	test_cmp expected actual
+'
+
+test_expect_success 'test for_each_ref()' '
+	test_commit foo &&
+	git ruby > actual <<-EOF &&
+	for_each_ref() do |name, sha1, flags|
+		puts "%s: %s" % [name, sha1_to_hex(sha1)]
+	end
+	EOF
+	git for-each-ref --format="%(refname): %(objectname)" > expected &&
+	test_cmp expected actual
+'
+
+test_done
-- 
1.8.4-fc

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]