@@ -49,12 +49,12 @@ def transform_csv_to_csv(location, output, transformer):
4949
5050 rows = read_csv_rows (location )
5151
52- column_names , data , errors = transform_csv (rows , transformer )
52+ field_names , data , errors = transform_csv (rows , transformer )
5353
5454 if errors :
5555 return errors
5656 else :
57- write_csv (output , data , column_names )
57+ write_csv (output , data , field_names )
5858 return []
5959
6060def transform_json_to_json (location , output , transformer ):
@@ -82,36 +82,36 @@ def transform_csv(rows, transformer):
8282 Read a list of list of CSV-like data `rows` and apply transformations using the
8383 `transformer` Transformer.
8484 Return a tuple of:
85- ([column names...], [transformed ordered dict...], [Error objects..])
85+ ([field names...], [transformed ordered dict...], [Error objects..])
8686 """
8787
8888 if not transformer :
8989 return rows
9090
9191 errors = []
9292 rows = iter (rows )
93- column_names = next (rows )
94- column_names = transformer .clean_columns ( column_names )
93+ field_names = next (rows )
94+ field_names = transformer .clean_fields ( field_names )
9595
96- dupes = check_duplicate_columns ( column_names )
96+ dupes = check_duplicate_fields ( field_names )
9797
9898 if dupes :
99- msg = 'Duplicated column name: {name}'
99+ msg = 'Duplicated field name: {name}'
100100 errors .extend (Error (CRITICAL , msg .format (name )) for name in dupes )
101- return column_names , [], errors
101+ return field_names , [], errors
102102
103- column_names = transformer .apply_renamings (column_names )
103+ field_names = transformer .apply_renamings (field_names )
104104
105- # convert to dicts using the renamed columns
106- data = [OrderedDict (zip_longest (column_names , row )) for row in rows ]
105+ # convert to dicts using the renamed fields
106+ data = [OrderedDict (zip_longest (field_names , row )) for row in rows ]
107107
108- if transformer .column_filters :
109- data = list (transformer .filter_columns (data ))
110- column_names = [c for c in column_names if c in transformer .column_filters ]
108+ if transformer .field_filters :
109+ data = list (transformer .filter_fields (data ))
110+ field_names = [c for c in field_names if c in transformer .field_filters ]
111111
112- errors = transformer .check_required_columns (data )
112+ errors = transformer .check_required_fields (data )
113113
114- return column_names , data , errors
114+ return field_names , data , errors
115115
116116
117117def transform_json (data , transformer ):
@@ -126,7 +126,7 @@ def transform_json(data, transformer):
126126
127127 errors = []
128128 new_data = []
129- renamings = transformer .column_renamings
129+ renamings = transformer .field_renamings
130130 #if json is output of scancode-toolkit
131131 try :
132132 if (data ["headers" ][0 ]["tool_name" ] == "scancode-toolkit" ):
@@ -161,12 +161,12 @@ def process_json_keys(data, renamings, transformer):
161161 o_dict [k ] = data [k ]
162162 new_data = [o_dict ]
163163
164- if transformer .column_filters :
165- new_data = list (transformer .filter_columns (new_data ))
164+ if transformer .field_filters :
165+ new_data = list (transformer .filter_fields (new_data ))
166166 else :
167167 new_data = list (new_data )
168168
169- errors = transformer .check_required_columns (new_data )
169+ errors = transformer .check_required_fields (new_data )
170170 return new_data , errors
171171
172172
@@ -177,42 +177,42 @@ def process_json_keys(data, renamings, transformer):
177177
178178The attributes that can be set in a configuration file are:
179179
180- * column_renamings :
181- An optional map of source CSV column name to target CSV new column name that
182- is used to rename CSV columns .
180+ * field_renamings :
181+ An optional map of source CSV or JSON field name to target CSV/JSON new field name that
182+ is used to rename CSV fields .
183183
184- For instance with this configuration the columns "Directory/Location" will be
184+ For instance with this configuration the fields "Directory/Location" will be
185185renamed to "about_resource" and "foo" to "bar":
186- column_renamings :
186+ field_renamings :
187187 'Directory/Location' : about_resource
188188 foo : bar
189189
190190The renaming is always applied first before other transforms and checks. All
191- other column names referenced below are these that exist AFTER the renamings
192- have been applied to the existing column names.
191+ other field names referenced below are these that exist AFTER the renamings
192+ have been applied to the existing field names.
193193
194- * required_columns :
195- An optional list of required column names that must have a value, beyond the
196- standard columns names. If a source CSV does not have such a column or a row is
197- missing a value for a required column , an error is reported.
194+ * required_fields :
195+ An optional list of required field names that must have a value, beyond the
196+ standard fields names. If a source CSV/JSON does not have such a field or a row is
197+ missing a value for a required field , an error is reported.
198198
199- For instance with this configuration an error will be reported if the columns
199+ For instance with this configuration an error will be reported if the fields
200200"name" and "version" are missing or if any row does not have a value set for
201- these columns :
202- required_columns :
201+ these fields :
202+ required_fields :
203203 - name
204204 - version
205205
206- * column_filters :
207- An optional list of column names that should be kept in the transformed CSV. If
208- this list is provided, all the columns from the source CSV that should be kept
209- in the target CSV must be listed be even if they are standard or required
210- columns . If this list is not provided, all source CSV columns are kept in the
211- transformed target CSV.
206+ * field_filters :
207+ An optional list of field names that should be kept in the transformed CSV/JSON . If
208+ this list is provided, all the fields from the source CSV/JSON that should be kept
209+ in the target CSV/JSON must be listed be even if they are standard or required
210+ fields . If this list is not provided, all source CSV/JSON fields are kept in the
211+ transformed target CSV/JSON .
212212
213- For instance with this configuration the target CSV will only contains the "name"
214- and "version" columns and no other column :
215- column_filters :
213+ For instance with this configuration the target CSV/JSON will only contains the "name"
214+ and "version" fields and no other field :
215+ field_filters :
216216 - name
217217 - version
218218'''
@@ -222,32 +222,32 @@ def process_json_keys(data, renamings, transformer):
222222class Transformer (object ):
223223 __doc__ = tranformer_config_help
224224
225- column_renamings = attr .attrib (default = attr .Factory (dict ))
226- required_columns = attr .attrib (default = attr .Factory (list ))
227- column_filters = attr .attrib (default = attr .Factory (list ))
225+ field_renamings = attr .attrib (default = attr .Factory (dict ))
226+ required_fields = attr .attrib (default = attr .Factory (list ))
227+ field_filters = attr .attrib (default = attr .Factory (list ))
228228
229- # a list of all the standard columns from AboutCode toolkit
230- standard_columns = attr .attrib (default = attr .Factory (list ), init = False )
231- # a list of the subset of standard columns that are essential and MUST be
229+ # a list of all the standard fields from AboutCode toolkit
230+ standard_fields = attr .attrib (default = attr .Factory (list ), init = False )
231+ # a list of the subset of standard fields that are essential and MUST be
232232 # present for AboutCode toolkit to work
233- essential_columns = attr .attrib (default = attr .Factory (list ), init = False )
233+ essential_fields = attr .attrib (default = attr .Factory (list ), init = False )
234234
235235 # called by attr after the __init__()
236236 def __attrs_post_init__ (self , * args , ** kwargs ):
237237 from attributecode .model import About
238238 about = About ()
239- self .essential_columns = list (about .required_fields )
240- self .standard_columns = [f .name for f in about .all_fields ()]
239+ self .essential_fields = list (about .required_fields )
240+ self .standard_fields = [f .name for f in about .all_fields ()]
241241
242242 @classmethod
243243 def default (cls ):
244244 """
245245 Return a default Transformer with built-in transforms.
246246 """
247247 return cls (
248- column_renamings = {},
249- required_columns = [],
250- column_filters = [],
248+ field_renamings = {},
249+ required_fields = [],
250+ field_filters = [],
251251 )
252252
253253 @classmethod
@@ -259,18 +259,18 @@ def from_file(cls, location):
259259 with io .open (location , encoding = 'utf-8' ) as conf :
260260 data = saneyaml .load (replace_tab_with_spaces (conf .read ()))
261261 return cls (
262- column_renamings = data .get ('column_renamings ' , {}),
263- required_columns = data .get ('required_columns ' , []),
264- column_filters = data .get ('column_filters ' , []),
262+ field_renamings = data .get ('field_renamings ' , {}),
263+ required_fields = data .get ('required_fields ' , []),
264+ field_filters = data .get ('field_filters ' , []),
265265 )
266266
267- def check_required_columns (self , data ):
267+ def check_required_fields (self , data ):
268268 """
269269 Return a list of Error for a `data` list of ordered dict where a
270- dict is missing a value for a required column name.
270+ dict is missing a value for a required field name.
271271 """
272272 errors = []
273- required = set (self .essential_columns + self .required_columns )
273+ required = set (self .essential_fields + self .required_fields )
274274 if not required :
275275 return []
276276
@@ -280,54 +280,54 @@ def check_required_columns(self, data):
280280 continue
281281
282282 missings = ', ' .join (missings )
283- msg = 'Row {rn} is missing required values for columns : {missings}'
283+ msg = 'Row {rn} is missing required values for fields : {missings}'
284284 errors .append (Error (CRITICAL , msg .format (** locals ())))
285285 return errors
286286
287- def apply_renamings (self , column_names ):
287+ def apply_renamings (self , field_names ):
288288 """
289- Return a tranformed list of `column_names ` where columns are renamed
289+ Return a tranformed list of `field_names ` where fields are renamed
290290 based on this Transformer configuration.
291291 """
292- renamings = self .column_renamings
292+ renamings = self .field_renamings
293293 if not renamings :
294- return column_names
294+ return field_names
295295 renamings = {n .lower (): rn .lower () for n , rn in renamings .items ()}
296296
297297 renamed = []
298- for name in column_names :
298+ for name in field_names :
299299 name = name .lower ()
300300 new_name = renamings .get (name , name )
301301 renamed .append (new_name )
302302 return renamed
303303
304- def clean_columns (self , column_names ):
304+ def clean_fields (self , field_names ):
305305 """
306- Apply standard cleanups to a list of columns and return these.
306+ Apply standard cleanups to a list of fields and return these.
307307 """
308- if not column_names :
309- return column_names
310- return [c .strip ().lower () for c in column_names ]
308+ if not field_names :
309+ return field_names
310+ return [c .strip ().lower () for c in field_names ]
311311
312- def filter_columns (self , data ):
312+ def filter_fields (self , data ):
313313 """
314314 Yield transformed dicts from a `data` list of dicts keeping only
315- columns with a name in the `column_filters `of this Transformer.
316- Return the data unchanged if no `column_filters ` exists.
315+ fields with a name in the `field_filters `of this Transformer.
316+ Return the data unchanged if no `field_filters ` exists.
317317 """
318- column_filters = set (self .clean_columns (self .column_filters ))
318+ field_filters = set (self .clean_fields (self .field_filters ))
319319 for entry in data :
320- items = ((k , v ) for k , v in entry .items () if k in column_filters )
320+ items = ((k , v ) for k , v in entry .items () if k in field_filters )
321321 yield OrderedDict (items )
322322
323323
324- def check_duplicate_columns ( column_names ):
324+ def check_duplicate_fields ( field_names ):
325325 """
326- Check that there are no duplicate in the `column_names ` list of column name
327- strings, ignoring case. Return a list of unique duplicated column names.
326+ Check that there are no duplicate in the `field_names ` list of field name
327+ strings, ignoring case. Return a list of unique duplicated field names.
328328 """
329- counted = Counter (c .lower () for c in column_names )
330- return [column for column , count in sorted (counted .items ()) if count > 1 ]
329+ counted = Counter (c .lower () for c in field_names )
330+ return [field for field , count in sorted (counted .items ()) if count > 1 ]
331331
332332
333333def read_csv_rows (location ):
@@ -349,13 +349,13 @@ def read_json(location):
349349 return data
350350
351351
352- def write_csv (location , data , column_names ): # NOQA
352+ def write_csv (location , data , field_names ): # NOQA
353353 """
354354 Write a CSV file at `location` the `data` list of ordered dicts using the
355- `column_names `.
355+ `field_names `.
356356 """
357357 with io .open (location , 'w' , encoding = 'utf-8' , newline = '\n ' ) as csvfile :
358- writer = csv .DictWriter (csvfile , fieldnames = column_names )
358+ writer = csv .DictWriter (csvfile , fieldnames = field_names )
359359 writer .writeheader ()
360360 writer .writerows (data )
361361
0 commit comments