Skip to content

Commit

Permalink
Merge pull request conda#1231 from asmeurer/clean-envs-dirs
Browse files Browse the repository at this point in the history
Clean envs dirs
  • Loading branch information
asmeurer committed Sep 28, 2015
2 parents 4447576 + 0855e44 commit 716db30
Showing 1 changed file with 101 additions and 89 deletions.
190 changes: 101 additions & 89 deletions conda/cli/main_clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import os
import sys
from collections import defaultdict

from os.path import join, getsize, isdir
from os import lstat, walk, listdir
Expand Down Expand Up @@ -100,29 +101,29 @@ def rm_lock(locks, verbose=True):


def find_tarballs():
pkgs_dir = config.pkgs_dirs[0]

rmlist = []
for fn in os.listdir(pkgs_dir):
if fn.endswith('.tar.bz2') or fn.endswith('.tar.bz2.part'):
rmlist.append(fn)

if not rmlist:
return pkgs_dir, rmlist, 0
pkgs_dirs = defaultdict(list)
for pkgs_dir in config.pkgs_dirs:
if not isdir(pkgs_dir):
continue
for fn in os.listdir(pkgs_dir):
if fn.endswith('.tar.bz2') or fn.endswith('.tar.bz2.part'):
pkgs_dirs[pkgs_dir].append(fn)

totalsize = 0
for fn in rmlist:
size = getsize(join(pkgs_dir, fn))
totalsize += size
for pkgs_dir in pkgs_dirs:
for fn in pkgs_dirs[pkgs_dir]:
size = getsize(join(pkgs_dir, fn))
totalsize += size

return pkgs_dir, rmlist, totalsize
return pkgs_dirs, totalsize


def rm_tarballs(args, pkgs_dir, rmlist, totalsize, verbose=True):
def rm_tarballs(args, pkgs_dirs, totalsize, verbose=True):
if verbose:
print('Cache location: %s' % pkgs_dir)
for pkgs_dir in pkgs_dirs:
print('Cache location: %s' % pkgs_dir)

if not rmlist:
if not any(pkgs_dirs[i] for i in pkgs_dirs):
if verbose:
print("There are no tarballs to remove")
return
Expand All @@ -131,12 +132,15 @@ def rm_tarballs(args, pkgs_dir, rmlist, totalsize, verbose=True):
print("Will remove the following tarballs:")
print()

maxlen = len(max(rmlist, key=lambda x: len(str(x))))
fmt = "%-40s %10s"
for fn in rmlist:
size = getsize(join(pkgs_dir, fn))
print(fmt % (fn, human_bytes(size)))
print('-' * (maxlen + 2 + 10))
for pkgs_dir in pkgs_dirs:
print(pkgs_dir)
print('-'*len(pkgs_dir))
fmt = "%-40s %10s"
for fn in pkgs_dirs[pkgs_dir]:
size = getsize(join(pkgs_dir, fn))
print(fmt % (fn, human_bytes(size)))
print()
print('-' * 51) # From 40 + 1 + 10 in fmt
print(fmt % ('Total:', human_bytes(totalsize)))
print()

Expand All @@ -145,79 +149,82 @@ def rm_tarballs(args, pkgs_dir, rmlist, totalsize, verbose=True):
if args.json and args.dry_run:
return

for fn in rmlist:
if verbose:
print("removing %s" % fn)
os.unlink(os.path.join(pkgs_dir, fn))
for pkgs_dir in pkgs_dirs:
for fn in pkgs_dirs[pkgs_dir]:
if verbose:
print("removing %s" % fn)
os.unlink(os.path.join(pkgs_dir, fn))


def find_pkgs():
# TODO: This doesn't handle packages that have hard links to files within
# themselves, like bin/python3.3 and bin/python3.3m in the Python package
pkgs_dir = config.pkgs_dirs[0]
warnings = []

rmlist = []
pkgs = [i for i in listdir(pkgs_dir) if isdir(join(pkgs_dir, i)) and
# Only include actual packages
isdir(join(pkgs_dir, i, 'info'))]
for pkg in pkgs:
breakit = False
for root, dir, files in walk(join(pkgs_dir, pkg)):
if breakit:
break
for fn in files:
try:
stat = lstat(join(root, fn))
except OSError as e:
warnings.append((fn, e))
continue
if stat.st_nlink > 1:
# print('%s is installed: %s' % (pkg, join(root, fn)))
breakit = True
pkgs_dirs = defaultdict(list)
for pkgs_dir in config.pkgs_dirs:
pkgs = [i for i in listdir(pkgs_dir) if isdir(join(pkgs_dir, i)) and
# Only include actual packages
isdir(join(pkgs_dir, i, 'info'))]
for pkg in pkgs:
breakit = False
for root, dir, files in walk(join(pkgs_dir, pkg)):
if breakit:
break
else:
rmlist.append(pkg)

if not rmlist:
return pkgs_dir, rmlist, warnings, 0, []
for fn in files:
try:
stat = lstat(join(root, fn))
except OSError as e:
warnings.append((fn, e))
continue
if stat.st_nlink > 1:
# print('%s is installed: %s' % (pkg, join(root, fn)))
breakit = True
break
else:
pkgs_dirs[pkgs_dir].append(pkg)

totalsize = 0
pkgsizes = []
for pkg in rmlist:
pkgsize = 0
for root, dir, files in walk(join(pkgs_dir, pkg)):
for fn in files:
# We don't have to worry about counting things twice: by
# definition these files all have a link count of 1!
size = lstat(join(root, fn)).st_size
totalsize += size
pkgsize += size
pkgsizes.append(pkgsize)

return pkgs_dir, rmlist, warnings, totalsize, pkgsizes


def rm_pkgs(args, pkgs_dir, rmlist, warnings, totalsize, pkgsizes,
pkgsizes = defaultdict(list)
for pkgs_dir in pkgs_dirs:
for pkg in pkgs_dirs[pkgs_dir]:
pkgsize = 0
for root, dir, files in walk(join(pkgs_dir, pkg)):
for fn in files:
# We don't have to worry about counting things twice: by
# definition these files all have a link count of 1!
size = lstat(join(root, fn)).st_size
totalsize += size
pkgsize += size
pkgsizes[pkgs_dir].append(pkgsize)

return pkgs_dirs, warnings, totalsize, pkgsizes


def rm_pkgs(args, pkgs_dirs, warnings, totalsize, pkgsizes,
verbose=True):
if verbose:
print('Cache location: %s' % pkgs_dir)
for fn, exception in warnings:
print(exception)
for pkgs_dir in pkgs_dirs:
print('Cache location: %s' % pkgs_dir)
for fn, exception in warnings:
print(exception)

if not rmlist:
if not any(pkgs_dirs[i] for i in pkgs_dirs):
if verbose:
print("There are no unused packages to remove")
return

if verbose:
print("Will remove the following packages:")
print()
maxlen = len(max(rmlist, key=lambda x: len(str(x))))
fmt = "%-40s %10s"
for pkg, pkgsize in zip(rmlist, pkgsizes):
print(fmt % (pkg, human_bytes(pkgsize)))
print('-' * (maxlen + 2 + 10))
for pkgs_dir in pkgs_dirs:
print(pkgs_dir)
print('-' * len(pkgs_dir))
print()
fmt = "%-40s %10s"
for pkg, pkgsize in zip(pkgs_dirs[pkgs_dir], pkgsizes[pkgs_dir]):
print(fmt % (pkg, human_bytes(pkgsize)))
print()
print('-' * 51) # 40 + 1 + 10 in fmt
print(fmt % ('Total:', human_bytes(totalsize)))
print()

Expand All @@ -226,10 +233,11 @@ def rm_pkgs(args, pkgs_dir, rmlist, warnings, totalsize, pkgsizes,
if args.json and args.dry_run:
return

for pkg in rmlist:
if verbose:
print("removing %s" % pkg)
rm_rf(join(pkgs_dir, pkg))
for pkgs_dir in pkgs_dirs:
for pkg in pkgs_dirs[pkgs_dir]:
if verbose:
print("removing %s" % pkg)
rm_rf(join(pkgs_dir, pkg))


def rm_index_cache():
Expand Down Expand Up @@ -312,13 +320,15 @@ def execute(args, parser):
rm_lock(locks, verbose=not args.json)

if args.tarballs:
pkgs_dir, rmlist, totalsize = find_tarballs()
pkgs_dirs, totalsize = find_tarballs()
first = sorted(pkgs_dirs)[0] if pkgs_dirs else ''
json_result['tarballs'] = {
'pkgs_dir': pkgs_dir,
'files': rmlist,
'pkgs_dir': first, # Backwards compabitility
'pkgs_dirs': dict(pkgs_dirs),
'files': pkgs_dirs[first], # Backwards compatibility
'total_size': totalsize
}
rm_tarballs(args, pkgs_dir, rmlist, totalsize, verbose=not args.json)
rm_tarballs(args, pkgs_dirs, totalsize, verbose=not args.json)

if args.index_cache:
json_result['index_cache'] = {
Expand All @@ -327,15 +337,17 @@ def execute(args, parser):
rm_index_cache()

if args.packages:
pkgs_dir, rmlist, warnings, totalsize, pkgsizes = find_pkgs()
pkgs_dirs, warnings, totalsize, pkgsizes = find_pkgs()
first = sorted(pkgs_dirs)[0] if pkgs_dirs else ''
json_result['packages'] = {
'pkgs_dir': pkgs_dir,
'files': rmlist,
'pkgs_dir': first, # Backwards compatibility
'pkgs_dirs': dict(pkgs_dirs),
'files': pkgs_dirs[first], # Backwards compatibility
'total_size': totalsize,
'warnings': warnings,
'pkg_sizes': dict(zip(rmlist, pkgsizes))
'pkg_sizes': {i: dict(zip(pkgs_dirs[i], pkgsizes[i])) for i in pkgs_dirs},
}
rm_pkgs(args, pkgs_dir, rmlist, warnings, totalsize, pkgsizes,
rm_pkgs(args, pkgs_dirs, warnings, totalsize, pkgsizes,
verbose=not args.json)

if args.source_cache:
Expand Down

0 comments on commit 716db30

Please sign in to comment.