1 /* 2 * Copyright Andrej Mitrovic 2013. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 module git.trace; 8 9 import std.conv; 10 11 import deimos.git2.trace; 12 13 import git.exception; 14 import git.util; 15 16 /** 17 Available tracing levels. When tracing is set to a particular level, 18 callers will be provided tracing at the given level and all lower levels. 19 */ 20 enum TraceLevel 21 { 22 /** No tracing will be performed. */ 23 none = GIT_TRACE_NONE, 24 25 /** Severe errors that may impact the program's execution. */ 26 fatal = GIT_TRACE_FATAL, 27 28 /** Errors that do not impact the program's execution. */ 29 error = GIT_TRACE_ERROR, 30 31 /** Warnings that suggest abnormal data. */ 32 warn = GIT_TRACE_WARN, 33 34 /** Informational messages about program execution. */ 35 info = GIT_TRACE_INFO, 36 37 /** Detailed data that allows for debugging. */ 38 debug_ = GIT_TRACE_DEBUG, 39 40 /** Exceptionally detailed debugging data. */ 41 trace = GIT_TRACE_TRACE 42 } 43 44 /** The trace callback function and delegate types. */ 45 alias TraceFunction = void function(TraceLevel level, in char[] msg); 46 47 /// ditto 48 alias TraceDelegate = void delegate(TraceLevel level, in char[] msg); 49 50 /** 51 Sets the git system tracing configuration to the specified level with the 52 specified callback. When system events occur at a level equal to, or 53 lower than, the given level they will be reported to the given callback. 54 55 $(BLUE Note:) If libgit2 is not built with tracing support calling this 56 function will throw a $(D GitException). 57 58 Make sure $(B -DGIT_TRACE) is set when building libgit2 59 to enable tracing support, or look at the libgit2 build instructions. 60 */ 61 void setGitTracer(TraceLevel level, TraceFunction callback) 62 { 63 setGitTracerImpl(level, callback); 64 } 65 66 /// ditto 67 void setGitTracer(TraceLevel level, scope TraceDelegate callback) 68 { 69 setGitTracerImpl(level, callback); 70 } 71 72 /// test callback function 73 unittest 74 { 75 static void tracer(TraceLevel level, in char[] msg) 76 { 77 import std.stdio; 78 stderr.writefln("Level(%s): %s", level, msg); 79 } 80 81 try 82 { 83 setGitTracer(TraceLevel.trace, &tracer); 84 } 85 catch (GitException exc) 86 { 87 assert(exc.msg == _noTraceMsg, exc.msg); 88 } 89 } 90 91 /// test callback delegate 92 unittest 93 { 94 struct S 95 { 96 size_t line = 1; 97 98 void tracer(TraceLevel level, in char[] msg) 99 { 100 import std.stdio; 101 stderr.writefln("Level(%s): Line %s - %s", line++, level, msg); 102 } 103 } 104 105 S s; 106 107 try 108 { 109 setGitTracer(TraceLevel.trace, &s.tracer); 110 } 111 catch (GitException exc) 112 { 113 assert(exc.msg == _noTraceMsg, exc.msg); 114 } 115 } 116 117 version(unittest) 118 { 119 enum _noTraceMsg = "Git error (GITERR_INVALID): This version of libgit2 was not built with tracing.."; 120 } 121 122 private void setGitTracerImpl(Callback)(TraceLevel level, Callback callback) 123 if (is(Callback == TraceFunction) || is(Callback == TraceDelegate)) 124 { 125 struct Tracer 126 { 127 extern(C) void tracer(git_trace_level_t level, const(char)* msg) 128 { 129 callback(cast(TraceLevel)level, to!(const(char)[])(msg)); 130 } 131 132 private: 133 /// The currently active callback 134 static Callback callback; 135 } 136 137 Tracer.callback = callback; 138 require(git_trace_set(cast(git_trace_level_t)level, &Tracer.tracer) == 0); 139 }