Example #1
0
def _package_plugins(ctx):
    """
    This functions can be just called when the generate_project_files and compile tasks have been already invoked
    """
    print("\n\n-- Creating Zip Files \n")

    project_dir = Path(__file__).parent
    plugins_projects = [x for x in (project_dir / "build/build_directory_for_tests/").iterdir() if x.is_dir()]
    artifacts_dir = project_dir / 'build/artifacts'

    plugins_zip = project_dir / 'build/plugin_zip'
    if plugins_zip.exists():
        shutil.rmtree(plugins_zip)

    plugins_zip.mkdir()

    for project in plugins_projects:
        plugins_dirs = [x for x in (project / 'plugin').iterdir() if x.is_dir() and (x / 'assets').exists()]
        hm_generator = HookManGenerator(hook_spec_file_path=project_dir / f"tests/plugins/{project.name}/hook_specs.py")

        for plugin in plugins_dirs:
            (plugin / 'artifacts').mkdir()
            if sys.platform == 'win32':
                shutil.copy2(src=artifacts_dir / f'{plugin.name}.dll', dst=plugin / 'artifacts')
            else:
                shutil.copy2(src=artifacts_dir / f'lib{plugin.name}.so', dst=plugin / 'artifacts')

            hm_generator.generate_plugin_package(
                package_name=plugin.name,
                plugin_dir=plugin,
                dst_path=plugins_zip
            )
Example #2
0
def package_plugin(specs_path: str, package_name: str, plugin_dir: str,
                   dst_path: Path):
    """Packages a plugin for distribution."""
    hm_generator = HookManGenerator(hook_spec_file_path=specs_path)
    hm_generator.generate_plugin_package(package_name=package_name,
                                         plugin_dir=plugin_dir,
                                         dst_path=Path(dst_path))
    return 0
Example #3
0
def test_generate_plugin_package_invalid_version(acme_hook_specs_file, tmp_path, mocker, mock_plugin_id_from_dll):
    hg = HookManGenerator(hook_spec_file_path=acme_hook_specs_file)
    plugin_id = 'acme'
    hg.generate_plugin_template(plugin_id, plugin_id, 'acme1', 'acme2', tmp_path)

    plugin_yaml = tmp_path / 'acme/assets/plugin.yaml'
    new_content = plugin_yaml.read_text().replace("version: '1.0.0'", "version: '1'")
    plugin_yaml.write_text(new_content)

    mocker.patch('hookman.hookman_generator.HookManGenerator._validate_package_folder', return_value=None)

    with pytest.raises(ValueError, match="Version attribute does not follow semantic version, got '1'"):
        hg.generate_plugin_package(plugin_id, plugin_dir=tmp_path / plugin_id)
Example #4
0
def package_plugin(specs_path: str, package_name: str, plugin_dir: str,
                   dst_path: Path):
    """
    Creates a PACKAGE_NAME for distribution on the current directory from the given PLUGIN_DIR for the project.

    If --dst-path is not provide, the PACKAGE_NAME will be created inside the PLUGIN_DIR folder.

    SPECS_PATH    Path to where the hook_specs.py file is located.
    PACKAGE_NAME  The name of the generated package
    PLUGIN_DIR    Path to the plugin directory, where configuration and the shared library is located.
    """
    hm_generator = HookManGenerator(hook_spec_file_path=specs_path)
    hm_generator.generate_plugin_package(package_name=package_name,
                                         plugin_dir=plugin_dir,
                                         dst_path=Path(dst_path))
    return 0
Example #5
0
def test_generate_plugin_package(acme_hook_specs_file, tmpdir, mock_plugin_id_from_dll):
    hg = HookManGenerator(hook_spec_file_path=acme_hook_specs_file)
    plugin_id = 'acme'
    hg.generate_plugin_template(
        caption='acme',
        plugin_id='acme',
        author_email='acme1',
        author_name='acme2',
        dst_path=Path(tmpdir)
    )
    plugin_dir = Path(tmpdir) / 'acme'

    artifacts_dir = plugin_dir / 'artifacts'
    artifacts_dir.mkdir()
    import sys

    shared_lib_name = f"{plugin_id}.dll" if sys.platform == 'win32' else f"lib{plugin_id}.so"
    shared_lib_path = artifacts_dir / shared_lib_name
    shared_lib_path.write_text('')

    hg.generate_plugin_package(
        package_name='acme',
        plugin_dir=plugin_dir,
    )

    from hookman.plugin_config import PluginInfo
    version = PluginInfo(Path(tmpdir / 'acme/assets/plugin.yaml'), None).version

    win_plugin_name = f"{plugin_id}-{version}-win64.hmplugin"
    linux_plugin_name = f"{plugin_id}-{version}-linux64.hmplugin"
    hm_plugin_name = win_plugin_name if sys.platform == 'win32' else linux_plugin_name

    compressed_plugin = plugin_dir / hm_plugin_name
    assert compressed_plugin.exists()

    from zipfile import ZipFile
    plugin_file_zip = ZipFile(compressed_plugin)
    list_of_files = [file.filename for file in plugin_file_zip.filelist]

    assert 'assets/plugin.yaml' in list_of_files
    assert 'assets/README.md' in list_of_files
    assert f'artifacts/{shared_lib_name}' in list_of_files
Example #6
0
def test_generate_plugin_package(acme_hook_specs_file, tmpdir):
    hg = HookManGenerator(hook_spec_file_path=acme_hook_specs_file)

    hg.generate_plugin_template(plugin_name='acme',
                                shared_lib_name='acme',
                                author_email='acme1',
                                author_name='acme2',
                                dst_path=Path(tmpdir))
    plugin_dir = Path(tmpdir) / 'acme'

    artifacts_dir = plugin_dir / 'artifacts'
    artifacts_dir.mkdir()
    import sys

    if sys.platform == 'win32':
        shared_lib_name = 'acme.dll'
        hm_plugin_name = 'acme-win64.hmplugin'
    else:
        shared_lib_name = 'libacme.so'
        hm_plugin_name = 'acme-linux64.hmplugin'

    test_dll = artifacts_dir / shared_lib_name
    test_dll.write_text('')

    hg.generate_plugin_package(
        package_name='acme',
        plugin_dir=plugin_dir,
    )

    compressed_plugin = plugin_dir / hm_plugin_name
    assert compressed_plugin.exists()

    from zipfile import ZipFile
    plugin_file_zip = ZipFile(compressed_plugin)
    list_of_files = [file.filename for file in plugin_file_zip.filelist]

    assert 'assets/plugin.yaml' in list_of_files
    assert 'assets/README.md' in list_of_files
    assert f'artifacts/{shared_lib_name}' in list_of_files
Example #7
0
def package_only(ctx, plugin_dir, package_name, dst):
    """
    Generate a ``<package_name>.hmplugin`` file with all the content from the directory assets and artifacts.

    By default, the package will be created inside the folder plugin_dir, however, it's possible
    to give another path filling the dst argument.
    """
    plugin_dir = Path(plugin_dir)
    dst = Path(dst)
    hook_specs_file_path = _get_hook_specs_file_path()
    hm = HookManGenerator(hook_spec_file_path=hook_specs_file_path)
    from alfasim_sdk._internal.constants import EXTRAS_REQUIRED_VERSION_KEY
    from alfasim_sdk._internal.alfasim_sdk_utils import (
        get_extras_default_required_version, )

    extras_defaults = {
        EXTRAS_REQUIRED_VERSION_KEY: get_extras_default_required_version()
    }
    hm.generate_plugin_package(package_name,
                               plugin_dir,
                               dst,
                               extras_defaults=extras_defaults)
Example #8
0
def test_generate_plugin_package_with_missing_folders(acme_hook_specs_file, tmpdir, mocker):
    import sys
    from textwrap import dedent
    from hookman.exceptions import AssetsDirNotFoundError, ArtifactsDirNotFoundError, SharedLibraryNotFoundError
    hg = HookManGenerator(hook_spec_file_path=acme_hook_specs_file)
    plugin_dir = Path(tmpdir) / 'acme'
    plugin_dir.mkdir()

    # -- Without Assets Folder
    with pytest.raises(AssetsDirNotFoundError):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    asset_dir = plugin_dir / 'assets'
    asset_dir.mkdir()

    # -- Without Artifacts Folder
    with pytest.raises(ArtifactsDirNotFoundError, match=r'Artifacts directory not found: .*[\\/]acme[\\/]artifacts'):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    artifacts_dir = plugin_dir / 'artifacts'
    artifacts_dir.mkdir()

    # -- Without a shared library binary
    shared_lib_extension = '*.dll' if sys.platform == 'win32' else '*.so'
    string_to_match = fr'Unable to locate a shared library ({shared_lib_extension}) in'
    import re
    with pytest.raises(FileNotFoundError, match=re.escape(string_to_match)):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    lib_name = 'test.dll' if sys.platform == 'win32' else 'libtest.so'
    shared_library_file = artifacts_dir / lib_name
    shared_library_file.write_text('')

    # -- Without Config file
    with pytest.raises(FileNotFoundError, match=f'Unable to locate the file plugin.yaml in'):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    config_file = asset_dir / 'plugin.yaml'
    config_file.write_text(dedent(f"""\
            caption: 'ACME'
            version: '1.0.0'

            author: 'acme_author'
            email: 'acme_email'

            id: 'acme'
        """))
    # -- Without Readme file
    with pytest.raises(FileNotFoundError, match=f'Unable to locate the file README.md in'):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    readme_file = asset_dir / 'README.md'
    readme_file.write_text('')

    # # -- With a invalid shared_library name on config_file
    acme_lib_name = 'acme.dll' if sys.platform == 'win32' else 'libacme.so'
    hm_plugin_name = 'acme-1.0.0-win64.hmplugin' if sys.platform == 'win32' else 'acme-1.0.0-linux64.hmplugin'

    with pytest.raises(SharedLibraryNotFoundError, match=f'{acme_lib_name} could not be found in *'):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    acme_shared_library_file = artifacts_dir / acme_lib_name
    acme_shared_library_file.write_text('')

    # The mock bellow is to avoid to have get a valid dll on this test
    from hookman.plugin_config import PluginInfo
    mocker.patch.object(PluginInfo, '_get_plugin_id_from_dll', return_value='')

    hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)
    compressed_plugin_package = plugin_dir / hm_plugin_name
    assert compressed_plugin_package.exists()
Example #9
0
def test_generate_plugin_package_with_missing_folders(acme_hook_specs_file,
                                                      tmpdir):
    import sys
    from textwrap import dedent
    from hookman.exceptions import AssetsDirNotFoundError, ArtifactsDirNotFoundError, SharedLibraryNotFoundError
    hg = HookManGenerator(hook_spec_file_path=acme_hook_specs_file)
    plugin_dir = Path(tmpdir) / 'acme'
    plugin_dir.mkdir()

    # -- Without Assets Folder
    with pytest.raises(AssetsDirNotFoundError):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    asset_dir = plugin_dir / 'assets'
    asset_dir.mkdir()

    # -- Without Artifacts Folder
    with pytest.raises(
            ArtifactsDirNotFoundError,
            match=r'Artifacts directory not found: .*[\\/]acme[\\/]artifacts'):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    artifacts_dir = plugin_dir / 'artifacts'
    artifacts_dir.mkdir()

    # -- Without a shared library binary
    shared_lib = '*.dll' if sys.platform == 'win32' else '*.so'
    string_to_match = fr'Unable to locate a shared library \(\{shared_lib}\) in'
    with pytest.raises(FileNotFoundError, match=string_to_match):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    lib_name = 'test.dll' if sys.platform == 'win32' else 'libtest.so'
    shared_library_file = artifacts_dir / lib_name
    shared_library_file.write_text('')

    # -- Without Config file
    with pytest.raises(FileNotFoundError,
                       match=f'Unable to locate the file plugin.yaml in'):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    config_file = asset_dir / 'plugin.yaml'
    config_file.write_text(
        dedent(f"""\
            plugin_name: 'ACME'
            plugin_version: '1'

            author: 'acme_author'
            email: 'acme_email'

            shared_lib: 'acme'
        """))
    # -- Without Readme file
    with pytest.raises(FileNotFoundError,
                       match=f'Unable to locate the file README.md in'):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    readme_file = asset_dir / 'README.md'
    readme_file.write_text('')

    # # -- With a invalid shared_library name on config_file
    if sys.platform == 'win32':
        acme_lib_name = 'acme.dll'
        hm_plugin_name = 'acme-win64.hmplugin'
    else:
        acme_lib_name = 'libacme.so'
        hm_plugin_name = 'acme-linux64.hmplugin'

    with pytest.raises(SharedLibraryNotFoundError,
                       match=f'{acme_lib_name} could not be found'):
        hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)

    acme_shared_library_file = artifacts_dir / acme_lib_name
    acme_shared_library_file.write_text('')

    hg.generate_plugin_package(package_name='acme', plugin_dir=plugin_dir)
    compressed_plugin_package = plugin_dir / hm_plugin_name
    assert compressed_plugin_package.exists()
Example #10
0
def test_generate_plugin_package(acme_hook_specs_file, tmpdir, mock_plugin_id_from_dll):
    hg = HookManGenerator(hook_spec_file_path=acme_hook_specs_file)
    plugin_id = "acme"
    hg.generate_plugin_template(
        caption="acme",
        plugin_id="acme",
        author_email="acme1",
        author_name="acme2",
        dst_path=Path(tmpdir),
        extras={"key": "override", "key2": "value2"},
    )
    plugin_dir = Path(tmpdir) / "acme"

    artifacts_dir = plugin_dir / "artifacts"
    artifacts_dir.mkdir()
    import sys

    shared_lib_name = f"{plugin_id}.dll" if sys.platform == "win32" else f"lib{plugin_id}.so"
    shared_lib_path = artifacts_dir / shared_lib_name
    shared_lib_path.write_text("")

    hg.generate_plugin_package(
        package_name="acme",
        plugin_dir=plugin_dir,
        extras_defaults={"key": "default", "key3": "default"},
    )

    from hookman.plugin_config import PluginInfo

    version = PluginInfo(Path(tmpdir / "acme/assets/plugin.yaml"), None).version

    win_plugin_name = f"{plugin_id}-{version}-win64.hmplugin"
    linux_plugin_name = f"{plugin_id}-{version}-linux64.hmplugin"
    hm_plugin_name = win_plugin_name if sys.platform == "win32" else linux_plugin_name

    compressed_plugin = plugin_dir / hm_plugin_name
    assert compressed_plugin.exists()

    from zipfile import ZipFile

    plugin_file_zip = ZipFile(compressed_plugin)
    list_of_files = [file.filename for file in plugin_file_zip.filelist]

    assert "assets/plugin.yaml" in list_of_files
    assert "assets/README.md" in list_of_files
    assert f"artifacts/{shared_lib_name}" in list_of_files

    with plugin_file_zip.open("assets/plugin.yaml", "r") as f:
        contents = f.read().decode("utf-8")

    from textwrap import dedent

    assert contents == dedent(
        """\
    author: acme2
    caption: acme
    email: acme1
    id: acme
    version: 1.0.0
    extras:
      key: override
      key2: value2
      key3: default
    """
    )