Wim Coenen
Wim Coenen

Reputation: 66723

How to list subfolders in Artifactory

I'm trying to write a script which cleans up old builds in my generic file repository in Artifactory. I guess the first step would be to look in the repository and check which builds are in there.

Each build shows up as a subfolder of /foo, so for example I have folders /foo/123, /foo/124, /foo/125/, etc.

There doesn't seem to be a ls or dir command. So I tried the search command:

jfrog rt search my-repo/foo/*

But this recursively lists all files, which is not what I'm looking for. I just need the list of direct subfolders. I also tried

jfrog rt search my-repo/foo/* --recursive=false

but this doesn't return any results, because the search command only returns files, not folders.

How do I list the subfolders of a given folder in an Artifactory repository?

Upvotes: 10

Views: 22104

Answers (7)

Anjan
Anjan

Reputation: 613

you are so close, you need to include --include-dirs

jfrog rt search --recursive=false --include-dirs my-repo/foo/* | jq '.[] | select(.type == "folder")'

Upvotes: 0

Gags08
Gags08

Reputation: 252

By default, it searches for files, if you want to list directories, add one more property --include-dirs

Refer the link for additional parameters. jfrog search

Here is the command.

jf rt search --recursive=false --include-dirs=true path/

Response:

 [
    {
        "path": "artifactory-name/path",
        "type": "folder",
        "created": "",
        "modified": ""
    }
]

Upvotes: 0

Alpaca
Alpaca

Reputation: 707

The jfrog cli now includes the --include-dirs option for search.

The command:

jf rt search --recursive=false --include-dirs path/

will essentially act like an ls.

Upvotes: 4

Wim Coenen
Wim Coenen

Reputation: 66723

A cleaner approach is to tell Artifactory about builds, and let it discard old ones.

There are 3 parts to this. My examples are for the jfrog command line utility:

  1. When uploading files with the "jfrog rt upload" command, use the --build-name someBuildName and --build-number someBuildNumber arguments. This links the uploaded files to a certain build.

  2. After uploading files, publish the build with "jfrog rt build-publish someBuildName someBuildNumber"

  3. To clean up all but the 3 latest builds, use "jfrog rt build-discard --max-builds=3 someBuildName"

Upvotes: -1

jroquelaure
jroquelaure

Reputation: 553

You should have a look to AQL (Artifactory Query Langage) here : https://www.jfrog.com/confluence/display/RTF/Artifactory+Query+Language

as an example the following AQL will retrieve all folders located in "my-repo" under "foo" folder and will display the result ordered by folder's name :

items.find(
    {
        "type":"folder",
        "repo":{"$eq":"my-repo"},
            "path":{"$eq":"foo"}
    }
)
.include("name")
.sort({"$desc":["name"]})

For cleanup you can also have a look at the following example which gives a list of the 10 biggest artifacts created more than a month ago that have never been downloaded :

items.find(
    {
        "type":"file",
        "repo":{"$eq":"my-repo"},
        "created":{"$before":"1mo"},
        "stat.downloads":{"$eq":null}
    }
)
.include("size","name")
.sort({"$desc":["size"]})
.limit(10) 

Upvotes: 7

cantSleepNow
cantSleepNow

Reputation: 10182

Just one more way to do it with curl and jq

curl -s http://myatifactory.domain:4567/artifactory/api/storage/myRepo/myFolder | jq -r '.children[] |select(.folder==true) |.uri'

Explanation: Curl is used to get the folder info and that is piped to JQ which then displays all the uri keys of the children array whose folder key has value true.

Just for easier understanding - the json that curl gets looks something like this (example from artifactory docs)

{
"uri": "http://localhost:8081/artifactory/api/storage/libs-release-local/org/acme",
"repo": "libs-release-local",
"path": "/org/acme",
"created": ISO8601 (yyyy-MM-dd'T'HH:mm:ss.SSSZ),
"createdBy": "userY",
"lastModified": ISO8601 (yyyy-MM-dd'T'HH:mm:ss.SSSZ),
"modifiedBy": "userX",
"lastUpdated": ISO8601 (yyyy-MM-dd'T'HH:mm:ss.SSSZ),
"children": [
{
            "uri" : "/child1",
            "folder" : "true"
        },{
            "uri" : "/child2",
            "folder" : "false"
         }
]
}

and for it the output of the command would be /child1.

Of course here it's assumed that artifactory repo myRepo allows anonymous read.

Upvotes: 10

Wim Coenen
Wim Coenen

Reputation: 66723

Based on jroquelaure's answer, I ended up with the following. The key thing that was still missing was that you have to convert the "items.find" call into JSON when putting it in a filespec. There is an example of that in the filespec documentation which I missed at first.

I put this JSON in a test.aql file:

{
  "files": 
    [
      {
        "aql": 
          {
            "items.find" : 
               {
                 "type":"folder",
                 "repo":{"$eq":"my-repo"},
                 "path":{"$eq":"foo"}
               }
          }
      }
    ]
}

Then I call jfrog rt search --spec=test.aql.

Upvotes: 6

Related Questions