Is there a way to get more information about the error that occurred? Seeing (pre-receive hook declined) does not really convey the heart of the problem, which is that the file is too big.
The push method lets us provide our own progress handler. We can make one that will print out the raw output of the git command. You can have it do whatever, log it, collect it, but for this example, let's just print it.
To make one, we can create our own class based on the RemoteProgress class and override the new_message_handler method. This has a function inside it called handler(line) and it seems that this is where all the raw output lines pass through. We can make a small one-line addition to their original code to print out the lines as they get handled.
If we then pass an instance of our new class into a push method's "progress" parameter, we should see the output of the git command print out as it runs.
from git import Repo, RemoteProgress
class MyProgressPrinter(RemoteProgress):
def new_message_handler(self):
"""
:return:
a progress handler suitable for handle_process_output(), passing lines on to this Progress
handler in a suitable format"""
def handler(line):
print(line.rstrip()) # THIS IS THE LINE I ADDED TO THE ORIGINAL METHOD
return self._parse_progress_line(line.rstrip())
# end
return handler
# Now that we've defined it, let's use it...
with Repo('path/to/my/repo/folder') as repo:
origin = repo.remote()
# And then pass in an instance of the new class when you perform your operation:
result = origin.push(progress=MyProgressPrinter())
You can find the original RemoteProgress class and new_message_handler method in this file:
https://github.com/gitpython-developers/GitPython/blob/master/git/util.py
Related
I am writing a custom matcher for my logging output, mostly so that I can customize the error output to be more readable and helpful.
The thing being examined for the test is the array returned by LoggingSpecHelper.log_events, a module class method (i.e. not a module instance method). Therefore, it is available without the need for it to be passed as a parameter.
LoggingSpecHelper.log_events is kind of long to specify in each expectation, and anyway I'd prefer to hide that implementation detail from the caller, in case that implementation changes. That leads to my using expect(:logging), where :logging is a dummy value which has no meaning and is not examined. This, however, is awkward and confusing, leaving the reader scratching their head thinking "he's examining a symbol?"
Here is an example of how it is currently called; in this case I'm looking to see if a fatal error occurs in the log that contains 'something is misconfigured' (not a real production message):
expect(:logging).to have_log_output_match(:fatal, 'something is misconfigured')
The long form of this, and what is happening in the matcher, is below, but if I do this instead of calling the matcher, I don't get to see what is in the log if an error occurs (the matcher includes log content in the failure message):
expect(LoggingSpecHelper.log_events.count do |event|
event.level == :fatal && /something is misconfigured/.match?(event.message)
end).to be == 1
How would you suggest I handle this? I don't think shared examples are what I want here because this log expectation might not be the only expectation in the example.
As an aside, I should probably rename the matcher so that it is clear that I am testing for 1 and not >=1 occurrences.
I'm modifying a ruby gem.
Currently returning a git log object between 2 revision numbers correctly:
def log(repo, prev_rev, this_rev)
repo.log.between(prev_rev, this_rev)
end
And storing the commit message using:
gitlog_item.each do |commit|
#message = commit.message
My question is what other information is available from this object? Specifically I'm looking for something that can identify the commit uniquely such as an ID, or date & time.
If you want to see the entirety of what your gitlog_item contains, you can simply inspect it, like so:
puts gitlog_item.inspect
That'll output the entire object to your console, so you can see everything that's available to you in that object.
This should be the documentation you are looking for.
Methods sha and committer_data seems to do for you.
I want to insert name of the method calling the logger methods into my log files. Not the whole stack trace, but the class, method and/or line number would be great.
In any method, one can use caller to get an array of strings, each of which contains the file, line number and method name. I've come up with a pretty awful kludge using regexes and Enumerable#find to try to return the first non-logger stack frame. I guess it works, but if the locations of the logging Ruby files change in a different version or Rails, or I name my files something to do with logs, it will break. Same with if I take a given index from the top of the stack (I did this at first, then refactored one thing and naturally it gave me the wrong frame).
Note that I'm not looking to just log the controller or action, as those can be retrieved easily. Mostly this is for stuff in the lib/ directory.
Isn't there an easy way to do this? I don't want to have to pass in __method__ every time I make a logging statement.
I've looked all over at different solutions for capturing the exact place (file, line number, method name) where I invoke any given logger instance method from within my rails app. To do this, you need to override Logger's format_message method, and a good place to do this is in your rails project's config/environment.rb file.
This is what I've come up with, which is good enough for me ;o)
class Logger
def format_message(severity, timestamp, progname, msg)
line = ''
Kernel.caller.each{|entry|
if (entry.include? Rails.root.to_s)
line = " #{entry.gsub(Rails.root.to_s,'').gsub(/\/(.+)\:in `(.+)'/, "\\1 -> \\2")}"
break
end
}
"[#{timestamp.strftime("%Y%m%d.%H:%M:%S")}] #{severity}#{line}: #{msg}\n"
end
end
Kernel.caller holds an enumerable array of the entire backtrace. If you look at it in its entirety, you'll see most calls are internal inside of a gem somewhere well outside your project. I've found that by looping through the Kernel.caller until I find the first place that includes my Rails.root, I can get the line with the information I want to parse.
Example:
If I call Rails.logger.debug("Streamer class started!") from the start method of my Streamer class, the raw entry would look like this:
/Users/chikoon/www/my_rails_app/lib/streamer.rb:7:in `start'
so by the time it makes it through my formatter, I've got the timestamp, severity mode, the file path, line number, method name, and message:
[20140919.19:23:44] DEBUG lib/streamer.rb:7 -> start: Streamer class started!
I hope that helps get your wheels turning.
How about setting up log_tags to call the __method__?
Blog::Application.configure do
config.log_tags = [lambda { |req| __method__ }]
end
In magento there are 2 events:
core_block_abstract_to_html_before
core_block_abstract_to_html_after
They are called every time when toHtml method is called. What I want is to echo to output some valuable data, BUT I get following error:
HEADERS ALREADY SENT
So is there any way to append to output?
If you look at the events being fired, the first event (core_block_abstract_to_html_before) receives the block instance as a parameter. The second event (core_block_abstract_to_html_after) receives both the block and the transport object from which you can extract the rendered content (this is the major feature of that transport object, as the rendered string is a local variable to the method otherwise). You can see the transport object receiving the rendered string in the line immediately preceding the dispatching of the second event:
self::$_transportObject->setHtml($html);
How you add to the block output depends on what you are trying to do. If you need to wrap your output and your preamble needs to use the ..._before event, you should set a param on the block in that event's observer in your module, e.g.
public function coreBlockAbstractToHtmlBefore($observer)
{
$arg = 'Whatever you are doing';
$observer->getBlock()->setYourCustomParam($arg); //e.g. using Magento setter method
}
Then, in your ...after event observer, you can evaluate your custom param and prepend it to the output like so:
public function coreBlockAbstractToHtmlAfter($observer)
{
$argBefore = $observer->getBlock()->getYourCustomParam();
$argAfter = 'Whatever you are doing afterwards';
//get output from _toHtml()
$normalOutput = $observer->getTransport()->getHtml();
//change the output; assume that both args are strings for this ex....
$observer->getTransport()->setHtml( $argBefore . $normalOutput . $argAfter )
}
That said, don't forget that you have a number of options at your disposal, including $block->setFrameTag($open,$close) which can be (somewhat hackishly) used to wrap whatever you want around block output.
A caveat regarding these approaches: the output that is being added will not be cached in the block html cache.
One thing I'd like to add as well is that if you need to target your rendering to specific scopes you can always use the full-action-name-automatic event from Mage_Core_Controller_Varien_Action::renderLayout() method (Mage::dispatchEvent('controller_action_layout_render_before_'.$this->getFullActionName());). You just use the same class to observe this event, invoke it as a singleton for all events, and set a flag.
And finally, a note on your "Headers already sent" error: typical Magento rendering uses a response object, and output should be added to that response object via $response->appendBody('string');.
You can edit the template that it is rendering. Or add another template file and call it from the template file that is rendering (after adding the new one to the layout file).
In web2py, is there a way to have a piece of common code be executed before all controllers are called?
For example, I want to add some code that will log client IPs to a log of requests to enable analysis. I could simply make the first line of all my controllers be something like response = RequestBase(request) but I'm curious to know if this is a problem that's already been solved through some other mechanisms.
You could simply put your piece of logging code in the model definition file, models/db.py, or in your controller controllers/default.py like this:
with open("mylog.log", "at") as f:
f.write(repr(request))
def index():
# index controller definition
# ... rest of the code
or, if you need functions or classes to be defined:
# --------------------------
# Log part:
# --------------------------
def my_log(request):
with open("mylog.log", "at") as f:
f.write(repr(request))
my_log(request)
# --------------------------
# Controllers part:
# --------------------------
def index():
# index controller definition
# ... rest of the code
Of course, repr(request) is not how you want it, but you get the idea: from there you can log any information you like before the controllers are called (they are just defined at this stage).
The server already maintains a log in the root directory, in httpserver.log.
Place the code in a model file and it will get executed before any controllers. If you only want the code to execute for a specific controller, place it at the top of the controller before any functions.