Re: [22007] portutil.tcl mods / more portfile.7 changes needed?
macports-dev@lists.macosforge.org on Tuesday, February 13, 2007 at 7:09 PM -0800 wrote:
Reimplement delete so it no longer uses system "/bin/rm -rf ..." This also fixes the case of filenames with spaces in them being incorrectly parsed - That was EXTREMELY dangerous Add new touch command - usage similar to BSD touch Add new copy and move commands - basically aliases for file copy/rename Add new ln command - usage similar to BSD ln These should be documented somewhere
I might be able to find time to document this. Especially because as I think about it there are still a couple of glaring omissions from our docs. I've written many portfiles and I still don't know the answer. Is there a way to do recursive copies without using a system call? I know how to use glob and recurse files within a directory, but I'm still not clear on whether it can be done for arbitrary contents of a directory. It seems not. So perhaps more portfile.7 manpage work is needed to answer these questions. They all revolve around globbing or recursion. 1) The use of 'glob'. It is missing from the manpages, is it not? Also provide liberal examples in the reinplace section and xinstall section. 2) Is it possible for reinplace to replace multiple strings for the same file with one statement? 3) The answer to whether generic recursive queries can be accomplished with TCL extensions. 3a) If the answer is no but a generic TCL script can be wrapped around xinstall using globs, then an example be given for doing this. If neither 3 or 3a is possible, state that system calls for recursive copies are acceptible. If someone can answer these questions adequately I may be able to find time to document this in portfile.7. It should be pretty simple and I think it would clear up some confusion. Mark
On Feb 14, 2007, at 12:01 AM, Mark Duling wrote:
I might be able to find time to document this. Especially because as I think about it there are still a couple of glaring omissions from our docs. I've written many portfiles and I still don't know the answer. Is there a way to do recursive copies without using a system call? I know how to use glob and recurse files within a directory, but I'm still not clear on whether it can be done for arbitrary contents of a directory. It seems not.
file copy will copy directories. And with my change, that can be shortened to just copy.
So perhaps more portfile.7 manpage work is needed to answer these questions. They all revolve around globbing or recursion.
1) The use of 'glob'. It is missing from the manpages, is it not? Also provide liberal examples in the reinplace section and xinstall section.
Docs on this can be found with `man n glob`. You may simply want to put in a reference to glob(n) there.
2) Is it possible for reinplace to replace multiple strings for the same file with one statement?
Nope. The syntax for reinplace is `reinplace pattern file1 [file2 ...]`. If you want to make things simple, you can do something like foreach pat [list pat1 pat2 pat3] { reinplace $pat file1 file2 } If the pattern has spaces, be sure to enclose it in quotes or braces (just like you do with reinplace) Incidentally, the pattern is a single command as understood by sed (in fact, it's actually interpreted by sed under the hood).
3) The answer to whether generic recursive queries can be accomplished with TCL extensions.
What do you mean by this?
3a) If the answer is no but a generic TCL script can be wrapped around xinstall using globs, then an example be given for doing this. If neither 3 or 3a is possible, state that system calls for recursive copies are acceptible.
Clarify 3 and I may be able to answer this as well.
If someone can answer these questions adequately I may be able to find time to document this in portfile.7. It should be pretty simple and I think it would clear up some confusion.
Sounds good. -Kevin Ballard -- Kevin Ballard http://kevin.sb.org eridius@macports.org http://www.tildesoft.com
Kevin Ballard <eridius@macports.org> on Tuesday, February 13, 2007 at 9:17 PM -0800 wrote:
Docs on this can be found with `man n glob`. You may simply want to put in a reference to glob(n) there.
Ah I see. Yes. I still think some usage examples in TCL extensions would be beneficial.
2) Is it possible for reinplace to replace multiple strings for the same file with one statement?
Nope. The syntax for reinplace is `reinplace pattern file1 [file2 ...]`.
If you want to make things simple, you can do something like
foreach pat [list pat1 pat2 pat3] { reinplace $pat file1 file2 }
If the pattern has spaces, be sure to enclose it in quotes or braces (just like you do with reinplace)
Incidentally, the pattern is a single command as understood by sed (in fact, it's actually interpreted by sed under the hood).
Got it.
3) The answer to whether generic recursive queries can be accomplished with TCL extensions.
What do you mean by this?
If I'm not supposed to do 'system "cp -R ${dir} ${dir}"', then what is the easiest and/or recommended way to accomplish the same thing without using system calls?
3a) If the answer is no but a generic TCL script can be wrapped around xinstall using globs, then an example be given for doing this. If neither 3 or 3a is possible, state that system calls for recursive copies are acceptible.
Clarify 3 and I may be able to answer this as well.
If there isn't a way to do recursive copies (functionally equivalent to cp -R) without system calls, is there a generic foolproof way to accomplish gneric recursive copies in TCL extensions by wrapping them in a script as in your example with reinplace?
foreach pat [list pat1 pat2 pat3] { reinplace $pat file1 file2 }
Mark
Like I said, file copy (or just copy, after my commit) will in fact copy directories. In general, if you want to be recursive, we actually have a find command in pextlib, though the only place I know of it being used is in my fusefs port. That can be used such as find basedir {filter_expression} {do stuff with $filename} or find -depth basedir {filter_expression} {do stuff with $filename, depth-first} If you want to match everything, filter_expression should just be expr 1. To give an example from fusefs, to recursively change file attributes (equivalent to chmod -R) I used find ${sysfsdir}/fusefs.fs {expr 1} { file attributes $filename -owner root -group wheel } That said, as long as I'm the only user of find (as I believe is the case) I am tempted to make some changes to the API. For example, the filter really should be an expr expression by default (as is the case with if/while/etc.), and the $filename variable really should have its name specified in the call, so it doesn't override an existing $filename (i.e. find basedir {filter} filevarname {some expression with $filevarname} ). On Feb 14, 2007, at 12:28 AM, Mark Duling wrote:
If I'm not supposed to do 'system "cp -R ${dir} ${dir}"', then what is the easiest and/or recommended way to accomplish the same thing without using system calls?
3a) If the answer is no but a generic TCL script can be wrapped around xinstall using globs, then an example be given for doing this. If neither 3 or 3a is possible, state that system calls for recursive copies are acceptible.
Clarify 3 and I may be able to answer this as well.
If there isn't a way to do recursive copies (functionally equivalent to cp -R) without system calls, is there a generic foolproof way to accomplish gneric recursive copies in TCL extensions by wrapping them in a script as in your example with reinplace?
-- Kevin Ballard http://kevin.sb.org eridius@macports.org http://www.tildesoft.com
Kevin Ballard <eridius@macports.org> on Tuesday, February 13, 2007 at 9:45 PM -0800 wrote:
Like I said, file copy (or just copy, after my commit) will in fact copy directories.
I'm sorry to be so dull. You seem to be saying this: copy ${sourcedir} ${destdir} is equivalent to this: system "cp -R ${sourcedir} ${destdir}" But doesn't 'eval xinstall [glob ${source}/* ${dest}' fail if there are nested directories? So I thought perhaps your new copy command would have the same problem. I'm sorry we're talking by each other, but I have some preconceptions that I'm having trouble getting beyond at the moment.
find basedir {filter_expression} {do stuff with $filename}
Because if filter_expression = "*", then is there a tcl command I can use in {do stuff with ..} that doesn't care if something is a file or directory? Because I thought that the TCL extensions I've learned so far require me to know in advance whether I'm copying files or directories, so I wonder if it is possible for {filter_expression} to be "*". Mark
On Feb 14, 2007, at 2:00 AM, Mark Duling wrote:
Like I said, file copy (or just copy, after my commit) will in fact copy directories.
I'm sorry to be so dull. You seem to be saying this:
copy ${sourcedir} ${destdir}
is equivalent to this:
system "cp -R ${sourcedir} ${destdir}"
But doesn't 'eval xinstall [glob ${source}/* ${dest}' fail if there are nested directories? So I thought perhaps your new copy command would have the same problem. I'm sorry we're talking by each other, but I have some preconceptions that I'm having trouble getting beyond at the moment.
xinstall and file copy are different - xinstall is implemented in pextlib, and apparently doesn't recursively copy directories. It's a shame. So yeah, while xinstall won't handle directories, copy will do it just fine. The difference is that copy won't handle file permissions, but xinstall does.
find basedir {filter_expression} {do stuff with $filename}
Because if filter_expression = "*", then is there a tcl command I can use in {do stuff with ..} that doesn't care if something is a file or directory? Because I thought that the TCL extensions I've learned so far require me to know in advance whether I'm copying files or directories, so I wonder if it is possible for {filter_expression} to be "*".
Actually, filter_expression isn't a glob, it's a tcl expression. In the current incarnation of find, you want to use something like {expr 1}. That will make it work on everything. That said, it will recurse into directories, so if you want the equivalent of the above xinstall command you'd simply do eval file copy [list [glob -directory ${source} *]] ${dest} Of course, this does have the problem where glob won't find dot- files. and if you use * .* instead of the *, it will, but it'll find . and .. as well. It's annoying. -- Kevin Ballard http://kevin.sb.org eridius@macports.org http://www.tildesoft.com
On Feb 13, 2007, at 9:45 PM, Kevin Ballard wrote:
That said, as long as I'm the only user of find (as I believe is the case) I am tempted to make some changes to the API. For example, the filter really should be an expr expression by default (as is the case with if/while/etc.), and the $filename variable really should have its name specified in the call, so it doesn't override an existing $filename (i.e. find basedir {filter} filevarname {some expression with $filevarname} ).
As the author of that find function, both of those changes seem reasonable to me. In hindsight, I should have at least buried the "magic $filename variable" behind an underscore or something, but making it non-magic is an even better idea (sort of similar to parameters in ruby blocks). - Jordan
participants (3)
-
Jordan K. Hubbard
-
Kevin Ballard
-
Mark Duling