ki_
ki_

Reputation: 649

Artifactory AQL delete empty folders

How do I delete empty folders(folders without any content) by using Artifactory AQL?

I have the current AQL query to find files that are older than 12w and never downloaded, which I will delete by an script.

items.find(
    {
        "repo":{"$eq":"libs-release-local"},
        "stat.downloads":{"$eq":null},
        "created":{"$before" : "12w"},
    }
)

This leaves me with empty folders, how do I specify an AQL query that finds all empty folders?

Upvotes: 7

Views: 4683

Answers (3)

Sean
Sean

Reputation: 11

Even now, nearly 7 years after the question was asked, it seems this is impossible to do using AQL. Mainly because the AQL 'item' entity doesn't support the 'children' field, so you cannot check for folders where the children field is empty.

AQL entity documentation here: https://jfrog.com/help/r/jfrog-rest-apis/aql-entities-and-fields.

So, I solved this using a Python script that calls the the 'storage' REST API. Apologies I cannot post the actual code here, but the abstract approach is as follows:

  1. Make an HTTP "get" request to the Artifactory storage API specifying the parent path in your repository. To specify the root of the repo, just use "/".

  2. Fetch the 'children' field from the result object.

  3. If the 'children' collection exists and is not empty, then iterate through its contents checking whether each child item is a folder.

    • Folder items have a boolean property 'folder' with a value of True.
    • File items do not have this property.
  4. For any child item which is a folder, recursively call steps 1-7, passing a folder URI which is the product of the current folder URI and the child item's own URI (child URI is relative to its parent)

  5. Count the children of the current folder, taking into account that any child folders might have been deleted. I simply call the storage API again for the current folder to get a fresh view of its 'children' collection, but you could also count and pass back up the recursive call chain.

  6. If no child items remain for the current folder, then make an HTTP "delete" for the current folder's repository and URI.

  7. Return to the caller.

If you are ONLY cleaning up empty folders, the above can be simplified. My own implementation is more complex because I'm checking file 'lastUpdated' timestamps against a configurable retention period and optionally deleting files as well, so I keep track of both files and folders as I recurse the folder structure. This way I housekeep old artefacts, and delete any folders that are left empty as I go.

Upvotes: 0

CacheYouOnTheFlipSide
CacheYouOnTheFlipSide

Reputation: 79

If you are not married to the idea of using AQL, note that there is an Empty Folder Clean-up plugin by JFrog.

Upvotes: 1

Roman G
Roman G

Reputation: 166

From Artifactory Query Language documentation: if type is not specified in the query, the default type searched for is file.

By adding a type to the query you can control the result type: file, folder or both.

For example:

items.find(
    {
        "repo": {"$eq":"libs-release-local"},
        "stat.downloads": {"$eq":null},
        "created": {"$before" : "12w"},
        "type": {"$eq":"any"}
    }
)

Upvotes: 4

Related Questions