125125)
126126
127127
128- @core .command (parser )
129- def python_userland_chown (opts , args : list [str ]):
130- parser .expect_nargs (args , (1 ,))
131-
132- from_uid : int | None = None
133- from_gid : int | None = None
134-
135- if opts .from_spec :
136- from_uid , from_gid = parser .parse_owner_spec (opts .from_spec )
137-
138- chown_args = {"follow_symlinks" : opts .dereference }
139-
140- owner_spec : str
141-
128+ def get_new_owner (opts , args : list [str ], chown_args : dict ) -> str | None :
142129 if opts .reference :
143130 try :
144131 ref_stat = Path (opts .reference ).stat (follow_symlinks = True )
145132 except OSError as e :
146133 core .perror (e )
147- return 1
134+ return None
148135
149136 chown_args ["user" ] = ref_stat .st_uid
150137 chown_args ["group" ] = ref_stat .st_gid
151138
152- owner_spec = (
139+ return (
153140 core .user_display_name_from_id (ref_stat .st_uid )
154141 + ":"
155142 + core .group_display_name_from_id (ref_stat .st_gid )
156143 )
157- else :
158- parser .expect_nargs (args , (2 ,))
159- owner_spec = args .pop (0 )
160144
161- if not ( owner_match := CHOWN_PATTERN . match ( owner_spec )):
162- parser . error ( f"invalid owner spec: { owner_spec } " )
145+ parser . expect_nargs ( args , ( 2 ,))
146+ owner_spec = args . pop ( 0 )
163147
164- chown_args ["user" ] = (
165- parser .parse_user (owner_match .group (1 )) if owner_match .group (1 ) else None
166- )
167- chown_args ["group" ] = (
168- parser .parse_group (owner_match .group (3 )) if owner_match .group (3 ) else None
169- )
148+ if not (owner_match := CHOWN_PATTERN .match (owner_spec )):
149+ parser .error (f"invalid owner spec: { owner_spec } " )
150+
151+ chown_args ["user" ] = (
152+ parser .parse_user (owner_match .group (1 )) if owner_match .group (1 ) else None
153+ )
154+ chown_args ["group" ] = (
155+ parser .parse_group (owner_match .group (3 )) if owner_match .group (3 ) else None
156+ )
157+
158+ return owner_spec
159+
160+
161+ @core .command (parser )
162+ def python_userland_chown (opts , args : list [str ]):
163+ parser .expect_nargs (args , (1 ,))
164+
165+ from_uid : int | None = None
166+ from_gid : int | None = None
167+
168+ if opts .from_spec :
169+ from_uid , from_gid = parser .parse_owner_spec (opts .from_spec )
170+
171+ chown_args = {"follow_symlinks" : opts .dereference }
172+
173+ if not (owner_spec := get_new_owner (opts , args , chown_args )):
174+ return 1
170175
171176 failed = False
172177
178+ def handle_error (err : Exception , level : int , msg : str ) -> None :
179+ nonlocal failed
180+ failed = True
181+
182+ if opts .verbosity :
183+ core .perror (err )
184+ if opts .verbosity > level :
185+ print (msg , file = sys .stderr )
186+
173187 for file in core .traverse_files (
174188 (tqdm (args , ascii = True , desc = "Changing ownership" ) if opts .progress else args ),
175189 recurse_mode = opts .recurse_mode if opts .recursive else None ,
@@ -184,14 +198,9 @@ def python_userland_chown(opts, args: list[str]):
184198 prev_uid = stat .st_uid
185199 prev_gid = stat .st_gid
186200 except OSError as e :
187- failed = True
188- if opts .verbosity :
189- core .perror (e )
190- if opts .verbosity > 2 :
191- print (
192- f"failed to change ownership of '{ file } ' to { owner_spec } " ,
193- file = sys .stderr ,
194- )
201+ handle_error (
202+ e , 2 , f"failed to change ownership of '{ file } ' to { owner_spec } "
203+ )
195204 continue
196205
197206 prev_uname = core .user_display_name_from_id (prev_uid )
@@ -207,14 +216,9 @@ def python_userland_chown(opts, args: list[str]):
207216 try :
208217 shutil .chown (file , ** chown_args )
209218 except OSError as e :
210- failed = True
211- if opts .verbosity :
212- core .perror (e )
213- if opts .verbosity > 2 :
214- print (
215- f"failed to change ownership of '{ file } ' to { owner_spec } " ,
216- file = sys .stderr ,
217- )
219+ handle_error (
220+ e , 2 , f"failed to change ownership of '{ file } ' to { owner_spec } "
221+ )
218222 continue
219223
220224 if prev_uid == chown_args ["user" ] or prev_gid == chown_args ["group" ]:
0 commit comments