Sfoglia il codice sorgente

logger → _logger

tags/v1.0
JustAnotherArchivist 1 anno fa
parent
commit
ed69ba16c9
3 ha cambiato i file con 33 aggiunte e 34 eliminazioni
  1. +4
    -5
      codearchiver/cli.py
  2. +19
    -19
      codearchiver/core.py
  3. +10
    -10
      codearchiver/modules/git.py

+ 4
- 5
codearchiver/cli.py Vedi File

@@ -15,7 +15,7 @@ import tempfile


## Logging ## Logging
dumpLocals = False dumpLocals = False
logger = logging # Replaced below after setting the logger class
_logger = logging # Replaced below after setting the logger class




class Logger(logging.Logger): class Logger(logging.Logger):
@@ -96,7 +96,7 @@ def _dump_locals_on_exception():
trace = inspect.trace() trace = inspect.trace()
if len(trace) >= 2: if len(trace) >= 2:
name = _dump_stack_and_locals(trace[1:], exc = e) name = _dump_stack_and_locals(trace[1:], exc = e)
logger.fatal(f'Dumped stack and locals to {name}')
_logger.fatal(f'Dumped stack and locals to {name}')
raise raise




@@ -150,8 +150,8 @@ def parse_args():


def setup_logging(): def setup_logging():
logging.setLoggerClass(Logger) logging.setLoggerClass(Logger)
global logger
logger = logging.getLogger(__name__)
global _logger
_logger = logging.getLogger(__name__)




def configure_logging(verbosity, dumpLocals_): def configure_logging(verbosity, dumpLocals_):
@@ -184,7 +184,6 @@ def main():
setup_logging() setup_logging()
args = parse_args() args = parse_args()
configure_logging(args.verbosity, args.dumpLocals) configure_logging(args.verbosity, args.dumpLocals)
_logger = logging.getLogger(__name__)


import codearchiver.core import codearchiver.core
import codearchiver.modules import codearchiver.modules


+ 19
- 19
codearchiver/core.py Vedi File

@@ -14,7 +14,7 @@ import typing
import weakref import weakref




logger = logging.getLogger(__name__)
_logger = logging.getLogger(__name__)




class InputURL: class InputURL:
@@ -176,10 +176,10 @@ class HttpClient:
for attempt in range(self._retries + 1): for attempt in range(self._retries + 1):
# The request is newly prepared on each retry because of potential cookie updates. # The request is newly prepared on each retry because of potential cookie updates.
req = self._session.prepare_request(requests.Request(method, url, params = params, data = data, headers = headers)) req = self._session.prepare_request(requests.Request(method, url, params = params, data = data, headers = headers))
logger.info(f'Retrieving {req.url}')
logger.debug(f'... with headers: {headers!r}')
_logger.info(f'Retrieving {req.url}')
_logger.debug(f'... with headers: {headers!r}')
if data: if data:
logger.debug(f'... with data: {data!r}')
_logger.debug(f'... with data: {data!r}')
try: try:
r = self._session.send(req, timeout = timeout) r = self._session.send(req, timeout = timeout)
except requests.exceptions.RequestException as exc: except requests.exceptions.RequestException as exc:
@@ -189,7 +189,7 @@ class HttpClient:
else: else:
retrying = '' retrying = ''
level = logging.ERROR level = logging.ERROR
logger.log(level, f'Error retrieving {req.url}: {exc!r}{retrying}')
_logger.log(level, f'Error retrieving {req.url}: {exc!r}{retrying}')
else: else:
if responseOkCallback is not None: if responseOkCallback is not None:
success, msg = responseOkCallback(r) success, msg = responseOkCallback(r)
@@ -198,7 +198,7 @@ class HttpClient:
msg = f': {msg}' if msg else '' msg = f': {msg}' if msg else ''


if success: if success:
logger.debug(f'{req.url} retrieved successfully{msg}')
_logger.debug(f'{req.url} retrieved successfully{msg}')
return r return r
else: else:
if attempt < self._retries: if attempt < self._retries:
@@ -207,14 +207,14 @@ class HttpClient:
else: else:
retrying = '' retrying = ''
level = logging.ERROR level = logging.ERROR
logger.log(level, f'Error retrieving {req.url}{msg}{retrying}')
_logger.log(level, f'Error retrieving {req.url}{msg}{retrying}')
if attempt < self._retries: if attempt < self._retries:
sleepTime = 1.0 * 2**attempt # exponential backoff: sleep 1 second after first attempt, 2 after second, 4 after third, etc. sleepTime = 1.0 * 2**attempt # exponential backoff: sleep 1 second after first attempt, 2 after second, 4 after third, etc.
logger.info(f'Waiting {sleepTime:.0f} seconds')
_logger.info(f'Waiting {sleepTime:.0f} seconds')
time.sleep(sleepTime) time.sleep(sleepTime)
else: else:
msg = f'{self._retries + 1} requests to {req.url} failed, giving up.' msg = f'{self._retries + 1} requests to {req.url} failed, giving up.'
logger.fatal(msg)
_logger.fatal(msg)
raise HttpError(msg) raise HttpError(msg)
raise RuntimeError('Reached unreachable code') raise RuntimeError('Reached unreachable code')


@@ -240,9 +240,9 @@ class ModuleMeta(type):
if class_.name in cls.__modulesByName: if class_.name in cls.__modulesByName:
raise RuntimeError(f'Class name collision: {class_.name!r} is already known') raise RuntimeError(f'Class name collision: {class_.name!r} is already known')
cls.__modulesByName[class_.name] = weakref.ref(class_) cls.__modulesByName[class_.name] = weakref.ref(class_)
logger.info(f'Found {class_.name!r} module {class_.__module__}.{class_.__name__}')
_logger.info(f'Found {class_.name!r} module {class_.__module__}.{class_.__name__}')
else: else:
logger.info(f'Found nameless module {class_.__module__}.{class_.__name__}')
_logger.info(f'Found nameless module {class_.__module__}.{class_.__name__}')
return class_ return class_


@classmethod @classmethod
@@ -252,7 +252,7 @@ class ModuleMeta(type):
if classRef := cls.__modulesByName.get(name): if classRef := cls.__modulesByName.get(name):
class_ = classRef() class_ = classRef()
if class_ is None: if class_ is None:
logger.info(f'Module {name!r} is gone, dropping')
_logger.info(f'Module {name!r} is gone, dropping')
del cls.__modulesByName[name] del cls.__modulesByName[name]
return class_ return class_


@@ -263,7 +263,7 @@ class ModuleMeta(type):
# Housekeeping first: remove dead modules # Housekeeping first: remove dead modules
for name in list(cls.__modulesByName): # create a copy of the names list so the dict can be modified in the loop for name in list(cls.__modulesByName): # create a copy of the names list so the dict can be modified in the loop
if cls.__modulesByName[name]() is None: if cls.__modulesByName[name]() is None:
logger.info(f'Module {name!r} is gone, dropping')
_logger.info(f'Module {name!r} is gone, dropping')
del cls.__modulesByName[name] del cls.__modulesByName[name]


for name, classRef in cls.__modulesByName.items(): for name, classRef in cls.__modulesByName.items():
@@ -284,11 +284,11 @@ class ModuleMeta(type):


if module.name is not None and module.name in cls.__modulesByName: if module.name is not None and module.name in cls.__modulesByName:
del cls.__modulesByName[module.name] del cls.__modulesByName[module.name]
logger.info(f'Module {module.name!r} dropped')
_logger.info(f'Module {module.name!r} dropped')


def __del__(self, *args, **kwargs): def __del__(self, *args, **kwargs):
if self.name is not None and self.name in type(self).__modulesByName: if self.name is not None and self.name in type(self).__modulesByName:
logger.info(f'Module {self.name!r} is being destroyed, dropping')
_logger.info(f'Module {self.name!r} is being destroyed, dropping')
del type(self).__modulesByName[self.name] del type(self).__modulesByName[self.name]
# type has no __del__ method, no need to call it. # type has no __del__ method, no need to call it.


@@ -328,7 +328,7 @@ def get_module_class(inputUrl: InputURL) -> typing.Type[Module]:
# Check if the URL references one of the modules directly # Check if the URL references one of the modules directly
if inputUrl.moduleScheme: if inputUrl.moduleScheme:
if module := ModuleMeta.get_module_by_name(inputUrl.moduleScheme): if module := ModuleMeta.get_module_by_name(inputUrl.moduleScheme):
logger.info(f'Selecting module {module.__module__}.{module.__name__}')
_logger.info(f'Selecting module {module.__module__}.{module.__name__}')
return module return module
else: else:
raise RuntimeError(f'No module with name {inputUrl.moduleScheme!r} exists') raise RuntimeError(f'No module with name {inputUrl.moduleScheme!r} exists')
@@ -336,11 +336,11 @@ def get_module_class(inputUrl: InputURL) -> typing.Type[Module]:
# Check if exactly one of the modules matches # Check if exactly one of the modules matches
matches = [class_ for class_ in ModuleMeta.iter_modules() if class_.matches(inputUrl)] matches = [class_ for class_ in ModuleMeta.iter_modules() if class_.matches(inputUrl)]
if len(matches) >= 2: if len(matches) >= 2:
logger.error('Multiple matching modules for input URL')
logger.debug(f'Matching modules: {matches!r}')
_logger.error('Multiple matching modules for input URL')
_logger.debug(f'Matching modules: {matches!r}')
raise RuntimeError('Multiple matching modules for input URL') raise RuntimeError('Multiple matching modules for input URL')
if matches: if matches:
logger.info(f'Selecting module {matches[0].__module__}.{matches[0].__name__}')
_logger.info(f'Selecting module {matches[0].__module__}.{matches[0].__name__}')
return matches[0] return matches[0]
raise RuntimeError('No matching modules for input URL') raise RuntimeError('No matching modules for input URL')




+ 10
- 10
codearchiver/modules/git.py Vedi File

@@ -8,7 +8,7 @@ import shutil
import subprocess import subprocess




logger = logging.getLogger(__name__)
_logger = logging.getLogger(__name__)




class GitIndex(codearchiver.core.Index): class GitIndex(codearchiver.core.Index):
@@ -33,38 +33,38 @@ class Git(codearchiver.core.Module):
def process(self): def process(self):
directory = self._url.rsplit('/', 1)[1] directory = self._url.rsplit('/', 1)[1]
if os.path.exists(directory): if os.path.exists(directory):
logger.fatal(f'{directory!r} already exists')
_logger.fatal(f'{directory!r} already exists')
raise FileExistsError(f'{directory!r} already exists') raise FileExistsError(f'{directory!r} already exists')
startTime = datetime.datetime.utcnow() startTime = datetime.datetime.utcnow()
if self._id is None: if self._id is None:
self._id = f'git_{self._url.replace("/", "_")}_{startTime:%Y%m%dT%H%M%SZ}' self._id = f'git_{self._url.replace("/", "_")}_{startTime:%Y%m%dT%H%M%SZ}'
bundle = f'{self._id}.bundle' bundle = f'{self._id}.bundle'
if os.path.exists(bundle): if os.path.exists(bundle):
logger.fatal(f'{bundle!r} already exists')
_logger.fatal(f'{bundle!r} already exists')
raise FileExistsError(f'{bundle!r} already exists') raise FileExistsError(f'{bundle!r} already exists')


logger.info(f'Cloning {self._url} into {directory}')
_logger.info(f'Cloning {self._url} into {directory}')
codearchiver.subprocess.run_with_log(['git', 'clone', '--verbose', '--progress', '--mirror', self._url, directory], env = {**os.environ, 'GIT_TERMINAL_PROMPT': '0'}) codearchiver.subprocess.run_with_log(['git', 'clone', '--verbose', '--progress', '--mirror', self._url, directory], env = {**os.environ, 'GIT_TERMINAL_PROMPT': '0'})


if self._extraBranches: if self._extraBranches:
for branch, commit in self._extraBranches.items(): for branch, commit in self._extraBranches.items():
logger.info(f'Fetching commit {commit} as {branch}')
_logger.info(f'Fetching commit {commit} as {branch}')
r = codearchiver.subprocess.run_with_log(['git', 'fetch', '--verbose', '--progress', 'origin', commit], cwd = directory, check = False) r = codearchiver.subprocess.run_with_log(['git', 'fetch', '--verbose', '--progress', 'origin', commit], cwd = directory, check = False)
if r.returncode == 0: if r.returncode == 0:
r2 = codearchiver.subprocess.run_with_log(['git', 'update-ref', f'refs/codearchiver/{branch}', commit, ''], cwd = directory, check = False) r2 = codearchiver.subprocess.run_with_log(['git', 'update-ref', f'refs/codearchiver/{branch}', commit, ''], cwd = directory, check = False)
if r2.returncode != 0: if r2.returncode != 0:
logger.error(f'Failed to update-ref refs/codearchiver/{branch} to {commit}')
_logger.error(f'Failed to update-ref refs/codearchiver/{branch} to {commit}')
else: else:
logger.error(f'Failed to fetch {commit}')
_logger.error(f'Failed to fetch {commit}')


logger.info(f'Bundling into {bundle}')
_logger.info(f'Bundling into {bundle}')
codearchiver.subprocess.run_with_log(['git', 'bundle', 'create', '--progress', f'../{bundle}', '--all'], cwd = directory) codearchiver.subprocess.run_with_log(['git', 'bundle', 'create', '--progress', f'../{bundle}', '--all'], cwd = directory)


logger.info(f'Collecting repository metadata for index')
_logger.info(f'Collecting repository metadata for index')
_, refs = codearchiver.subprocess.run_with_log(['git', 'show-ref'], cwd = directory) _, refs = codearchiver.subprocess.run_with_log(['git', 'show-ref'], cwd = directory)
_, commits = codearchiver.subprocess.run_with_log(['git', 'log', '--reflog', '--format=format:%H% P'], cwd = directory) _, commits = codearchiver.subprocess.run_with_log(['git', 'log', '--reflog', '--format=format:%H% P'], cwd = directory)


logger.info(f'Removing clone')
_logger.info(f'Removing clone')
shutil.rmtree(directory) shutil.rmtree(directory)


index = GitIndex() index = GitIndex()


Caricamento…
Annulla
Salva