/******************************************************************************* Copyright (c) 1997-2004, Perforce Software, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTR IBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ /******************************************************************************* * Name : clientuserruby.h * * Author : Tony Smith <tony@perforce.com> or <tony@smee.org> * * Description : Ruby bindings for the Perforce API. User interface class * for getting Perforce results into Ruby. * ******************************************************************************/ /******************************************************************************* * ClientUserRuby - the user interface part. Gets responses from the Perforce * server, and converts the data to Ruby form for returning to the caller. ******************************************************************************/ class ClientUserRuby : public ClientUser { public: ClientUserRuby(); // Client User methods overridden here void HandleError( Error *e ); void OutputText( const_char *data, int length ); void OutputInfo( char level, const_char *data ); void OutputStat( StrDict *values ); void OutputBinary( const_char *data, int length ); void InputData( StrBuf *strbuf, Error *e ); void Diff( FileSys *f1, FileSys *f2, int doPage, char *diffFlags, Error *e ); void Prompt( const StrPtr &msg, StrBuf &rsp, int noEcho, Error *e ); int Resolve( ClientMerge *m, Error *e ); void Finished(); // Local methods VALUE SetInput( VALUE i ); P4Result& GetResults() { return results; } int ErrorCount(); void Reset(); StrPtr & LastSpecDef() { return lastSpecDef; } // GC support void GCMark(); // Debugging support void SetDebug( int d ) { debug = d; } private: VALUE MkMergeInfo( ClientMerge *m, StrPtr &hint ); private: P4Result results; StrBuf lastSpecDef; VALUE input; VALUE mergeData; VALUE mergeResult; int debug; };
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#15 | 5791 | Tony Smith |
Add experimental support for passing a block to P4#run_resolve. The block is passed a P4::MergeData object encapsulating the context of each merge performed. The block should evaluate to a string indicating the desired result of the merge: 'ay', 'at', 'am', 's', etc. The P4::MergeData object contains information about the files involved in the merge and can invoke an external merge tool. This is still experimental at this stage so the interface may change as it evolves. |
||
#14 | 4680 | Tony Smith |
Make P4Ruby return new P4::Spec objects instead of plain old hashes when parse_forms mode is in use. A P4::Spec object is derived from Hash so should be backwards compatible with previous code. P4::Spec provides limited fieldname validation on forms and accessor methods for quick and easy access to the fields in the form. The accessor methods are all prefixed with '_' to avoid colliding with methods from the Hash parent class. This is a little ugly, but deriving from hash is a big win, so it's worth it. This change also fixes a minor bug found along the way. Spec parsing and formatting wouldn't work with labels, branches, depots and groups unless you'd previously run a P4::fetch_label( <label> ), P4::fetch_branch( <branch> ) etc. etc. This is because the spec parsing code internally runs one of these commands in order to grab the specdef from the server but it wasn't providing a spec name. i.e. it was using 'p4 client -o' and assuming that this would work for other types of spec too. It does, but not for all spec types. So, now the spec parsing code will use a bogus name for the spec types that require it. |
||
#13 | 4651 | Tony Smith |
Add format_spec() method and format_* shortcuts to make it easy to convert a spec in a hash back to its string form without sending it to the server. |
||
#12 | 4593 | Tony Smith |
Add support for 'p4 login' to P4Ruby per request from Robert Cowham. New installer to follow. |
||
#11 | 4261 | Tony Smith |
Add support for parsing arbitrary specs from strings in Ruby space. Useful with spec depots. You might obtain the spec by running a "p4 print -q" against a file in a spec depot, but want to parse it into a Ruby hash. i.e. p4 = P4.new p4.parse_forms # Required! p4.connect buf = p4.run_print( "-q", "//specs/client/myclient" ) spec = p4.parse_client( buf ) # Or equivalently spec = p4.parse_spec( "client", buf ) |
||
#10 | 4157 | Tony Smith |
Copyright notice update. No functional change |
||
#9 | 2210 | Tony Smith |
Bug fix to change 2085 which broke form parsing as the specdef variable is only available within the context of the command being executed and the SetInput() method was trying to use it outside of any command context. That and having a bad condition in the test for its existence was causing a segvio. |
||
#8 | 2086 | Tony Smith |
Add support for capturing the output of "p4 diff" to the Ruby API interface. |
||
#7 | 1464 | Tony Smith |
Add support for binary output - mainly for "p4 print binary_file". Binary output is returned in a Ruby string. Note that due to the fragmentation of large messages by the Perforce server, P4#run( "print", "-q", "binfile" ) can return an array of more than one element - each element comprising a chunk of the same file. If you're only printing one file, then you can simply use: p4.run_print( "-q", binfile ).join( "" ) If you're printing more than one file, you'll have to iterate over the result array to find the file markers ( using "-q" is a bad plan in this case ). Each file marker will be in a separate element of the array though. |
||
#6 | 1391 | Tony Smith |
Bug fix. Garbage collection can apparently run at any time (i.e. when you're in C space and not just when you're in Ruby space) and it was occasionally running in between adjacent "delete" and "new" statements when the result set was being reset. This change removes this race condition by making the result member of ClientUserRuby a permanently instantiated variable and extending the P4Result class so that it can reset itself in a way that GC respects. Now the only dynamically allocated C++ object is the top level P4ClientApi object. No functional change. |
||
#5 | 1164 | Tony Smith |
Reworked exception handling (hopefully for the last time) in P4/Ruby. Now exceptions are raised on completion of Perforce commands if any errors or warnings were received as part of executing the command. This change also adds documentation, and indexes the Ruby interface off my main page. Bad form to combine so many changes in one changelist, but it's getting late and I want to get them submitted! |
||
#4 | 1083 | Tony Smith |
Sweeping change to exception handling and garbage collection. Exceptions are no longer raised for errors encoutered during execution of Perforce commands as that was causing processing to abort at the first error when several success messages may have been close behind. Now exceptions are raised for events which are fatal to the execution of commands - such as failure to connect to the Perforce server for example. For other errors, the user must call "p4.errors? " to determine whether or not errors occured and "p4.errors" to get an array of error messages. You can of course then raise exceptions yourself if you want to: begin client = p4.fetch_client if p4.errors? raise P4Exception, "p4 client -o failed" end rescue P4Exception => m puts( m ) p4.errors.each { |e| puts( e ) } end version.h got renamed because it conflicts with ruby's own version.h file. We may need to look in there at some point for ruby's version so I'm getting it out of the way now. Added gc_hack.h to make sure that GC works properly on all platforms now so Ruby shouldn't nuke any objects we're holding now. |
||
#3 | 1081 | Tony Smith |
Debugging and identification support. Adds two new methods: P4#identify() P4#debug( int ) |
||
#2 | 1051 | Tony Smith | Port nested data handling code from Perl API to Ruby API. | ||
#1 | 1015 | Tony Smith |
First cut of Perforce bindings for the Ruby scripting language. Similar functionality to the Perl API stuff, but "rubyfied". Supports error reporting via exceptions, and presents tagged output and parsed forms as hash structures, with nested arrays where required. Still early days so the docs are thin on the ground. See the example.pl for a brief guide. Built with Ruby 1.6.4 on Linux. May still be some memory management issues as the Ruby Garbage Collection API has changed a little since the docs I've got and I've just dodged garbage collection for now. Not indexing this just yet. |