ClearCase: Find files having exactly one specific label and not more
Asked Answered
A

3

6

I'd like to find files in ClearCase that are labeled with a specific label but that do not have any other labels set.

For example, if I have files labeled like this:

file1 LBL_A, LBL_B
file2 LBL_A

I'd like to have a query that gives me just file2 and not file1.

Is there a way to do this with cleartool find? If this is not possible to do with a single query, I'd also be happy for any ideas how to do this in several steps (I'll be calling cleartool from a perl script, so it will be easy to save lists of files temporarily and run further commands on them).

Thanks a lot in advance!

Jan

Afrikaner answered 24/6, 2009 at 10:55 Comment(1)
Just updated my command lines to show versions instead of elementRarity
B
7

Assuming LBL_A is the (only) label you want running

cleartool find /some/dir -version 'lbtype(LBL_A)' -print | xargs cleartool describe -fmt "%n: %l"

should give

file1: (LBL_A, LBL_B)
file2: (LBL_A)

as output which you then can check in your perl script or filter through sed -n 's/\(.*\): (LBL_A)/\1/p' (assuming no colons in filenames).

Update: As VonC correctly points out, the command above will fail for files with spaces in. To handle that run as:

cleartool find ... -print | tr '\012' '\000' | xargs -0 cleartool ....

which will translate newlines into ascii null and then have xargs use that as delimiter.

British answered 24/6, 2009 at 11:40 Comment(2)
@British you did not miss anything (like I did). I just canceled the downvote and rewrite my post :)Rarity
@British I fix my post and propose another (simple) way to filter the result. Since your post follow is essentially correct: +1Rarity
I
6

You can do this directly without having to pipe:

cleartool find . -ver "lbtype(LBL_A) && !lbtype(LBL_B)" -print
Inferential answered 5/9, 2009 at 23:48 Comment(2)
Did anyone verify whether this actually works? Sounds like a much more efficient solution than filtering the cleartool output after the fact. Of course this method doesn't exactly answer the question, unless one knows exactly what labels may occur.Mogador
I can assure you it does, which doesn't create an additional process to do the filtering. Of course, it requires knowing in advance which labels to filter out. Some combination of this method plus some post-processing (as in other answers) might be required.Inferential
R
2

hlovdal's answer illustrates that, in this case, you have to find more elements than you need, and then filter them (despite all the ClearCase find features).

Note:

 cleartool find . -type f -element 'lbtype_sub(LBL_A)' -print

could give you directly the elements (and not the version which may not be interesting in this case). You can find the version with -version and a format directive as explained below.

With the help of fmt_ccase, you can tailor the output to get precisely what your perl script will need to go on:

 cleartool find . -type f -element 'lbtype_sub(LBL_A)' -exec 'cleartool describe -fmt "%En %Cl\n" \"$CLEARCASE_XPN\"' | grep -v ","
  • -fmt "%En %l\n" will display the full path of the element (instead of the version: /a/b/myFile@@/main/myVersion) => /a/b/myFile'. the '\n` ensure one result per line.
  • -version and -fmt "%n %l\n" would display the version
  • \"$CLEARCASE_XPN\": the double quotes arount the extended path of the version found ensure a file with spaces in its name will still work.
  • grep -v ",": if there is any comma, that means "more than one label"
  • %Cl: avoid displaying the all list of labels. Anyway, if there are more than one, you are not interested!

So, for finding the exact version:

 cleartool find . -type f -version 'lbtype_sub(LBL_A)' -exec 'cleartool describe -fmt "%n %Cl\n" \"$CLEARCASE_XPN\"' | grep -v ","|awk '{sub(/ \(.*/,"");print}'

Note:
The above works with unix syntax. The windows syntax would be:

cleartool find . -type f -element "lbtype(LBL_A)" -exec "cleartool describe -fmt \"%n %Cl\n\" \"%CLEARCASE_XPN%\"" | grep -v "," | gawk "{gsub(/ \(.*,"");print}"

, which would list the version of files with only one (correct) label.

  • awk '{sub(/ \(.*/,"");print}' will transform "myFile@@/main/myVersion (LBL_A)" into "myFile@@/main/myVersion"
Rarity answered 24/6, 2009 at 12:29 Comment(3)
Eh, did I miss something? The question says "any other labels", you are only explicitly testing LBL_B.British
@British You are correct, and and have rewritten my answer to actually respond to the OP ;)Rarity
thanks to you, too - because I need the version, hlovdal's version suits me better, but also the link to of fmtccase was very helpful!Afrikaner

© 2022 - 2024 — McMap. All rights reserved.