blob: 705ffc5d6ee16a66fe4e9dddae5a3672b3fad4a5 [file] [log] [blame]
#!/usr/bin/env python
#
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
#
import sys
import os
import getpass
from svn import client, ra, core
def printer(segment, pool):
path = segment.path is not None and segment.path or "(null)"
print("r%d-r%d: %s" % (segment.range_start, segment.range_end, path))
def parse_args(args):
argc = len(sys.argv)
# parse the target URL and optional peg revision
path_pieces = args[0].split('@')
if len(path_pieces) > 1:
peg_revision = int(path_pieces[-1])
assert peg_revision >= 0
url = '@'.join(path_pieces[:-1])
else:
peg_revision = core.SVN_INVALID_REVNUM
url = path_pieces[0]
url = core.svn_path_canonicalize(url)
# parse the revision range, if any
if argc > 2:
rev_pieces = args[1].split(':')
num_revs = len(rev_pieces)
assert num_revs < 3
if num_revs == 2:
start_revision = int(rev_pieces[0])
end_revision = int(rev_pieces[1])
else:
start_revision = end_revision = int(rev_pieces[0])
assert(start_revision >= 0)
assert(end_revision >= 0)
else:
start_revision = peg_revision
end_revision = 0
# validate
if start_revision >= 0 \
and end_revision >= 0 \
and end_revision > start_revision:
raise Exception("End revision must not be younger than start revision")
if peg_revision >= 0 \
and start_revision >= 0 \
and start_revision > peg_revision:
raise Exception("Start revision must not be younger than peg revision")
return url, peg_revision, start_revision, end_revision
def prompt_func_ssl_unknown_cert(realm, failures, cert_info, may_save, pool):
print( "The certficate details are as follows:")
print("--------------------------------------")
print("Issuer : " + str(cert_info.issuer_dname))
print("Hostname : " + str(cert_info.hostname))
print("ValidFrom : " + str(cert_info.valid_from))
print("ValidUpto : " + str(cert_info.valid_until))
print("Fingerprint: " + str(cert_info.fingerprint))
print("")
ssl_trust = core.svn_auth_cred_ssl_server_trust_t()
if may_save:
choice = raw_input( "accept (t)temporarily (p)permanently: ")
else:
choice = raw_input( "(r)Reject or accept (t)temporarily: ")
if choice[0] == "t" or choice[0] == "T":
ssl_trust.may_save = False
ssl_trust.accepted_failures = failures
elif choice[0] == "p" or choice[0] == "P":
ssl_trust.may_save = True
ssl_trust.accepted_failures = failures
else:
ssl_trust = None
return ssl_trust
def prompt_func_simple_prompt(realm, username, may_save, pool):
username = raw_input("username: ")
password = getpass.getpass(prompt="password: ")
simple_cred = core.svn_auth_cred_simple_t()
simple_cred.username = username
simple_cred.password = password
simple_cred.may_save = False
return simple_cred
def prompt_func_gnome_keyring_prompt(keyring, pool):
return getpass.getpass(prompt="Password for '%s' GNOME keyring: " % keyring)
def main():
try:
url, peg_revision, start_revision, end_revision = parse_args(sys.argv[1:])
except Exception as e:
sys.stderr.write("""Usage: %s URL[@PEG-REV] [START-REV[:END-REV]]
Trace the history of URL@PEG-REV, printing the location(s) of its
existence between START-REV and END-REV. If START-REV is not
provided, the entire history of URL@PEG-REV back to its origin will be
displayed. If provided, START-REV must not be younger than PEG-REV.
If END-REV is provided, it must not be younger than START-REV.
(This is a wrapper around Subversion's svn_ra_get_location_segments() API.)
ERROR: %s
""" % (os.path.basename(sys.argv[0]), str(e)))
sys.exit(1)
core.svn_config_ensure(None)
ctx = client.svn_client_create_context()
ctx.config = core.svn_config_get_config(None)
# Make sure that these are at the start of the list, so passwords from
# gnome-keyring / kwallet are checked before asking for new passwords.
providers = core.svn_auth_get_platform_specific_client_providers(ctx.config['config'], None)
providers.extend([
client.get_simple_provider(),
core.svn_auth_get_ssl_server_trust_file_provider(),
core.svn_auth_get_simple_prompt_provider(prompt_func_simple_prompt, 2),
core.svn_auth_get_ssl_server_trust_prompt_provider(prompt_func_ssl_unknown_cert),
client.get_username_provider(),
client.get_ssl_server_trust_file_provider(),
client.get_ssl_client_cert_file_provider(),
client.get_ssl_client_cert_pw_file_provider(),
])
ctx.auth_baton = core.svn_auth_open(providers)
if hasattr(core, 'svn_auth_set_gnome_keyring_unlock_prompt_func'):
core.svn_auth_set_gnome_keyring_unlock_prompt_func(ctx.auth_baton, prompt_func_gnome_keyring_prompt)
ra_callbacks = ra.callbacks_t()
ra_callbacks.auth_baton = ctx.auth_baton
ra_session = ra.open(url, ra_callbacks, None, ctx.config)
ra.get_location_segments(ra_session, "", peg_revision,
start_revision, end_revision, printer)
if __name__ == "__main__":
main()