def test_manifest_should_be_able_to_list_installed_plugins_along_with_their_metadata( ): offshoot.config["allow"]["files"] = False offshoot.config["allow"]["config"] = False offshoot.config["allow"]["libraries"] = False offshoot.config["allow"]["callbacks"] = False TestPlugin.install() manifest = offshoot.Manifest() plugins = manifest.list_plugins() assert "TestPlugin" in plugins assert plugins["TestPlugin"].get("name") == "TestPlugin" assert plugins["TestPlugin"].get("version") == "0.1.0" assert "files" in plugins["TestPlugin"] assert "config" in plugins["TestPlugin"] assert "libraries" in plugins["TestPlugin"] TestPlugin.uninstall() offshoot.config["allow"]["files"] = True offshoot.config["allow"]["config"] = True offshoot.config["allow"]["libraries"] = True offshoot.config["allow"]["callbacks"] = True
def test_manifest_should_create_manifest_file_if_it_does_not_exist_on_initialization( ): os.remove("offshoot.manifest.json") offshoot.Manifest() assert os.path.isfile("offshoot.manifest.json") with open("offshoot.manifest.json", "r") as f: assert "plugins" in json.loads(f.read())
def install_files(cls): print("\nOFFSHOOT PLUGIN INSTALL: Installing files...\n") is_success = True install_messages = list() installed_files = list() pluggable_classes = offshoot.pluggable_classes() try: for file_dict in cls.files: plugin_file_path = "%s/%s/files/%s".replace( "/", os.sep) % (offshoot.config["file_paths"]["plugins"], cls.name, file_dict["path"]) # Pluggable Validation if "pluggable" in file_dict: is_valid, messages = cls._validate_file_for_pluggable( plugin_file_path, file_dict["pluggable"]) if not is_valid: is_success = False list( map( lambda m: install_messages.append( "\n%s: %s" % (file_dict["path"], m)), messages)) continue installed_files.append(file_dict) # File Callback if "pluggable" in file_dict: pluggable_classes[file_dict["pluggable"]].on_file_install( **file_dict) if not is_success: raise PluginError("Offshoot Plugin File Install Errors: %s" % "".join(install_messages)) except PluginError as e: print("\nThere was a problem during installation... Reverting!") # Trigger File Uninstall Callback for file_dict in installed_files: if "pluggable" in file_dict: pluggable_classes[ file_dict["pluggable"]].on_file_uninstall(**file_dict) manifest = offshoot.Manifest() manifest.remove_plugin(cls.name) raise e
def uninstall(cls): if offshoot.config["allow"]["files"] is True: cls.uninstall_files() if offshoot.config["allow"]["config"] is True: cls.uninstall_configuration() if offshoot.config["allow"]["libraries"] is True: cls.uninstall_libraries() if offshoot.config["allow"]["callbacks"] is True: cls.on_uninstall() manifest = offshoot.Manifest() manifest.remove_plugin(cls.name)
def install(cls): if offshoot.config["allow"]["plugins"] is True: cls.verify_plugin_dependencies() if offshoot.config["allow"]["files"] is True: cls.install_files() if offshoot.config["allow"]["config"] is True: cls.install_configuration() if offshoot.config["allow"]["libraries"] is True: cls.install_libraries() if offshoot.config["allow"]["callbacks"] is True: cls.on_install() manifest = offshoot.Manifest() manifest.add_plugin(cls.name)
def test_manifest_should_be_able_to_add_a_plugin_and_its_metadata(): os.remove("offshoot.manifest.json") manifest = offshoot.Manifest() manifest.add_plugin("TestPlugin") plugins = manifest.list_plugins() assert "TestPlugin" in plugins assert plugins["TestPlugin"].get("name") == "TestPlugin" assert plugins["TestPlugin"].get("version") == "0.1.0" assert "files" in plugins["TestPlugin"] assert "config" in plugins["TestPlugin"] assert "libraries" in plugins["TestPlugin"]
def verify_plugin_dependencies(cls): print( "\nOFFSHOOT PLUGIN INSTALL: Verifying that plugin dependencies are installed...\n" ) manifest = offshoot.Manifest() missing_plugin_names = list() for plugin_name in cls.plugins: if not manifest.contains_plugin(plugin_name): missing_plugin_names.append(plugin_name) if len(missing_plugin_names): raise PluginError( "One or more plugin dependencies are not met: %s. Please install them before continuing..." % ", ".join(missing_plugin_names))
def test_manifest_should_be_able_to_determine_if_a_specific_plugin_is_installed( ): offshoot.config["allow"]["files"] = False offshoot.config["allow"]["config"] = False offshoot.config["allow"]["libraries"] = False offshoot.config["allow"]["callbacks"] = False TestPlugin.install() manifest = offshoot.Manifest() assert manifest.contains_plugin("TestPlugin") TestPlugin.uninstall() offshoot.config["allow"]["files"] = True offshoot.config["allow"]["config"] = True offshoot.config["allow"]["libraries"] = True offshoot.config["allow"]["callbacks"] = True
def plugins(): plugin_names = set() for root, directories, files in os.walk(offshoot.config['file_paths']['plugins']): if root != offshoot.config['file_paths']['plugins']: break for directory in directories: plugin_names.add(directory) manifest_plugin_names = set() for plugin_name in offshoot.Manifest().list_plugins().keys(): manifest_plugin_names.add(plugin_name) active_plugins = plugin_names & manifest_plugin_names inactive_plugins = plugin_names - manifest_plugin_names print("\nACTIVE Plugins:\n") print("\n".join(active_plugins or ["No active plugins..."])) print("\nINACTIVE Plugins:\n") print("\n".join(inactive_plugins or ["No inactive plugins..."]))
def test_manifest_should_be_able_to_return_all_file_names_containing_a_specific_pluggable( ): offshoot.config["allow"]["files"] = False offshoot.config["allow"]["config"] = False offshoot.config["allow"]["libraries"] = False offshoot.config["allow"]["callbacks"] = False TestPlugin.install() manifest = offshoot.Manifest() plugin_files = manifest.plugin_files_for_pluggable("TestPluggable") assert len(plugin_files) == 1 assert plugin_files[0][ 0] == "plugins/TestPlugin/files/test_plugin_pluggable_expected.py" assert plugin_files[0][1] == "TestPluggable" TestPlugin.uninstall() offshoot.config["allow"]["files"] = True offshoot.config["allow"]["config"] = True offshoot.config["allow"]["libraries"] = True offshoot.config["allow"]["callbacks"] = True
def test_base_should_be_able_to_determine_if_a_file_implements_a_specified_pluggable( ): offshoot.config["allow"]["config"] = False offshoot.config["allow"]["libraries"] = False offshoot.config["allow"]["callbacks"] = False offshoot.config["modules"].append("pluggable") TestPlugin.install() manifest = offshoot.Manifest() files = manifest.plugin_files_for_pluggable("TestPluggable") valid, plugin_class = offshoot.file_contains_pluggable( files[0][0], "TestPluggable") assert valid is True assert plugin_class == "TestPluginPluggableExpected" valid, plugin_class = offshoot.file_contains_pluggable( "INVALID.txt", "TestPluggable") assert valid is False assert plugin_class is None valid, plugin_class = offshoot.file_contains_pluggable( files[0][0], "InvalidPluggable") assert valid is False assert plugin_class is None TestPlugin.uninstall() offshoot.config["allow"]["config"] = True offshoot.config["allow"]["libraries"] = True offshoot.config["allow"]["callbacks"] = True