LOG - repograph: new option --tab-separated

This commit is contained in:
Vladimir Testov 2012-11-07 11:31:34 -05:00
parent be12c9cebe
commit 35a3dde9f5

View file

@ -56,10 +56,6 @@ from rpm5utils.urpmgraphs.algorithms.cycles import simple_cycles
import gettext import gettext
gettext.install('urpm-tools') gettext.install('urpm-tools')
#import rpm5utils.urpmgraphs
#from rpm5utils.urpmgraphs.algorithms import cycles
#from rpm5utils.urpmgraphs.classes import digraph
synthesis_arch = "synthesis.hdlist.cz" synthesis_arch = "synthesis.hdlist.cz"
synthesis_arch_renamed = "synthesis.hdlist.gz" synthesis_arch_renamed = "synthesis.hdlist.gz"
@ -72,6 +68,9 @@ loopdotfile = "loopgraph"
altdotfile = "altgraph" altdotfile = "altgraph"
default_output = "sys.stdout" default_output = "sys.stdout"
timeout = 5 timeout = 5
nodes_file = "nodes.txt"
edges_file = "edges.txt"
modedef = ['normal', 'cross-repo', 'broken']
re_search_unver = re.compile("([^\[\]]+)[\[\]]") re_search_unver = re.compile("([^\[\]]+)[\[\]]")
re_search_verrel = re.compile("\[(== |> |< |>= |<= )([\{\}+=0-9a-zA-Z_\.]*:)?([[\{\}+=0-9a-zA-Z_\.]+)(-[[\{\}+=0-9a-zA-Z_\.]+)?([^\[\]]*)\]$") re_search_verrel = re.compile("\[(== |> |< |>= |<= )([\{\}+=0-9a-zA-Z_\.]*:)?([[\{\}+=0-9a-zA-Z_\.]+)(-[[\{\}+=0-9a-zA-Z_\.]+)?([^\[\]]*)\]$")
@ -87,7 +86,7 @@ def ParseCommandLine():
parser.add_argument("repository", action="store", nargs=1, parser.add_argument("repository", action="store", nargs=1,
metavar="REPOSITORY", help="URL or local PATH to repository.") metavar="REPOSITORY", help="URL or local PATH to repository.")
parser.add_argument("--cross", "-c", action="store", nargs='+', metavar="CROSS_REPO", parser.add_argument("--cross", "-c", action="store", nargs='+', metavar="CROSS_REPO",
help=_("Search for cross-repository references in CROSS_REPO(s) repositories.")) help=_("Search for cross-repository references in CROSS_REPO(s) repositories."))
parser.add_argument("--quiet", "-q", action="store_false", parser.add_argument("--quiet", "-q", action="store_false",
help=_("Hide service messages. (About progress status etc.)")) help=_("Hide service messages. (About progress status etc.)"))
@ -128,6 +127,10 @@ def ParseCommandLine():
graphgroup.add_argument("--nograph", "-n", action="store_true", graphgroup.add_argument("--nograph", "-n", action="store_true",
help=_("Do not output graph. Tool will not start working if --quiet, --nograph are present \ help=_("Do not output graph. Tool will not start working if --quiet, --nograph are present \
and --verbose is not. (If there is nothing to output - then nothing has to be done.)")) and --verbose is not. (If there is nothing to output - then nothing has to be done.)"))
parser.add_argument("--tab-separated", "-t", action="store_true",
help=_("Output in tab-separated format. If OUTPUT_FILE is not present, files \"" + nodes_file + "\" and \"" + edges_file + "\" \
will be created in the current directory. Otherwise these files will be written to the selected directory."))
return parser.parse_args() return parser.parse_args()
def exit_proc(arg): def exit_proc(arg):
@ -139,8 +142,9 @@ def exit_proc(arg):
err_loops = arg.loops err_loops = arg.loops
err_alternatives = arg.alternatives err_alternatives = arg.alternatives
err_different = arg.different err_different = arg.different
err_iftab = arg.tab_separated
if (err_output != None) and not ((err_loops or err_alternatives) and (err_different)): if (err_output != None) and not ((err_loops or err_alternatives) and (err_different)) and not err_iftab:
err_output.close() err_output.close()
if os.path.isdir(err_tmp_dir): if os.path.isdir(err_tmp_dir):
shutil.rmtree(err_tmp_dir) shutil.rmtree(err_tmp_dir)
@ -207,10 +211,25 @@ def CheckOutput(arg):
ifloops = arg.loops ifloops = arg.loops
ifalternatives = arg.alternatives ifalternatives = arg.alternatives
ifdifferent = arg.different ifdifferent = arg.different
iftab = arg.tab_separated
if (file_output == "sys.stdout") or (file_output == "stdout"): if (file_output == "sys.stdout") or (file_output == "stdout"):
arg.output = sys.stdout if iftab:
return if ifdifferent:
if ifalternatives:
arg.output = './' + altdotfile + '/'
elif ifloops:
arg.output = './' + loopdotfile + '/'
else:
arg.output = './'
file_output = arg.output
else:
arg.output = sys.stdout
return
else:
if iftab:
arg.output = './' + file_output + '/'
file_output = arg.output
if((ifloops or ifalternatives) and ifdifferent): # check for dir if((ifloops or ifalternatives) and ifdifferent): # check for dir
if(os.path.isdir(file_output)): if(os.path.isdir(file_output)):
print _("Error: directory %s already exists") % file_output print _("Error: directory %s already exists") % file_output
@ -233,6 +252,22 @@ def CheckOutput(arg):
file_output = file_output + '/' file_output = file_output + '/'
arg.output = file_output arg.output = file_output
else: else:
if iftab:
if os.path.isfile(file_output + nodes_file):
print _("Error: File %s already exists") % (file_output + nodes_file)
arg.output = None
exit_proc(arg)
if os.path.isfile(file_output + edges_file):
print _("Error: File %s already exists") % (file_output + edges_file)
arg.output = None
exit_proc(arg)
try:
os.makedirs(file_output)
except:
print _("Error: directory %s was not created") % file_output
arg.output = None
exit_proc(arg)
return
if(os.path.isfile(file_output)): if(os.path.isfile(file_output)):
print _("Error: File %s already exists") % file_output print _("Error: File %s already exists") % file_output
arg.output = None arg.output = None
@ -378,10 +413,14 @@ def RPMNameFilter(rpmname, disttagepoch):
string = rpmname.split('-') string = rpmname.split('-')
lastpart = string.pop() lastpart = string.pop()
tmp = lastpart.split('.') tmp = lastpart.split('.')
tmp.pop() issrc = (tmp.pop() == "src")
ismageia = 0
if tmp[-1].startswith("mga"):
tmp.pop()
ismageia = 1
lastpart = '.'.join(tmp) lastpart = '.'.join(tmp)
if (lastpart[0].isdigit() or (not lastpart.startswith(disttagepoch))) and\ if (lastpart[0].isdigit() or (not lastpart.startswith(disttagepoch))) and\
(not lastpart.isdigit()): ((not lastpart.isdigit()) or issrc or ismageia):
name = '-'.join(string[:-1]) name = '-'.join(string[:-1])
else: else:
name = '-'.join(string[:-2]) name = '-'.join(string[:-2])
@ -825,10 +864,14 @@ def AssignColors(dict_depend, count_depend, arg):
""" """
ifnotquiet = arg.quiet ifnotquiet = arg.quiet
ifchangecolors = arg.whatrequires ifchangecolors = arg.whatrequires
iftab = arg.tab_separated
dict_colors = {} dict_colors = {}
dict_count = {} dict_count = {}
if iftab:
return dict_colors
if ifnotquiet: if ifnotquiet:
print _("Calculating colors.") print _("Calculating colors.")
sorted_count = sorted(count_depend) sorted_count = sorted(count_depend)
@ -913,50 +956,116 @@ def OutputGraphBody(some_list, dict_color, file_output, packagename, node_type):
tmp_string = tmp_string + '};\n\n' tmp_string = tmp_string + '};\n\n'
file_output.write(tmp_string) file_output.write(tmp_string)
def OutputGraphTail(file_output): def OutputGraphTail(file_output):
"""Finish the graph. """Finish the graph.
""" """
file_output.write('}\n') file_output.write('}\n')
def GetNodesEdges(dict_depend):
nodes = {}
edges = []
for packagename in dict_depend:
if packagename not in nodes:
nodes[packagename] = 0
for pkg in dict_depend[packagename]:
if pkg not in nodes:
nodes[pkg] = 0
mode = dict_depend[packagename][pkg]
edges.append([packagename, pkg, mode])
if mode == 2:
nodes[pkg] = 2
return (nodes, edges)
def OutputNodes(dict_depend, nodes, arg):
"""Output nodes.
"""
output_dir = arg.output
file_output = output_dir + nodes_file
if os.path.isfile(file_output):
print _("Error: File %s already exists") % file_output
arg.output = None
exit_proc(arg)
sorted_list = sorted(nodes)
try:
NODES = open(file_output, "w")
except:
print _("Error: File %s cannot be created") % file_output
arg.output = None
exit_proc(arg)
for pkg in sorted_list:
NODES.write('\t'.join([pkg, modedef[nodes[pkg]]]))
NODES.write('\n')
NODES.close()
def OutputEdges(dict_depend, edges, arg):
"""Output edges.
"""
output_dir = arg.output
file_output = output_dir + edges_file
if os.path.isfile(file_output):
print _("Error: File %s already exists") % file_output
arg.output = None
exit_proc(arg)
try:
EDGES = open(file_output, "w")
except:
print _("Error: File %s cannot be created") % file_output
arg.output = None
exit_proc(arg)
for (node1, node2, mode) in edges:
EDGES.write('\t'.join([node1, node2, modedef[mode]]))
EDGES.write('\n')
EDGES.close()
def OutputGraph(dict_depend, dict_color, arg): def OutputGraph(dict_depend, dict_color, arg):
"""Output the graph. """Output the graph.
""" """
file_output = arg.output file_output = arg.output
iftab = arg.tab_separated
if arg.whatrequires: if arg.whatrequires:
selected_node = arg.whatrequires[0] selected_node = arg.whatrequires[0]
elif arg.requires_recursive: elif arg.requires_recursive:
selected_node = arg.requires_recursive[0] selected_node = arg.requires_recursive[0]
else: else:
selected_node = None selected_node = None
OutputGraphHead(file_output)
if (selected_node): if not iftab:
file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n') OutputGraphHead(file_output)
sorted_list = sorted(dict_depend)
for packagename in sorted_list:
if not dict_depend[packagename]:
continue
usual_list = []
cross_list = []
missed_list = []
for pkg in dict_depend[packagename]:
mode = dict_depend[packagename][pkg]
if (mode == 0):
usual_list.append(pkg)
elif (mode == 1):
cross_list.append(pkg)
elif (mode == 2):
missed_list.append(pkg)
if (len(usual_list) > 0): if (selected_node):
OutputGraphBody(usual_list, dict_color, file_output, packagename, 0) file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n')
if (len(cross_list) > 0): sorted_list = sorted(dict_depend)
OutputGraphBody(cross_list, dict_color, file_output, packagename, 1) for packagename in sorted_list:
if (len(missed_list) > 0): if not dict_depend[packagename]:
OutputGraphBody(missed_list, None, file_output, packagename, 2) continue
usual_list = []
cross_list = []
missed_list = []
for pkg in dict_depend[packagename]:
mode = dict_depend[packagename][pkg]
if (mode == 0):
usual_list.append(pkg)
elif (mode == 1):
cross_list.append(pkg)
elif (mode == 2):
missed_list.append(pkg)
OutputGraphTail(file_output) if (len(usual_list) > 0):
OutputGraphBody(usual_list, dict_color, file_output, packagename, 0)
if (len(cross_list) > 0):
OutputGraphBody(cross_list, dict_color, file_output, packagename, 1)
if (len(missed_list) > 0):
OutputGraphBody(missed_list, None, file_output, packagename, 2)
OutputGraphTail(file_output)
else: #iftab == TRUE
(nodes, edges) = GetNodesEdges(dict_depend)
OutputNodes(dict_depend, nodes, arg)
OutputEdges(dict_depend, edges, arg)
def CountPor(number): def CountPor(number):
tmp = number / 10 tmp = number / 10
@ -973,74 +1082,206 @@ def LeadingZeroes(number, por):
def OutputLoopGraph(loops, colors, arg): def OutputLoopGraph(loops, colors, arg):
"""Output graph(s) of loops. """Output graph(s) of loops.
""" """
iftab = arg.tab_separated
ifdifferent = arg.different ifdifferent = arg.different
if arg.whatrequires:
selected_node = arg.whatrequires[0]
elif arg.requires_recursive:
selected_node = arg.requires_recursive[0]
else:
selected_node = None
output = arg.output if not iftab:
file_output = output if arg.whatrequires:
if not ifdifferent: selected_node = arg.whatrequires[0]
OutputGraphHead(file_output) elif arg.requires_recursive:
if (selected_node): selected_node = arg.requires_recursive[0]
file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n') else:
selected_node = None
length = len(colors) output = arg.output
por = CountPor(length) file_output = output
for i in range(length): if not ifdifferent:
if ifdifferent:
filename = output + loopdotfile + LeadingZeroes(i, por) + '.dot'
file_output = open(filename, 'w')
OutputGraphHead(file_output) OutputGraphHead(file_output)
if (selected_node): if (selected_node):
file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n') file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n')
OutputGraphLoopBody(loops[i], colors[i], file_output)
if ifdifferent:
OutputGraphTail(file_output)
file_output.close()
if not ifdifferent: length = len(colors)
OutputGraphTail(file_output) por = CountPor(length)
for i in range(length):
if ifdifferent:
filename = output + loopdotfile + LeadingZeroes(i, por) + '.dot'
try:
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
OutputGraphHead(file_output)
if (selected_node):
file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n')
OutputGraphLoopBody(loops[i], colors[i], file_output)
if ifdifferent:
OutputGraphTail(file_output)
file_output.close()
if not ifdifferent:
OutputGraphTail(file_output)
else: #tab-separated
output = arg.output
if not ifdifferent:
filename = output + edges_file
try:
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
length = len(loops)
pot = CountPor(length)
nodes = []
i = 0
for loop in loops:
if ifdifferent:
dirname = output + loopdotfile + LeadingZeroes(i, pot) + '/'
filename = dirname + edges_file
try:
os.makedirs(dirname)
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
nodes = []
j = 0
for pkg in loop:
if j == 0:
j = 1
file_output.write(str(pkg))
else:
file_output.write('\t' + str(pkg))
if pkg not in nodes:
nodes.append(pkg)
file_output.write('\n')
if ifdifferent:
file_output.close()
filename = dirname + nodes_file
try:
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
for pkg in nodes:
file_output.write(str(pkg) + '\n')
file_output.close()
i = i + 1
if not ifdifferent:
filename = output + nodes_file
try:
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
for pkg in nodes:
file_output.write(str(pkg) + '\n')
file_output.close()
def OutputAltGraph(alternatives, colors, arg): def OutputAltGraph(alternatives, colors, arg):
"""Output graph(s) of alternatives. """Output graph(s) of alternatives.
""" """
iftab = arg.tab_separated
ifdifferent = arg.different ifdifferent = arg.different
if arg.whatrequires:
selected_node = arg.whatrequires[0]
elif arg.requires_recursive:
selected_node = arg.requires_recursive[0]
else:
selected_node = None
output = arg.output if not iftab:
file_output = output if arg.whatrequires:
if not ifdifferent: selected_node = arg.whatrequires[0]
OutputGraphHead(file_output) elif arg.requires_recursive:
if (selected_node): selected_node = arg.requires_recursive[0]
file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n') else:
selected_node = None
i = 0 output = arg.output
length = len(colors) file_output = output
por = CountPor(length) if not ifdifferent:
for phrase in alternatives:
if ifdifferent:
filename = output + altdotfile + LeadingZeroes(i, por) + '.dot'
file_output = open(filename, 'w')
OutputGraphHead(file_output) OutputGraphHead(file_output)
if (selected_node): if (selected_node):
file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n') file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n')
OutputGraphAltBody(phrase, alternatives[phrase], colors[i], file_output)
if ifdifferent:
OutputGraphTail(file_output)
file_output.close()
i = i + 1
if not ifdifferent: i = 0
OutputGraphTail(file_output) length = len(colors)
por = CountPor(length)
for phrase in alternatives:
if ifdifferent:
filename = output + altdotfile + LeadingZeroes(i, por) + '.dot'
try:
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
OutputGraphHead(file_output)
if (selected_node):
file_output.write('"' + selected_node + '" [color="0.4 1.0 1.0"];\n')
OutputGraphAltBody(phrase, alternatives[phrase], colors[i], file_output)
if ifdifferent:
OutputGraphTail(file_output)
file_output.close()
i = i + 1
if not ifdifferent:
OutputGraphTail(file_output)
else: #tab-separated
output = arg.output
if not ifdifferent:
filename = output + edges_file
try:
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
length = len(alternatives)
pot = CountPor(length)
nodes = []
i = 0
for phrase in alternatives:
if ifdifferent:
dirname = output + altdotfile + LeadingZeroes(i, pot) + '/'
filename = dirname + edges_file
try:
os.makedirs(dirname)
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
nodes = []
file_output.write(str(phrase))
for pkg in alternatives[phrase]:
file_output.write('\t' + str(pkg))
if pkg not in nodes:
nodes.append(pkg)
file_output.write('\n')
if ifdifferent:
file_output.close()
filename = dirname + nodes_file
try:
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
for pkg in nodes:
file_output.write(str(pkg) + '\n')
file_output.close()
i = i + 1
if not ifdifferent:
filename = output + nodes_file
try:
file_output = open(filename, 'w')
except:
print _("Error: file %s cannot be created") % filename
arg.output = None
exit_proc(arg)
for pkg in nodes:
file_output.write(str(pkg) + '\n')
file_output.close()
def BuildGraph(dict_depend): def BuildGraph(dict_depend):
"""Build additional structures. """Build additional structures.
@ -1389,6 +1630,7 @@ def main(args):
ifbroken = arg.broken ifbroken = arg.broken
ifoptact = ifloops or ifalternatives or ifbroken ifoptact = ifloops or ifalternatives or ifbroken
ifunprovided = arg.unprovided ifunprovided = arg.unprovided
iftab = arg.tab_separated
arg.crossurl = [] arg.crossurl = []
arg.tmp_dir = "" arg.tmp_dir = ""
@ -1396,7 +1638,7 @@ def main(args):
file_output = arg.output[0] file_output = arg.output[0]
else: else:
file_output = default_output file_output = default_output
arg.output = None arg.output = file_output
if (not ifnotquiet) and (not ifverbose) and (ifnograph): if (not ifnotquiet) and (not ifverbose) and (ifnograph):
print _("Do not use -q/--quiet and -n/--nograph without -v/--verbose together.") print _("Do not use -q/--quiet and -n/--nograph without -v/--verbose together.")
print _("That way there is no information to output anywhere. Nothing will be done.") print _("That way there is no information to output anywhere. Nothing will be done.")
@ -1412,6 +1654,8 @@ def main(args):
for i in crossrange: for i in crossrange:
arg.crossurl.append(CheckURLPATH(arg.cross[i], arg)) arg.crossurl.append(CheckURLPATH(arg.cross[i], arg))
CheckOptions(arg) CheckOptions(arg)
CheckOutput(arg)
arg.tmp_dir = tempfile.mkdtemp() + '/' arg.tmp_dir = tempfile.mkdtemp() + '/'
#get all needed files #get all needed files
GetFile(arg.repository, synthesis_arch, arg.tmp_dir, arg) GetFile(arg.repository, synthesis_arch, arg.tmp_dir, arg)
@ -1439,8 +1683,6 @@ def main(args):
if (answer): if (answer):
(dict_depend, count_depend, dict_asks, dict_provides, dict_cross_asks, dict_cross_provides) = answer (dict_depend, count_depend, dict_asks, dict_provides, dict_cross_asks, dict_cross_provides) = answer
arg.output = file_output
CheckOutput(arg)
if (ifoptact): ##REMAKE (MUTUALLY EXCLUSIVE) if (ifoptact): ##REMAKE (MUTUALLY EXCLUSIVE)
if (ifloops): if (ifloops):
loops = FindLoops(dict_depend, arg) loops = FindLoops(dict_depend, arg)