mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 01:35:35 +00:00
Bug 1445944 - [mozprofile] Pull functionality out of Profile and into an abstract 'BaseProfile' class r=rwood
In addition to Profile, this will be implemented by the ChromeProfile class in the next commit. This way we can test for 'isinstance(profile, BaseProfile)' when we just want to test for a profile regardless of application. Ideally I would have preferred 'Profile' itself to be the base class (and co-opt FirefoxProfile to be the new defacto class for firefox profiles), but this would break backwards compatibility. MozReview-Commit-ID: 6TTFq2PQOGM --HG-- extra : rebase_source : 57651887061ec52b176729109271ee2e23552cdb
This commit is contained in:
parent
198dd77c3a
commit
e29aebf0d9
@ -6,23 +6,103 @@ from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import platform
|
||||
import time
|
||||
import tempfile
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from .addons import AddonManager
|
||||
import mozfile
|
||||
from .permissions import Permissions
|
||||
from .prefs import Preferences
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from shutil import copytree
|
||||
|
||||
__all__ = ['Profile',
|
||||
import mozfile
|
||||
|
||||
from .addons import AddonManager
|
||||
from .permissions import Permissions
|
||||
from .prefs import Preferences
|
||||
|
||||
__all__ = ['BaseProfile',
|
||||
'Profile',
|
||||
'FirefoxProfile',
|
||||
'ThunderbirdProfile',
|
||||
'create_profile']
|
||||
|
||||
|
||||
class Profile(object):
|
||||
class BaseProfile(object):
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
def __init__(self, profile=None, addons=None, preferences=None, restore=True):
|
||||
self._addons = addons
|
||||
|
||||
# Prepare additional preferences
|
||||
if preferences:
|
||||
if isinstance(preferences, dict):
|
||||
# unordered
|
||||
preferences = preferences.items()
|
||||
|
||||
# sanity check
|
||||
assert not [i for i in preferences if len(i) != 2]
|
||||
else:
|
||||
preferences = []
|
||||
self._preferences = preferences
|
||||
|
||||
# Handle profile creation
|
||||
self.restore = restore
|
||||
self.create_new = not profile
|
||||
if profile:
|
||||
# Ensure we have a full path to the profile
|
||||
self.profile = os.path.abspath(os.path.expanduser(profile))
|
||||
else:
|
||||
self.profile = tempfile.mkdtemp(suffix='.mozrunner')
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.cleanup()
|
||||
|
||||
def __del__(self):
|
||||
self.cleanup()
|
||||
|
||||
def cleanup(self):
|
||||
"""Cleanup operations for the profile."""
|
||||
|
||||
if self.restore:
|
||||
# If it's a temporary profile we have to remove it
|
||||
if self.create_new:
|
||||
mozfile.remove(self.profile)
|
||||
|
||||
@abstractmethod
|
||||
def _reset(self):
|
||||
pass
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
reset the profile to the beginning state
|
||||
"""
|
||||
self.cleanup()
|
||||
self._reset()
|
||||
|
||||
@classmethod
|
||||
def clone(cls, path_from, path_to=None, ignore=None, **kwargs):
|
||||
"""Instantiate a temporary profile via cloning
|
||||
- path: path of the basis to clone
|
||||
- ignore: callable passed to shutil.copytree
|
||||
- kwargs: arguments to the profile constructor
|
||||
"""
|
||||
if not path_to:
|
||||
tempdir = tempfile.mkdtemp() # need an unused temp dir name
|
||||
mozfile.remove(tempdir) # copytree requires that dest does not exist
|
||||
path_to = tempdir
|
||||
copytree(path_from, path_to, ignore=ignore)
|
||||
|
||||
c = cls(path_to, **kwargs)
|
||||
c.create_new = True # deletes a cloned profile when restore is True
|
||||
return c
|
||||
|
||||
def exists(self):
|
||||
"""returns whether the profile exists or not"""
|
||||
return os.path.exists(self.profile)
|
||||
|
||||
|
||||
class Profile(BaseProfile):
|
||||
"""Handles all operations regarding profile.
|
||||
|
||||
Creating new profiles, installing add-ons, setting preferences and
|
||||
@ -58,37 +138,17 @@ class Profile(object):
|
||||
:param whitelistpaths: List of paths to pass to Firefox to allow read
|
||||
access to from the content process sandbox.
|
||||
"""
|
||||
self._addons = addons
|
||||
super(Profile, self).__init__(
|
||||
profile=profile, addons=addons, preferences=preferences, restore=restore)
|
||||
|
||||
self._locations = locations
|
||||
self._proxy = proxy
|
||||
|
||||
# Prepare additional preferences
|
||||
if preferences:
|
||||
if isinstance(preferences, dict):
|
||||
# unordered
|
||||
preferences = preferences.items()
|
||||
|
||||
# sanity check
|
||||
assert not [i for i in preferences if len(i) != 2]
|
||||
else:
|
||||
preferences = []
|
||||
self._preferences = preferences
|
||||
self._whitelistpaths = whitelistpaths
|
||||
|
||||
# Handle profile creation
|
||||
self.create_new = not profile
|
||||
if profile:
|
||||
# Ensure we have a full path to the profile
|
||||
self.profile = os.path.abspath(os.path.expanduser(profile))
|
||||
else:
|
||||
self.profile = tempfile.mkdtemp(suffix='.mozrunner')
|
||||
|
||||
self.restore = restore
|
||||
|
||||
# Initialize all class members
|
||||
self._internal_init()
|
||||
self._reset()
|
||||
|
||||
def _internal_init(self):
|
||||
def _reset(self):
|
||||
"""Internal: Initialize all class members to their default value"""
|
||||
|
||||
if not os.path.exists(self.profile):
|
||||
@ -136,17 +196,6 @@ class Profile(object):
|
||||
self.addons = AddonManager(self.profile, restore=self.restore)
|
||||
self.addons.install(self._addons)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.cleanup()
|
||||
|
||||
def __del__(self):
|
||||
self.cleanup()
|
||||
|
||||
# cleanup
|
||||
|
||||
def cleanup(self):
|
||||
"""Cleanup operations for the profile."""
|
||||
|
||||
@ -158,18 +207,7 @@ class Profile(object):
|
||||
self.addons.clean()
|
||||
if getattr(self, 'permissions', None) is not None:
|
||||
self.permissions.clean_db()
|
||||
|
||||
# If it's a temporary profile we have to remove it
|
||||
if self.create_new:
|
||||
mozfile.remove(self.profile)
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
reset the profile to the beginning state
|
||||
"""
|
||||
self.cleanup()
|
||||
|
||||
self._internal_init()
|
||||
super(Profile, self).cleanup()
|
||||
|
||||
def clean_preferences(self):
|
||||
"""Removed preferences added by mozrunner."""
|
||||
@ -181,27 +219,6 @@ class Profile(object):
|
||||
if not self.pop_preferences(filename):
|
||||
break
|
||||
|
||||
@classmethod
|
||||
def clone(cls, path_from, path_to=None, ignore=None, **kwargs):
|
||||
"""Instantiate a temporary profile via cloning
|
||||
- path: path of the basis to clone
|
||||
- ignore: callable passed to shutil.copytree
|
||||
- kwargs: arguments to the profile constructor
|
||||
"""
|
||||
if not path_to:
|
||||
tempdir = tempfile.mkdtemp() # need an unused temp dir name
|
||||
mozfile.remove(tempdir) # copytree requires that dest does not exist
|
||||
path_to = tempdir
|
||||
copytree(path_from, path_to, ignore=ignore)
|
||||
|
||||
c = cls(path_to, **kwargs)
|
||||
c.create_new = True # deletes a cloned profile when restore is True
|
||||
return c
|
||||
|
||||
def exists(self):
|
||||
"""returns whether the profile exists or not"""
|
||||
return os.path.exists(self.profile)
|
||||
|
||||
# methods for preferences
|
||||
|
||||
def set_preferences(self, preferences, filename='user.js'):
|
||||
|
@ -12,6 +12,7 @@ import mozunit
|
||||
import pytest
|
||||
|
||||
from mozprofile import (
|
||||
BaseProfile,
|
||||
Profile,
|
||||
FirefoxProfile,
|
||||
ThunderbirdProfile,
|
||||
@ -51,7 +52,7 @@ def test_create_profile(tmpdir, app, cls):
|
||||
return
|
||||
|
||||
profile = create_profile(app, profile=path)
|
||||
assert isinstance(profile, Profile)
|
||||
assert isinstance(profile, BaseProfile)
|
||||
assert profile.__class__ == cls
|
||||
assert profile.profile == path
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user