Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# This file is part of daf_butler. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <http://www.gnu.org/licenses/>. 

21 

22 

23import click 

24from functools import partial 

25 

26from ..utils import MWOptionDecorator, split_commas, split_kv, unwrap, yaml_presets 

27from lsst.daf.butler.registry import CollectionType 

28 

29 

30class CollectionTypeCallback: 

31 

32 collectionTypes = CollectionType.__members__.keys() 

33 

34 @staticmethod 

35 def makeCollectionTypes(context, param, value): 

36 if not value: 

37 # Click seems to demand that the default be an empty tuple, rather 

38 # than a sentinal like None. The behavior that we want is that 

39 # not passing this option at all passes all collection types, while 

40 # passing it uses only the passed collection types. That works 

41 # fine for now, since there's no command-line option to subtract 

42 # collection types, and hence the only way to get an empty tuple 

43 # is as the default. 

44 return tuple(CollectionType.all()) 

45 result = [] 

46 for item in split_commas(context, param, value): 

47 item = item.upper() 

48 try: 

49 result.append(CollectionType.__members__[item]) 

50 except KeyError: 

51 raise KeyError(f"{item} is not a valid CollectionType.") from None 

52 return tuple(result) 

53 

54 

55collection_type_option = MWOptionDecorator("--collection-type", 

56 callback=CollectionTypeCallback.makeCollectionTypes, 

57 multiple=True, 

58 help="If provided, only list collections of this type.", 

59 type=click.Choice(CollectionTypeCallback.collectionTypes, 

60 case_sensitive=False)) 

61 

62 

63collections_option = MWOptionDecorator("--collections", 

64 help=unwrap("""One or more expressions that fully or partially identify 

65 the collections to search for datasets. If not provided all 

66 datasets are returned."""), 

67 multiple=True, 

68 callback=split_commas) 

69 

70 

71components_option = MWOptionDecorator("--components/--no-components", 

72 default=None, 

73 help=unwrap("""For --components, apply all expression patterns to 

74 component dataset type names as well. For --no-components, 

75 never apply patterns to components. Default (where neither 

76 is specified) is to apply patterns to components only if 

77 their parent datasets were not matched by the expression. 

78 Fully-specified component datasets (`str` or `DatasetType` 

79 instances) are always included.""")) 

80 

81 

82config_option = MWOptionDecorator("-c", "--config", 

83 callback=split_kv, 

84 help="Config override, as a key-value pair.", 

85 multiple=True) 

86 

87 

88config_file_option = MWOptionDecorator("-C", "--config-file", 

89 help=unwrap("""Path to a pex config override to be included after the 

90 Instrument config overrides are applied.""")) 

91 

92 

93dataset_type_option = MWOptionDecorator("-d", "--dataset-type", 

94 callback=split_commas, 

95 help="Specific DatasetType(s) to validate.", 

96 multiple=True) 

97 

98 

99datasets_option = MWOptionDecorator("--datasets") 

100 

101 

102logLevelChoices = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"] 

103log_level_option = MWOptionDecorator("--log-level", 

104 callback=partial(split_kv, 

105 choice=click.Choice(logLevelChoices, 

106 case_sensitive=False), 

107 normalize=True, 

108 unseparated_okay=True, 

109 add_to_default=True), 

110 help="The logging level. " 

111 f"Supported levels are [{'|'.join(logLevelChoices)}]", 

112 is_eager=True, 

113 metavar="LEVEL|COMPONENT=LEVEL", 

114 multiple=True) 

115 

116 

117long_log_option = MWOptionDecorator("--long-log", 

118 help="Make log messages appear in long format.", 

119 is_flag=True) 

120 

121 

122options_file_option = MWOptionDecorator("--options-file", "-@", 

123 expose_value=False, # This option should not be forwarded 

124 help=unwrap("""URI to YAML file containing overrides 

125 of command line options. The YAML should be organized 

126 as a hierarchy with subcommand names at the top 

127 level options for that subcommand below."""), 

128 callback=yaml_presets) 

129 

130 

131processes_option = MWOptionDecorator("-j", "--processes", 

132 default=1, 

133 help="Number of processes to use.", 

134 type=click.IntRange(min=1)) 

135 

136 

137regex_option = MWOptionDecorator("--regex") 

138 

139 

140run_option = MWOptionDecorator("--output-run", 

141 help="The name of the run datasets should be output to.") 

142 

143 

144transfer_option = MWOptionDecorator("-t", "--transfer", 

145 default="auto", # set to `None` if using `required=True` 

146 help="The external data transfer mode.", 

147 type=click.Choice(["auto", "link", "symlink", "hardlink", "copy", "move", 

148 "relsymlink", "direct"], 

149 case_sensitive=False)) 

150 

151 

152verbose_option = MWOptionDecorator("-v", "--verbose", 

153 help="Increase verbosity.", 

154 is_flag=True) 

155 

156 

157where_option = MWOptionDecorator("--where", 

158 help="A string expression similar to a SQL WHERE clause.")