2 * Copyright 2007-2009 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * François Revol, revol@free.fr
7 * Jonas Sundström, jonas@kirilla.com
11 * CheckItOut: wraps SCM URL mime types around command line apps
12 * to check out sources in a user-friendly fashion.
22 #include <FilePanel.h>
29 #include "checkitout.h"
32 const char* kAppSig
= "application/x-vnd.Haiku-checkitout";
33 const char* kTrackerSig
= "application/x-vnd.Be-TRAK";
35 const char* kTerminalSig
= "application/x-vnd.Haiku-Terminal";
37 const char* kTerminalSig
= "application/x-vnd.Be-SHEL";
40 CheckItOut::CheckItOut() : BApplication(kAppSig
)
45 CheckItOut::~CheckItOut()
51 CheckItOut::_Warn(const char* url
)
53 BString
message("An application has requested the system to open the "
55 message
<< "\n" << url
<< "\n\n";
56 message
<< "This type of URL has a potential security risk.\n";
57 message
<< "Proceed anyway?";
58 BAlert
* alert
= new BAlert("Warning", message
.String(), "Proceed", "Stop", NULL
,
59 B_WIDTH_AS_USUAL
, B_WARNING_ALERT
);
60 alert
->SetShortcut(1, B_ESCAPE
);
71 CheckItOut::_FilePanel(uint32 nodeFlavors
, BString
&name
)
73 BFilePanel
*panel
= new BFilePanel(B_SAVE_PANEL
);
75 BMessenger* target = NULL, const entry_ref* directory = NULL,
76 uint32 nodeFlavors = 0, bool allowMultipleSelection = true,
77 BMessage* message = NULL, BRefFilter* refFilter = NULL,
78 bool modal = false, bool hideWhenDone = true);
80 panel
->Window()->SetTitle("Check It Out to...");
81 panel
->SetSaveText(name
.String());
88 CheckItOut::RefsReceived(BMessage
* msg
)
94 CheckItOut::MessageReceived(BMessage
* msg
)
98 case B_SAVE_REQUESTED
:
102 msg
->FindRef("directory", &ref
);
103 msg
->FindString("name", &name
);
104 _DoCheckItOut(&ref
, name
.String());
115 CheckItOut::ArgvReceived(int32 argc
, char** argv
)
125 BString full
= BUrl(url
).SetProtocol(BString()).UrlString();
126 BString proto
= url
.Protocol();
127 BString host
= url
.Host();
128 BString port
= BString() << url
.Port();
129 BString user
= url
.UserInfo();
130 BString pass
= url
.Password();
131 BString path
= url
.Path();
133 if (!url
.IsValid()) {
134 fprintf(stderr
, "malformed url: '%s'\n", url
.UrlString().String());
139 PRINT(("PROTO='%s'\n", proto
.String()));
140 PRINT(("HOST='%s'\n", host
.String()));
141 PRINT(("PORT='%s'\n", port
.String()));
142 PRINT(("USER='%s'\n", user
.String()));
143 PRINT(("PASS='%s'\n", pass
.String()));
144 PRINT(("PATH='%s'\n", path
.String()));
146 BString
leaf(url
.Path());
147 if (leaf
.FindLast('/') > -1)
148 leaf
.Remove(0, leaf
.FindLast('/') + 1);
149 PRINT(("leaf %s\n", leaf
.String()));
150 _FilePanel(B_DIRECTORY_NODE
, leaf
);
155 CheckItOut::_DoCheckItOut(entry_ref
*ref
, const char *name
)
157 const char* failc
= " || read -p 'Press any key'";
158 const char* pausec
= " ; read -p 'Press any key'";
159 char* args
[] = { (char *)"/bin/sh", (char *)"-c", NULL
, NULL
};
161 BUrl
url(fUrlString
);
162 BString full
= BUrl(url
).SetProtocol(BString()).UrlString();
163 BString proto
= url
.Protocol();
164 BString host
= url
.Host();
165 BString port
= BString() << url
.Port();
166 BString user
= url
.UserInfo();
167 BString pass
= url
.Password();
168 BString path
= url
.Path();
169 PRINT(("url %s\n", url
.UrlString().String()));
172 if (proto
== "git") {
173 BString
cmd("git clone ");
175 cmd
<< " '" << refPath
.Path() << "/" << name
<< "'";
176 PRINT(("CMD='%s'\n", cmd
.String()));
177 cmd
<< " && open '" << refPath
.Path() << "/" << name
<< "'";
179 PRINT(("CMD='%s'\n", cmd
.String()));
180 args
[2] = (char*)cmd
.String();
181 be_roster
->Launch(kTerminalSig
, 3, args
);
184 if (proto
== "rsync") {
185 BString
cmd("rsync ");
187 cmd
<< " '" << refPath
.Path() << "/" << name
<< "'";
188 PRINT(("CMD='%s'\n", cmd
.String()));
189 cmd
<< " && open '" << refPath
.Path() << "/" << name
<< "'";
191 PRINT(("CMD='%s'\n", cmd
.String()));
192 args
[2] = (char*)cmd
.String();
193 be_roster
->Launch(kTerminalSig
, 3, args
);
196 if (proto
== "svn" || proto
== "svn+ssh") {
197 BString
cmd("svn checkout ");
199 cmd
<< " '" << refPath
.Path() << "/" << name
<< "'";
200 PRINT(("CMD='%s'\n", cmd
.String()));
201 cmd
<< " && open '" << refPath
.Path() << "/" << name
<< "'";
203 PRINT(("CMD='%s'\n", cmd
.String()));
204 args
[2] = (char*)cmd
.String();
205 be_roster
->Launch(kTerminalSig
, 3, args
);
213 CheckItOut::_DecodeUrlString(BString
& string
)
215 // TODO: check for %00 and bail out!
216 int32 length
= string
.Length();
218 for (i
= 0; string
[i
] && i
< length
- 2; i
++) {
219 if (string
[i
] == '%' && isxdigit(string
[i
+1])
220 && isxdigit(string
[i
+2])) {
222 sscanf(string
.String() + i
+ 1, "%02x", &c
);
224 string
.Insert((char)c
, 1, i
);
234 CheckItOut::ReadyToRun(void)
243 int main(int argc
, char** argv
)