diff --git a/ext/ddcov/ddcov.c b/ext/ddcov/ddcov.c index 9fe245a9..417949de 100644 --- a/ext/ddcov/ddcov.c +++ b/ext/ddcov/ddcov.c @@ -2,19 +2,80 @@ #include #include -VALUE DDCovClass = Qnil; +// Utils +static bool prefix(const char *pre, const char *str) +{ + return strncmp(pre, str, strlen(pre)) == 0; +} -VALUE dd_cov_initialize(VALUE self) +// Data structure +struct dd_cov_data { - rb_iv_set(self, "@var", rb_hash_new()); - return self; + char *root; + VALUE coverage; +}; + +static void dd_cov_mark(void *ptr) +{ + // printf("MARK\n"); + struct dd_cov_data *dd_cov_data = ptr; + rb_gc_mark_movable(dd_cov_data->coverage); +} + +static void dd_cov_free(void *ptr) +{ + // printf("FREE\n"); + struct dd_cov_data *dd_cov_data = ptr; + + xfree(dd_cov_data); +} + +static void dd_cov_compact(void *ptr) +{ + // printf("COMPACT\n"); + struct dd_cov_data *dd_cov_data = ptr; + dd_cov_data->coverage = rb_gc_location(dd_cov_data->coverage); +} + +const rb_data_type_t dd_cov_data_type = { + .wrap_struct_name = "dd_cov", + .function = { + .dmark = dd_cov_mark, + .dfree = dd_cov_free, + .dsize = NULL, + .dcompact = dd_cov_compact}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY}; + +static VALUE dd_cov_allocate(VALUE klass) +{ + // printf("ALLOCATE\n"); + struct dd_cov_data *dd_cov_data; + VALUE obj = TypedData_Make_Struct(klass, struct dd_cov_data, &dd_cov_data_type, dd_cov_data); + dd_cov_data->coverage = rb_hash_new(); + return obj; +} + +// DDCov methods +static VALUE dd_cov_initialize(VALUE self, VALUE rb_root) +{ + // printf("INITIALIZE\n"); + struct dd_cov_data *dd_cov_data; + TypedData_Get_Struct(self, struct dd_cov_data, &dd_cov_data_type, dd_cov_data); + + // printf("struct got\n"); + dd_cov_data->root = StringValueCStr(rb_root); + // printf("root set\n"); + + return Qnil; } -void dd_cov_update_line_coverage(rb_event_flag_t event, VALUE data, VALUE self, ID id, VALUE klass) +static void dd_cov_update_line_coverage(rb_event_flag_t event, VALUE data, VALUE self, ID id, VALUE klass) { // printf("EVENT HOOK FIRED\n"); // printf("FILE: %s\n", rb_sourcefile()); // printf("LINE: %d\n", rb_sourceline()); + struct dd_cov_data *dd_cov_data; + TypedData_Get_Struct(data, struct dd_cov_data, &dd_cov_data_type, dd_cov_data); const char *filename = rb_sourcefile(); if (filename == 0) @@ -22,13 +83,18 @@ void dd_cov_update_line_coverage(rb_event_flag_t event, VALUE data, VALUE self, return; } - unsigned long filename_length = strlen(filename); + if (!prefix(dd_cov_data->root, filename)) + { + return; + } + + unsigned long len_filename = strlen(filename); - VALUE rb_str_source_file = rb_str_new(filename, filename_length); - rb_hash_aset(rb_iv_get(data, "@var"), rb_str_source_file, Qtrue); + VALUE rb_str_source_file = rb_str_new(filename, len_filename); + rb_hash_aset(dd_cov_data->coverage, rb_str_source_file, Qtrue); } -VALUE dd_cov_start(VALUE self) +static VALUE dd_cov_start(VALUE self) { // get current thread VALUE thval = rb_thread_current(); @@ -39,23 +105,30 @@ VALUE dd_cov_start(VALUE self) return self; } -VALUE dd_cov_stop(VALUE self) +static VALUE dd_cov_stop(VALUE self) { // get current thread VALUE thval = rb_thread_current(); - // remove event hook rb_thread_remove_event_hook(thval, dd_cov_update_line_coverage); - return rb_iv_get(self, "@var"); + struct dd_cov_data *dd_cov_data; + TypedData_Get_Struct(self, struct dd_cov_data, &dd_cov_data_type, dd_cov_data); + + VALUE cov = dd_cov_data->coverage; + + dd_cov_data->coverage = rb_hash_new(); + + return cov; } void Init_ddcov(void) { - id_puts = rb_intern("puts"); + VALUE cDDCov = rb_define_class("DDCov", rb_cObject); + + rb_define_alloc_func(cDDCov, dd_cov_allocate); - DDCovClass = rb_define_class("DDCov", rb_cObject); - rb_define_method(DDCovClass, "initialize", dd_cov_initialize, 0); - rb_define_method(DDCovClass, "start", dd_cov_start, 0); - rb_define_method(DDCovClass, "stop", dd_cov_stop, 0); + rb_define_method(cDDCov, "initialize", dd_cov_initialize, 1); + rb_define_method(cDDCov, "start", dd_cov_start, 0); + rb_define_method(cDDCov, "stop", dd_cov_stop, 0); } diff --git a/lib/datadog/ci/itr/coverage/collector.rb b/lib/datadog/ci/itr/coverage/collector.rb index f4093edb..b58b2125 100644 --- a/lib/datadog/ci/itr/coverage/collector.rb +++ b/lib/datadog/ci/itr/coverage/collector.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true -require "coverage" - -require_relative "filter" +require_relative "../../utils/git" require_relative "../../../../ddcov/ddcov" module Datadog @@ -11,7 +9,7 @@ module Itr module Coverage class Collector def initialize - @ddcov = DDCov.new + # TODO: make this thread local end def setup @@ -19,14 +17,14 @@ def setup end def start + @ddcov = DDCov.new(Utils::Git.root) @ddcov.start end def stop - result = @ddcov.stop - @ddcov.instance_variable_set(:@var, {}) - - Filter.call(result) + @ddcov.stop + # p "RAW" + # p result.count end end end