(ctx, integration, to_version)
Helper tool to ease the migration of a manifest to a newer version, auto-filling fields when possible

    Inputs:

    integration: The name of the integration folder to perform the migration on

    to_version: The schema version to upgrade the manifest to
Helper tool to ease the migration of a manifest to a newer version, auto-filling fields when possible
Helper tool to ease the migration of a manifest to a newer version auto - filling fields when possible
def migrate(ctx, integration, to_version):
    """
    Helper tool to ease the migration of a manifest to a newer version, auto-filling fields when possible

    Inputs:

    integration: The name of the integration folder to perform the migration on

    to_version: The schema version to upgrade the manifest to
    """
    echo_info(f"Migrating {integration} manifest to {to_version}....", nl=True)

    # Perform input validations
    if integration and integration not in get_valid_integrations():
        abort(f'    Unknown integration `{integration}`, is your repo set properly in `ddev config`?')

    loaded_manifest = JSONDict(load_manifest(integration))
    manifest_version = loaded_manifest.get_path("/manifest_version")

    if to_version not in SUPPORTED_MANIFEST_VERSIONS:
        abort(f"    Unknown to_version: `{to_version}`. Valid options are: {SUPPORTED_MANIFEST_VERSIONS}")
    if to_version == manifest_version:
        abort(f"    {integration} is already on version `{manifest_version}`")
    if to_version not in SUPPORTED_VERSION_UPGRADE_PATHS.get(manifest_version, []):
        abort(
            f"    Can't migrate from version `{manifest_version}` to version: `{to_version}`. Unsupported upgrade path"
        )

    migrated_manifest = JSONDict()

    # Explicitly set the manifest_version first so it appears at the top of the manifest
    migrated_manifest.set_path("/manifest_version", "2.0.0")

    # Generate and introduce a uuid
    app_uuid = str(uuid.uuid4())
    migrated_manifest.set_path("/app_uuid", app_uuid)

    for key, val in V2_TO_V1_MAP.items():
        if val == SKIP_IF_FOUND:
            continue
        # If the value is a string and is a JSONPath, then load the value from the JSON Path
        elif isinstance(val, str) and val.startswith("/"):
            final_value = loaded_manifest.get_path(val)
        else:
            final_value = val

        # We need to remove any of the underlying "assets" that are just an empty dictionary
        if key in ["/assets/dashboards", "/assets/monitors", "/assets/saved_views"] and not final_value:
            continue

        if final_value is not None:
            migrated_manifest.set_path(key, final_value)

    # Update any previously skipped field in which we can use logic to assume the value of
    # Also iterate through any lists to include new/updated fields at each index of the list
    migrated_manifest.set_path("/classifier_tags", TODO_FILL_IN)

    # Retrieve and map all categories from other fields
    classifier_tags = []
    supported_os = loaded_manifest.get_path("/supported_os")
    for os in supported_os:
        os_tag = OS_TO_CLASSIFIER_TAGS.get(os.lower())
        if os_tag:
            classifier_tags.append(os_tag)

    categories = loaded_manifest.get_path("/categories")
    for category in categories:
        category_tag = CATEGORIES_TO_CLASSIFIER_TAGS.get(category.lower())
        if category_tag:
            classifier_tags.append(category_tag)

    # Write the manifest back to disk
    migrated_manifest.set_path("/classifier_tags", classifier_tags)

    # Marketplace-only fields:
    if ctx.obj['repo_name'] == "marketplace":
        migrated_manifest.set_path("/author/vendor_id", TODO_FILL_IN)
        migrated_manifest.set_path("/author/sales_email", loaded_manifest.get_path("/terms/legal_email"))

        migrated_manifest.set_path("/pricing", loaded_manifest.get_path("/pricing"))
        migrated_manifest.set_path("/legal_terms", {})
        migrated_manifest.set_path("/legal_terms/eula", loaded_manifest.get_path("/terms/eula"))

        for idx, _ in enumerate(migrated_manifest.get_path("/pricing") or []):
            migrated_manifest.set_path(f"/pricing/{idx}/product_id", TODO_FILL_IN)
            migrated_manifest.set_path(f"/pricing/{idx}/short_description", TODO_FILL_IN)
            migrated_manifest.set_path(f"/pricing/{idx}/includes_assets", True)

    write_file(get_manifest_file(integration), json.dumps(migrated_manifest, indent=2))

    echo_success(
        f"Successfully migrated {integration} manifest to version {to_version}. Please update any needed fields, "
        f"especially those that are marked with `{TODO_FILL_IN}`"
    )
def migrate ( ctx , integration , to_version ) : echo_info ( f"Migrating {integration} manifest to {to_version}...." , nl = True ) # Perform input validations if integration and integration not in get_valid_integrations ( ) : abort ( f'    Unknown integration `{integration}`, is your repo set properly in `ddev config`?' ) loaded_manifest = JSONDict ( load_manifest ( integration ) ) manifest_version = loaded_manifest . get_path ( "/manifest_version" ) if to_version not in SUPPORTED_MANIFEST_VERSIONS : abort ( f"    Unknown to_version: `{to_version}`. Valid options are: {SUPPORTED_MANIFEST_VERSIONS}" ) if to_version == manifest_version : abort ( f"    {integration} is already on version `{manifest_version}`" ) if to_version not in SUPPORTED_VERSION_UPGRADE_PATHS . get ( manifest_version , [ ] ) : abort ( f"    Can't migrate from version `{manifest_version}` to version: `{to_version}`. Unsupported upgrade path" ) migrated_manifest = JSONDict ( ) # Explicitly set the manifest_version first so it appears at the top of the manifest migrated_manifest . set_path ( "/manifest_version" , "2.0.0" ) # Generate and introduce a uuid app_uuid = str ( uuid . uuid4 ( ) ) migrated_manifest . set_path ( "/app_uuid" , app_uuid ) for key , val in V2_TO_V1_MAP . items ( ) : if val == SKIP_IF_FOUND : continue # If the value is a string and is a JSONPath, then load the value from the JSON Path elif isinstance ( val , str ) and val . startswith ( "/" ) : final_value = loaded_manifest . get_path ( val ) else : final_value = val # We need to remove any of the underlying "assets" that are just an empty dictionary if key in [ "/assets/dashboards" , "/assets/monitors" , "/assets/saved_views" ] and not final_value : continue if final_value is not None : migrated_manifest . set_path ( key , final_value ) # Update any previously skipped field in which we can use logic to assume the value of # Also iterate through any lists to include new/updated fields at each index of the list migrated_manifest . set_path ( "/classifier_tags" , TODO_FILL_IN ) # Retrieve and map all categories from other fields classifier_tags = [ ] supported_os = loaded_manifest . get_path ( "/supported_os" ) for os in supported_os : os_tag = OS_TO_CLASSIFIER_TAGS . get ( os . lower ( ) ) if os_tag : classifier_tags . append ( os_tag ) categories = loaded_manifest . get_path ( "/categories" ) for category in categories : category_tag = CATEGORIES_TO_CLASSIFIER_TAGS . get ( category . lower ( ) ) if category_tag : classifier_tags . append ( category_tag ) # Write the manifest back to disk migrated_manifest . set_path ( "/classifier_tags" , classifier_tags ) # Marketplace-only fields: if ctx . obj [ 'repo_name' ] == "marketplace" : migrated_manifest . set_path ( "/author/vendor_id" , TODO_FILL_IN ) migrated_manifest . set_path ( "/author/sales_email" , loaded_manifest . get_path ( "/terms/legal_email" ) ) migrated_manifest . set_path ( "/pricing" , loaded_manifest . get_path ( "/pricing" ) ) migrated_manifest . set_path ( "/legal_terms" , { } ) migrated_manifest . set_path ( "/legal_terms/eula" , loaded_manifest . get_path ( "/terms/eula" ) ) for idx , _ in enumerate ( migrated_manifest . get_path ( "/pricing" ) or [ ] ) : migrated_manifest . set_path ( f"/pricing/{idx}/product_id" , TODO_FILL_IN ) migrated_manifest . set_path ( f"/pricing/{idx}/short_description" , TODO_FILL_IN ) migrated_manifest . set_path ( f"/pricing/{idx}/includes_assets" , True ) write_file ( get_manifest_file ( integration ) , json . dumps ( migrated_manifest , indent = 2 ) ) echo_success ( f"Successfully migrated {integration} manifest to version {to_version}. Please update any needed fields, " f"especially those that are marked with `{TODO_FILL_IN}`" )