From lionel.thiry at gmail.com Sat Dec 3 08:12:03 2005 From: lionel.thiry at gmail.com (Lionel Thiry) Date: Sat, 03 Dec 2005 14:12:03 +0100 Subject: [Rant] ruby build and extconf.rb Message-ID: <439199A3.2020307@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello Stefan, hello the list Have you ever tried to compile some extensions to ruby with the extconf.rb technique and encountered difficulties? Or even lamentably failed? I have. And as I can see in the ruby mailing list, it is not that rare. The extconf.rb uses the mkmf file, and mkmf file uses rbconfig, and rbconfig.rb is a plateform specific file which has been created when ruby were build. It were build with mkconfig.rb, as stated in rbconfig.rb. But ruby itself were build with the gnu autotools (correct me if I'm wrong). Then I suppose the rbconfig.rb works in concordance with the configure script run when ruby were build. (still, correct me if I'm wrong) And now, here is where I wanted to go from the beginning: how would extconf.rb works if ruby were build using rant instead of the gnu autotools? Let me point out that it is probably possible to do that. First is "build the mini-ruby interpreter" and second is "run a ruby build script". And that ruby build script could have been generated by that so much powerfull feature of rant: rant-import. It is just a meditation proposal, nothing more. I'm not saying that you Stefan, nor anyone who'd read this should do such a work. I'm just asking: is it feasible? What good would it bring? What bad would it bring? Would it be easy to do or not? Would Matz be happy with that? Would ruby community be happy with that? That kind of question. Thanks for your attention, cheers - -- Lionel Thiry Personal web site: http://users.skynet.be/lthiry/ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (MingW32) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFDkZmjwm55UGlHz5IRAkX1AKCZLD0cdB3YjvfpHQGLuM93NuMy9wCeMUll hT0NY7b2Da55g2d0J/w5LLI= =tQC7 -----END PGP SIGNATURE----- From langstefan at gmx.at Sat Dec 3 17:24:23 2005 From: langstefan at gmx.at (Stefan Lang) Date: Sat, 3 Dec 2005 23:24:23 +0100 Subject: [Rant] ruby build and extconf.rb In-Reply-To: <439199A3.2020307@gmail.com> References: <439199A3.2020307@gmail.com> Message-ID: <200512032324.24398.langstefan@gmx.at> On Saturday 03 December 2005 14:12, Lionel Thiry wrote: > Hello Stefan, hello the list > > Have you ever tried to compile some extensions to ruby with the > extconf.rb technique and encountered difficulties? Or even > lamentably failed? I have. And as I can see in the ruby mailing > list, it is not that rare. > > The extconf.rb uses the mkmf file, and mkmf file uses rbconfig, and > rbconfig.rb is a plateform specific file which has been created > when ruby were build. It were build with mkconfig.rb, as stated in > rbconfig.rb. But ruby itself were build with the gnu autotools > (correct me if I'm wrong). Then I suppose the rbconfig.rb works in > concordance with the configure script run when ruby were build. > (still, correct me if I'm wrong) > > And now, here is where I wanted to go from the beginning: how would > extconf.rb works if ruby were build using rant instead of the gnu > autotools? If ruby were built using rant, the standard ruby package would include rant at least in form of a library. Consequently, extconf.rb could be used just for parametrization instead of generating a Makefile. > Let me point out that it is probably possible to do that. First is > "build the mini-ruby interpreter" and second is "run a ruby build > script". And that ruby build script could have been generated by > that so much powerfull feature of rant: rant-import. I think the main problem here is, that much of the current build system would be needed anyway to build miniruby. There would be two build systems to maintain, one using autotools and one using rant. Anyway, I'll try to build ruby using rant some time. But at least a first version of this build system will depend on a previous ruby installation. With regards to building ruby extensions: A library for Rant is planned, that can be used from within an Rantfile to build and install extensions. But don't expect it in the near future. I would say earliest rant release date with this feature is about march next year. Suggestions and help are always welcome! Kind regards, Stefan From langstefan at gmx.at Mon Dec 12 13:50:17 2005 From: langstefan at gmx.at (Stefan Lang) Date: Mon, 12 Dec 2005 19:50:17 +0100 Subject: [Rant] Rant 0.5.2 released Message-ID: <200512121950.17953.langstefan@gmx.at> == What's new in this release? Incompatible changes: * The two undocumented Array methods ary.arglist and ary.shell_pathes, which are deprecated since release 0.4.8, are removed with this release. Use sys.sp(ary) in Rantfiles instead. * The method rac, which is deprecated since release 0.4.6 is gone. * Filelists no longer respond to all Array methods. To use the filelist method no_dir, import "filelist/std" is required now. See below for documentation links. Fixes and minor improvements: * A bug in the YAML library of Ruby 1.8.3/1.8.4-preview1 prevented created gems to work with other ruby versions. Since this Rant release gems created with a RubyPackage task and Ruby 1.8.3 will work with all Ruby versions (with gem support, of course). * Fixed bug where the method Rant::Sys.split_all would drop a leading dot directory (e.g. as in "./foo/bar"). * New method Rant::Sys.regular_filename for filename conversion. New features: * Major rework of filelist support. The Rant::FileList class is available as "normal" Ruby library now. Read doc/filelist.rdoc for Rant::FileList documentation and doc/sys_filelist.rdoc for instructions on how to use filelists in Rantfiles. == Installing Rant You can install Rant as a RubyGem: ? ? % gem install --remote rant or download the package from RubyForge(http://rubyforge.org/frs/?group_id=615) and install with install.rb: ? ? % ruby install.rb == Using the Rant::FileList class Docs: http://make.rubyforge.org/files/doc/filelist_rdoc.html You can use Rant's FileList class as library in your Ruby app/library. Example usage: # Iterate over all files in the current directory and its # subdirectories, skipping backup files (filenames ending # in ~ or .bak). require "rant/filelist" Rant::FileList.glob_all "**/*" do |fl| fl.exclude "*~", "*.bak" fl.files.each { |filename| # do something with the file "filename" } end Note: If Rant is installed as a RubyGem, you have to: require "rubygems" require_gem "rant" first. The following code snippet, using only Ruby core libraries is equivalent to the above FileList example: fl = Dir.glob("**/*", File::FNM_DOTMATCH) fl.reject! { |filename| File.fnmatch("*~", filename, File::FNM_DOTMATCH) or File.fnmatch("*.bak", filename, File::FNM_DOTMATCH) } fl.select { |filename| File.file?(filename) }.each { |filename| # do something with the file "filename" } == Resources Homepage:: visit http://make.ruby-co.de Rubyforge page:: http://rubyforge.org/projects/make/ Repository:: http://developer.berlios.de/svn/?group_id=5046 Naming suggestions, feature requests for further Rant development, etc. are welcome! -- Stefan From kevin.burge at systemware.com Fri Dec 16 15:04:35 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Fri, 16 Dec 2005 14:04:35 -0600 Subject: [Rant] Using rant to automate a huge collection of projects Message-ID: <43A31DD3.5000607@systemware.com> Stefan, I've been using a make tool called Jam to build a large repository of projects that contain many of our projects as well as many third party libraries. I've started implementing a replacement using rant. I decided on rant because we've used Ruby for years, and love coding in Ruby. Jam is a pain to extend (written in C) or to do anything out of the ordinary. We're building large C/C++ applications, C#, and Java (there's some VB in there, but I'm not as concerned about it). I'm looking to make a completey automated build system for multiple Unix platforms as well as Windows. I decided not to use rake just based on the fact that Rant appears to be more organized and has been error messages (I didn't really look at the source of rake though), and because of the comparison on your web site. My main concern is: is Rant ready? Am I going to find myself implementing a lot of stuff, particularly for compiling C/C++ code? -- it seems to be mostly "there". I once tried a tool called maven, and though I liked what it could do, I didn't like the "java-ish" nature of it (especially that the language behind it was executable xml - perhaps the antithesis of Ruby). This sort of task does seem more fit for languages like Ruby and Python (granted that the number of dependencies is reasonable). Anyways, basically I've been implementing a framework where a new developer can type: rant -f bootstrap.rant (or ruby bootstrap.rb after rant-import) and download prepacked rant import files from a web server, that are then used by all of the smaller individual project's rantfiles for deploying to the web cache (in binary or source distribution form, etc.) for retrieving dependencies and unpacking them, perhaps building them, etc. One of the limitations of Jam is that we have to check out the entire repository (200+MB iirc) just to build a small piece because Jam requires the "main" Jamfile (Jamrules) to be in the parent directory of ALL sub-directories that use Jamfiles. I want to use rant to free us from that restriction, and to gain a much, much more powerful tool in the process. I'd be happy to contribute code and ideas back to this project - because I need it to work, and a non-ruby solution is really undesirable. My immediate problem (or lack of understanding of rant): I'm using gen Package::Zip (or Tgz) to create a package of files. But the package gets created with the entire path of the dependent files I provided: i.e. dist/win/dbg/include/test.h The "root.rant" is in the parent of the dist directory. I want the package to have this file as a dependency, but when it zips it, I want the path to be: dist_dir/include/test.h not dist_dir/dist/win/dbg/include/test.h I was thinking of adding a :trunc option to the package to indicate a part of the path that you want to truncate from the dependencies. i.e. gen Package::Zip, 'build', :files => files, :trunc => 'dist/win/dbg/' or something like that. Any assistance would be appreciated. Thanks, Kevin Please visit http://www.systemware.com/. From langstefan at gmx.at Fri Dec 16 18:33:53 2005 From: langstefan at gmx.at (Stefan Lang) Date: Sat, 17 Dec 2005 00:33:53 +0100 Subject: [Rant] Using rant to automate a huge collection of projects In-Reply-To: <43A31DD3.5000607@systemware.com> References: <43A31DD3.5000607@systemware.com> Message-ID: <200512170033.54208.langstefan@gmx.at> On Friday 16 December 2005 21:04, Kevin Burge wrote: > Stefan, > > I've been using a make tool called Jam to build a large repository > of projects that contain many of our projects as well as many third > party libraries. I've started implementing a replacement using > rant. I decided on rant because we've used Ruby for years, and > love coding in Ruby. Jam is a pain to extend (written in C) or to > do anything out of the ordinary. > > We're building large C/C++ applications, C#, and Java (there's some > VB in there, but I'm not as concerned about it). I'm looking to > make a completey automated build system for multiple Unix platforms > as well as Windows. I decided not to use rake just based on the > fact that Rant appears to be more organized and has been error > messages (I didn't really look at the source of rake though), and > because of the comparison on your web site. > > My main concern is: is Rant ready? Am I going to find myself > implementing a lot of stuff, particularly for compiling C/C++ code? > -- it seems to be mostly "there". Currently, Rant has only one C/C++ specific ability: It can check dependencies between source files (caused by #include statements). > I once tried a tool called maven, and though I liked what it could > do, I didn't like the "java-ish" nature of it (especially that the > language behind it was executable xml - perhaps the antithesis of > Ruby). This sort of task does seem more fit for languages like > Ruby and Python (granted that the number of dependencies is > reasonable). Anyways, basically I've been implementing a framework > where a new developer can type: > > rant -f bootstrap.rant > (or ruby bootstrap.rb after rant-import) > > and download prepacked rant import files from a web server, that > are then used by all of the smaller individual project's rantfiles > for deploying to the web cache (in binary or source distribution > form, etc.) for retrieving dependencies and unpacking them, perhaps > building them, etc. > > One of the limitations of Jam is that we have to check out the > entire repository (200+MB iirc) just to build a small piece because > Jam requires the "main" Jamfile (Jamrules) to be in the parent > directory of ALL sub-directories that use Jamfiles. I want to use > rant to free us from that restriction, and to gain a much, much > more powerful tool in the process. > > I'd be happy to contribute code and ideas back to this project - > because I need it to work, and a non-ruby solution is really > undesirable. > > My immediate problem (or lack of understanding of rant): > > I'm using gen Package::Zip (or Tgz) to create a package of files. > But the package gets created with the entire path of the dependent > files I provided: > > i.e. > > dist/win/dbg/include/test.h > > The "root.rant" is in the parent of the dist directory. > > I want the package to have this file as a dependency, but when it > zips it, I want the path to be: > > dist_dir/include/test.h > > not > > dist_dir/dist/win/dbg/include/test.h > > I was thinking of adding a :trunc option to the package to indicate > a part of the path that you want to truncate from the dependencies. > > i.e. > > gen Package::Zip, 'build', :files => files, :trunc => > 'dist/win/dbg/' > > or something like that. Such an option is currently missing. I think a :trunc option like you need it now should be supported and thus it will come with the next release! Until this option is implemented, you could use something like this: import "archive/zip" desc "Create sources package build.zip" task "build-pkg" do make "build-dist_dir" make "build.zip" end task "build-dist_dir" do dist_dir = "dist_dir" dist_files = sys["rant-0.5.2/lib/**/*.rb"] trunc = "rant-0.5.2/lib/" dist_files.each { |source| target = File.join(dist_dir, source.sub(/^#{trunc}/, "")) target_dir = File.dirname(target) sys.mkdir_p target_dir sys.install source, target, :preserve => true } end gen Archive::Zip, "build", :files => sys["dist_dir/**/*"] Regards, Stefan From langstefan at gmx.at Fri Dec 16 18:38:07 2005 From: langstefan at gmx.at (Stefan Lang) Date: Sat, 17 Dec 2005 00:38:07 +0100 Subject: [Rant] Using rant to automate a huge collection of projects In-Reply-To: <200512170033.54208.langstefan@gmx.at> References: <43A31DD3.5000607@systemware.com> <200512170033.54208.langstefan@gmx.at> Message-ID: <200512170038.07489.langstefan@gmx.at> On Saturday 17 December 2005 00:33, Stefan Lang wrote: > On Friday 16 December 2005 21:04, Kevin Burge wrote: [...] > > I'm using gen Package::Zip (or Tgz) to create a package of files. > > But the package gets created with the entire path of the > > dependent files I provided: > > > > i.e. > > > > dist/win/dbg/include/test.h > > > > The "root.rant" is in the parent of the dist directory. > > > > I want the package to have this file as a dependency, but when it > > zips it, I want the path to be: > > > > dist_dir/include/test.h > > > > not > > > > dist_dir/dist/win/dbg/include/test.h > > > > I was thinking of adding a :trunc option to the package to > > indicate a part of the path that you want to truncate from the > > dependencies. > > > > i.e. > > > > gen Package::Zip, 'build', :files => files, :trunc => > > 'dist/win/dbg/' > > > > or something like that. > > Such an option is currently missing. I think a :trunc option like > you need it now should be supported and thus it will come with > the next release! > > Until this option is implemented, you could use something like > this: Correction for your pathes :) > import "archive/zip" > > desc "Create sources package build.zip" > task "build-pkg" do > make "build-dist_dir" > make "build.zip" > end > > task "build-dist_dir" do > dist_dir = "dist_dir" > dist_files = sys["rant-0.5.2/lib/**/*.rb"] # list of files to package dist_files = sys["dist/win/dbg/**/*.{c,h}", "dist/win/dgb/foo", ...] > trunc = "rant-0.5.2/lib/" trunc = "dist/win/dbg/" > dist_files.each { |source| > target = File.join(dist_dir, source.sub(/^#{trunc}/, "")) > target_dir = File.dirname(target) > sys.mkdir_p target_dir > sys.install source, target, :preserve => true > } > end > > gen Archive::Zip, "build", :files => sys["dist_dir/**/*"] > > Regards, > Stefan > _______________________________________________ > make-cafe mailing list > make-cafe at rubyforge.org > http://rubyforge.org/mailman/listinfo/make-cafe From kevin.burge at systemware.com Sat Dec 17 00:21:02 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Fri, 16 Dec 2005 23:21:02 -0600 Subject: [Rant] Using rant to automate a huge collection of projects (task specific var values), part 2 Message-ID: <43A3A03E.4090107@systemware.com> Stefan, Thank you for the previous answer. I thought about doing this manually, I'll look over your solution when I get back to this later today. I just remember two other issues that I'm running into: * Jam allows you to set variables to specific values for a specific task. An example would be CCFLAGS (actually, a variable named CCHDRS is the one I'm most concerned about). I originally had (basically): gen Rule, '.o' => '.c' with a gen Command inside with a command like '${var :cc} -c -o ${t.name} ${var[:CCHDRS].join(' ')}'.............etc.. I turned out to not be able to use the rule, because I couldn't say "CCHDRS on libfoo.a should be xxxxx" but "CCHDRS on testfoolib should be yyyy". I set var[:CCHDRS] in both sub.rant files, but the last definition was use in the actuall command. Jam had the syntax: CCHDRS on libfoo.a += ..........new headers, etc. ; Basically, what I did to work around this was use ruby variables to pass to a method that creates the tasks and the actions required to build it. Here's the code: def library(libname, includes, files) name = "#{var[:pfxlib]}#{libname}#{var[:suflib]}" gen Directory, var[:features]['c:locate_target'] var[:clean] << var[:features]['c:locate_target'] # create build task desc "Build #{name}" task :build => [ var[:features]['c:locate_target'], "#{var[:features]['c:locate_target']}/#{name}" ] # generate and source dependencies gen C::Dependencies, :search => %w( . ) + includes gen Action do source "c_dependencies" end hdrs = includes.map { |i| "-I#{sys.sp i}" } desc "Make libraries" task :libs => [ name ] var[:clean] << name dps = [] files.each do |src| case File.extname(src) when /\.(c|cc|cpp|cxx)$/i obj = "#{var[:features]['c:locate_target']}/#{src.sub_ext(var[:sufobj][1..-1])}" var[:clean] << obj dps << obj f = file obj => [ src, ] do |t| # #{var[:CCFLAGS].join(' ')} #{var[:OPTIM].join(' ')} #{var[:CCDEFS].join(' ')} if Env.on_windows? sys "#{var :CC} /c /Fo#{sys.sp t.name} #{hdrs.join(' ')} #{sys.sp t.source}" else sys "#{var :CC} -c -o #{sys.sp t.name} #{hdrs.join(' ')} #{sys.spt.source}" end end f.enhance [ var[:features]['c:locate_target'] ] #when /\.rc$/i # etc else abort("Dont' know how to handle #{src}") end end file "#{var[:features]['c:locate_target']}/#{name}" => dps do |t| if Env.on_windows? sys "#{var[:features]['cmd:ar'].cmd} /out:#{sys.sp t.name} #{t.prerequisites.map{|i| sys.sp i}.join(' ')}" else sys "#{var[:features]['cmd:ar'].cmd} #{t.prerequisites.map{|i| sys.sp i}.join(' ')}" end unless var[:features]['cmd:ranlib'].cmd.nil? sys "#{var[:features]['cmd:ranlib'].cmd} #{sys.sp t.name}" end end end This code works (on windows), but is incomplete (more stuff needed on compile and link command lines). My "features" stuff is a set of classes that encapsulates c_flags, cpp_flags, link_flags, cpp_link_flags, and etc. variables for a specific feature, like say "threaded". The values are set per os/cpu/version, etc. in one of my common rant files. I could have just used var :cc or var :cc_cmd for the "command features"... I'm still experimenting, and I don't want to run into variable naming conflict issues in "var". I don't know how Jam does this "task specific var value". I thought about using the task name and duping var and storing it as a variable of var with "#{task.name}:var" or something like that. Right now I'm on the fast track to getting something to work. I'll make it pretty later. So, basically, I don't see how I can use gen Rule for this type of thing, without the Rule smart enough to allow for variables in the gen Command string to be different for each task that's being generated. Maybe I just need to dup "var" and store it as part of the task object itself? fwiw, my "features" are defined like such (might be something useful to add into rant): var[:features]['c:flags:release'] = CFlagsFeature.new var[:features]['c:flags:debug'] = CFlagsFeature.new var[:features]['c:flags:optim-release'] = CFlagsFeature.new var[:features]['c:flags:optim-debug'] = CFlagsFeature.new var[:features]['c:flags:optim-none'] = CFlagsFeature.new var[:features]['c:flags:warnings'] = CFlagsFeature.new var[:features]['c:flags:dynamic-library'] = CFlagsFeature.new var[:features]['c:flags:static-library'] = CFlagsFeature.new var[:features]['c:flags:shrlib'] = CFlagsFeature.new var[:features]['c:libs:mpatrol'] = CLibsFeature.new var[:features]['c:libs:insure'] = CLibsFeature.new var[:features]['c:libs:system'] = CLibsFeature.new var[:features]['c:libs:console'] = CLibsFeature.new example usage: when 'linux' var[:features]['c:flags:os'].c_flags += %w( -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 ) when 'solaris' var[:features]['c:flags:os'].c_flags += %w( -D_POSIX_C_SOURCE=199506L -D__EXTENSIONS__ -D_FILE_OFFSET_BITS=64 ) else $stderr.puts "compiler \"#{var[:compiler]}\" on \"#{var[:os]}\" not supported" end var[:features]['c:flags:os'].cpp_flags = var[:features]['c:flags:os'].c_flags var[:features]['c:flags:optim-release'].c_flags = %w( -O2 -g -g3 -ggdb -ggdb3 ) var[:features]['c:flags:optim-debug'].c_flags = %w( -O0 -g -g3 -ggdb -ggdb3 ) Etc. I may if I get far enough into this create a gen "Feature" task, something like this: task "test.o" => [ :cfeature_multi_threaded ] gen Feature, :cfeature_multi_threaded do |t| # somehow append task specific vars required for "multi-threaded code" to the target task # i.e. target.var :CFLAGS += %w( ...... ) # etc. end And then make another feature that combines several features together, so that when I define my multi-threaded library, I only have to make the "multi_threaded_cpp_library" a prereq for my library. I apologize for the length of this message. I know this list doesn't have a great deal of activity, so I hope the others don't mind. Thanks, Kevin Please visit http://www.systemware.com/. From kevin.burge at systemware.com Sat Dec 17 00:33:06 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Fri, 16 Dec 2005 23:33:06 -0600 Subject: [Rant] Extending "sys"? Message-ID: <43A3A312.204@systemware.com> Stefan, Since I'm automating deployment via rant, I've added in a couple commands to sys: sys.wget and sys.scp (and sys.scp_t). I also added a sys.write_to_binfile class < File.dirname(pkg_dir) else sys.unpack_tgz pkg, :in => File.dirname(pkg_dir) end end # remember the project definition var['project:wget'] = prj # remember the installation path var['path:wget'] = pkg_dir end end # task to retrive the wget yaml file file "#{var :cache_local_path}/project/wget.yaml" => [ "#{var[:cache_local_path]}/project" ] do |t| require 'net/http' require 'uri' yaml_fn = "#{File.basename(t.name)}" # download and save as text url = URI.parse("#{var :cache_web_url}/project/#{yaml_fn}") req = Net::HTTP::Get.new(url.path) res = Net::HTTP.start(url.host, url.port) do |http| # need to handle HTTP errors here!! http.request(req) end sys.write_to_file "#{var :cache_local_path}/project/#{yaml_fn}", res.body end and sys.scp (only partialy pasting sinc the code is similar to the above): gen Task, :sys_scp do |t| t.needed { !sys.respond_to?('scp') } t.act do # make sure putty is installed first (or at least can be located) make 'installed:putty' # extend the sys instance class < #{sp tf.path}" IO.foreach(sfn) do |l| tf.puts l.chomp! end tf.close src_t << tf.path end scp(src_t, dest) end else alias :scp_t :scp end end end end Please visit http://www.systemware.com/. From kevin.burge at systemware.com Sat Dec 17 00:44:35 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Fri, 16 Dec 2005 23:44:35 -0600 Subject: [Rant] Dependency tree? Message-ID: <43A3A5C3.1050609@systemware.com> Hi Stefan and all, I haven't been able to find a way to figure out how and where a specific task is being required. Is there a way to do this? I've ended up having to remove every occurrance and start adding it back until I found out where it was being required. A little time consuming. I've got a situation right now where I do a deploy, which then runs the build, installs, pacakages, then deploys. Then if I run the delpoy task again, it builds, installs, but doesn't repackage, then deploys (which is expected, since I don't know whether it's deployed yet). Then when I run it again, it does what it should have done the second time... just deploy. I've got no clue how to find out why it's rebuilding and reinstalling other than the method I indicated above. Thanks, Kevin Please visit http://www.systemware.com/. From kevin.burge at systemware.com Sat Dec 17 00:47:02 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Fri, 16 Dec 2005 23:47:02 -0600 Subject: [Rant] Have to say this last thing Message-ID: <43A3A656.8080601@systemware.com> Stefan, I like Rant, like I like Ruby. Thanks for creating this. Didn't want to have only questions/concerns/problems on this list. :) If I can make this all work, this will save me a lot of time day to day. Kevin Please visit http://www.systemware.com/. From langstefan at gmx.at Sat Dec 17 07:14:43 2005 From: langstefan at gmx.at (Stefan Lang) Date: Sat, 17 Dec 2005 13:14:43 +0100 Subject: [Rant] Extending "sys"? In-Reply-To: <43A3A312.204@systemware.com> References: <43A3A312.204@systemware.com> Message-ID: <200512171314.43866.langstefan@gmx.at> On Saturday 17 December 2005 06:33, Kevin Burge wrote: > Stefan, > > Since I'm automating deployment via rant, I've added in a couple > commands to sys: sys.wget and sys.scp (and sys.scp_t). > > I also added a sys.write_to_binfile > > class < def write_to_binfile(fn, content) > content = content.to_str > fu_output_message "writing #{content.size} bytes to file > `#{fn}'" File.open fn, "wb" do |f| > f.write content > end > end > end > > The problem was I was downloading a zip file, and sys.write_to_file > was corrupting it, only having opened with "w" on windows. :) > > If you have a better way to extend sys, I'd like to hear it. (makes > me nervous changing the instance). It's OK to add the methods directly to the instance and it is the recommended way if the methods are very specific to your project. If you want to separate the method definitions from the other task definitions, place them in a separate file, i.e. "sys_methods.rb" in the same directory as the Rantfile and load it with: source "sys_methods.rb" from the Rantfile. The usual way to add methods not specific to a single project would be to add a file under rant/import/sys/ somewhere in Ruby's $LOAD_PATH. It seems that you have already looked at the definition of write_to_file. > (I'm pasting most of the code, for completeness, so you can see > what I'm trying to do. You seem to be open to ideas, based on what > I've read from the list postings.) > > # task used to make sure sys.wget is available > # use sys_wget as a prereq to make sure it's installed > > gen Task, :sys_wget do |t| > t.needed { !sys.respond_to?('wget') } > > t.act do > # make sure wget is installed first (or at least can be > located) make 'installed:wget' > > # extend the sys instance > class < def wget(src) > path = sp "#{@rant::var['path:wget']}/wget.exe" sh "#{path} #{src}" =begin remove this section > cmd = "#{path} #{src}" > fu_output_message cmd > success = system(cmd) > if block_given? > block[$?] > elsif !success > raise ::Rant::CommandError.new(cmd, $?) > end =end > end > end > end > end Doesn't wget.exe live in a directory listed in the PATH environment variable? If it does, the definition of wget could simply look like: def wget(src) sh "wget", src.to_s end [...] > and sys.scp (only partialy pasting sinc the code is similar to the > above): > > gen Task, :sys_scp do |t| > t.needed { !sys.respond_to?('scp') } > > t.act do > # make sure putty is installed first (or at least can be > located) make 'installed:putty' > > # extend the sys instance > class < def scp(src, dest) > if ::Rant::Env.on_windows? > path = sp "#{@rant::var['path:putty']}/pscp.exe" > cmd = "#{path} -p -q -i #{sp > @rant.var[:cache_web_ssh_key]} #{src.map {|i| sp i}.join ' '} > #{dest.map {|i| escape i}.join ' '}" else > cmd = "scp -p #{src.map{|i| sp i}.join ' '} > #{dest.map{|i| escape i}.join ' '}" > end > fu_output_message cmd > success = system(cmd) > if block_given? > block[$?] > elsif !success > raise ::Rant::CommandError.new(cmd, $?) > end > end def scp(src, dest) # note: sp and escape accept an array as argument if Rant::Env.on_windows? path = sp "#{@rant::var['path:putty']}/pscp.exe" sh "#{path} -p -q -i #{sp @rant.var[:cache_web_ssh_key]} #{sp src} #{escape dest}" else sh "scp -p #{sp src} #{escape dest}" end end > # on windows, we need to convert some files to unix because > # transferring to a Unix web server. Use sys.scp_t to > automatically # convert. On Unix, sys.scp_t will just call sys.scp > (it's aliased) if ::Rant::Env.on_windows? > def scp_t(src, dest) > src_t = [] > src.to_a.each do |sfn| > tf = Tempfile.new('rant') > tf.binmode > fu_output_message "dos2unix #{sp sfn} > #{sp tf.path}" > IO.foreach(sfn) do |l| > tf.puts l.chomp! > end > tf.close > src_t << tf.path > end > > scp(src_t, dest) > end > else > alias :scp_t :scp > end > end > end > end Regards, Stefan From langstefan at gmx.at Sat Dec 17 10:57:18 2005 From: langstefan at gmx.at (Stefan Lang) Date: Sat, 17 Dec 2005 16:57:18 +0100 Subject: [Rant] Using rant to automate a huge collection of projects (task specific var values), part 2 In-Reply-To: <43A3A03E.4090107@systemware.com> References: <43A3A03E.4090107@systemware.com> Message-ID: <200512171657.18978.langstefan@gmx.at> On Saturday 17 December 2005 06:21, Kevin Burge wrote: > Stefan, > > Thank you for the previous answer. I thought about doing this > manually, I'll look over your solution when I get back to this > later today. > > I just remember two other issues that I'm running into: > > * Jam allows you to set variables to specific values for a specific > task. An example would be CCFLAGS (actually, a variable named > CCHDRS is the one I'm most concerned about). > > I originally had (basically): > > gen Rule, '.o' => '.c' with a gen Command inside with a command > like '${var :cc} -c -o ${t.name} ${var[:CCHDRS].join(' > ')}'.............etc.. Currently, there are no task specific variables in Rant :(. I'm in the process of adding the missing features to make Rant a feature complete general purpose build tool. Task specific variables are somewhere at the top of missing features, I'm searching for a nice declaration syntax, how to set them on the commandline, etc. Any suggestions are highly appreciated! Note that you can "fake" task specific variables with Command tasks and lambdas as variable values. The attached archive contains a small (artifical) example project with task specific variables. Probably you can integrate the relevant parts into your build system. Sadly the example revealed a bug in the latest Rant release. If you want, I can send you a Rant package with this bug fixed. [...] Seems that you have digged deep in Rant docs/sources ;) I think Command in combination with a lambda as variable value can help you much. E.g. var[:FLAGS] = lambda { |t| # t.full_name is the project subdirectory + task name # could be "subdir/foo.o" or "main.o", etc. # the return value of this Ruby block # will be interpolated in the command } gen Rule, '.o' => '.c' do |object, sources| gen Command object, sources, "cc ${FLAGS} -c -o $(>) $(<)" end > ,,, > And then make another feature that combines several features > together, so that when I define my multi-threaded library, I only > have to make the "multi_threaded_cpp_library" a prereq for my > library. That is an interesting approach. Anyway I'm interested if you succeed and if, in your solution! Just ask on this list if something isn't clear. Regards, Stefan -------------- next part -------------- A non-text attachment was scrubbed... Name: target_vars.zip Type: application/x-zip Size: 2218 bytes Desc: not available Url : http://rubyforge.org/pipermail/make-cafe/attachments/20051217/1b571281/target_vars.bin From kevin.burge at systemware.com Sat Dec 17 13:08:32 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Sat, 17 Dec 2005 12:08:32 -0600 Subject: [Rant] Extending sys? Message-ID: <43A45420.6070909@systemware.com> Stefan, You said: Doesn't wget.exe live in a directory listed in the PATH environment variable? If it does, the definition of wget could simply look like: def wget(src) sh "wget", src.to_s end Long answer: Part of the goal of this project is to allow that the user has nothing "as expected" except ruby and maybe rant. As it stands, we build so many different projects, and the user's machine varies so widely as to what might get in the way, I completely obliterate the environment on start up, and I go "fetch" from the web cache the tools that are needed to accomplish whatever task is required (and these tools have to be versioned, i.e. java 1.4 and java 1.5, even java 1.3 unfortunately). This requires being able to execute the tools from the "local cache" which the user does get to define. Yes, we could generate a setup that has the tools we need, but then we'll need a new tool eventually for something, and that'd require everyone to install... or say, we find a problem with cvsnt.exe we're using. I can "push out" a new one just by updating the project.yaml file for cvsnt with a new version and deploy it to the "web cache". Maven, from what I understand, works out the dependencies without the user having to download a bunch of stuff themselves. I like this, especially since it gives the rant developer total control of the build environment. Short answer: No, we don't know if wget.exe (or it's required dlls) live on the PATH. User's (developers) environments have caused too many problems for me (us). (Many times I had something build or run just fine on my machine, but would fail in five different ways on other's machines due to misconfiguration, tool differences, things in the path ahead of other things, etc.). if Env.on_windows? safe_vars = %w( ALLUSERSPROFILE APPDATA CLIENTNAME CommonProgramFiles COMPUTERNAME ComSpec HOME HOMEDRIVE HOMEPATH LOGONSERVER NUMBER_OF_PROCESSORS OS PATHEXT PROCESSOR_ARCHITECTURE PROCESSOR_IDENTIFIER PROCESSOR_LEVEL PROCESSOR_REVISION ProgramFiles PROMPT SESSIONNAME SystemDrive SystemRoot USERDOMAIN USERNAME USERPROFILE windir ) ENV.keys.each do |var| ENV[var] = nil unless safe_vars.include?(var) end ENV['PATH'] = "#{ENV['SystemRoot']}\\system32;#{ENV['SystemRoot']};#{ENV['SystemRoot']}\\System32\\Wbem" #fix $LOAD_PATH else $stderr.puts "set up for unix" end Thanks for the info on sh, sp, escape, and lamba. Definitely makes the code cleaner! Kevin Please visit http://www.systemware.com/. From kevin.burge at systemware.com Sat Dec 17 13:56:22 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Sat, 17 Dec 2005 12:56:22 -0600 Subject: [Rant] Plugin/generator guide Message-ID: <43A45F56.80108@systemware.com> Stefan, One thing that would really be useful would be examples on writing plugins (or at least more comments in the source) that explains how to extend rant with my own "gen Package" or "file " type generators/tasks. That way end-users can be consistent in syntax, rather than writing functions for doing the same thing as a generator would do. i.e. I have: def gen_project_deploy() ... end defined, when I'd rather do: gen Deploy, :myproject do end ..etc.. I could (and probably will) study the source more. I'm under a deadline to get my build system working before the end of the year (hopefully before the end of this weekend). Thanks for all the help, Kevin Please visit http://www.systemware.com/. From langstefan at gmx.at Sat Dec 17 15:11:45 2005 From: langstefan at gmx.at (Stefan Lang) Date: Sat, 17 Dec 2005 21:11:45 +0100 Subject: [Rant] Plugin/generator guide In-Reply-To: <43A45F56.80108@systemware.com> References: <43A45F56.80108@systemware.com> Message-ID: <200512172111.45924.langstefan@gmx.at> On Saturday 17 December 2005 19:56, Kevin Burge wrote: > Stefan, > > One thing that would really be useful would be examples on writing > plugins (or at least more comments in the source) that explains how > to extend rant with my own "gen Package" or "file " type > generators/tasks. That way end-users can be consistent in syntax, > rather than writing functions for doing the same thing as a > generator would do. > > i.e. > > I have: > > def gen_project_deploy() > ... > end > > defined, when I'd rather do: > > gen Deploy, :myproject do > end > > ..etc.. I'll try to explain enough for you to understand. Note that most of this is not officially supported. Sooner or later there will be an official and documented way to extend Rant. Anyway, to help you now: * All Rantfiles (i.e. the toplevel Rantfile, sub.rant files, files read with the source method) are evaluated in the context of a special object (via instance_eval). This object defines the methods: task file gen rant # accessor to the rant application object # which holds all tasks, variables, does # argument processing etc. import sys desc source var make subdirs These methods are not global (i.e. Kernel or Object methods). The context object is available as "rant.context". So in an Rantfile the code "rant.context == self" is true. The "gen" method is mainly a redirection mechanism. It requires an object that responds to "rant_gen" as first argument. To explore the "gen" functionality, run this Rantfile: obj = Object.new def obj.rant_gen(rant, ch, args, &block) # rant is the Rant application managing the build # rant.context is the context in which Rantfiles are # evaluated. p ch # a hash containing file and line number # of the "gen" call. ( e.g. {:ln => 5, :file => "/home/stefan/Rantfile"} ) p args # an array of the additional arguments to "gen" p block # the do end block given to "gen", or nil # usually tasks are defined now via rant.context (alias rant.cx) end gen obj gen obj, "foo", "bar" gen obj, "foo" => "bar" do end task :default The generators defined by Rant are class objects, so the rant_gen method of this generators are class methods. The generator classes live in the module Rant::Generators (not required) and are usually defined in a file under rant/import/ in Ruby's $LOAD_PATH. Let's create a simple My::FileCopy generator. Usage should be: import "my/filecopy" gen My::FileCopy, "dest" => "src" which should be equivalent to: file "dest" => "src" do |t| sys.cp t.source, t.name end Save the following code in a file rant/import/my/filecopy.rb somewhere in a $LOAD_PATH directory: ############################################################# module Rant # This method is called on an (more exactly: the first) # import "my/filecopy" # statement from an Rantfile. Note that the slash # is translated into a double underscore. def self.init_import_my__filecopy(rant, *rest) # With current Rant versions, rest is always empty, # just ignore it. # rant is the Rant application managing the current build # rant.context is the Rantfile context cx = rant.context # you could initialize variables via cx.var[:foo] = "bar" # or call sys methods, like cx.sys.touch "foo" # or load other imports, e.g. cx.import "package/zip" cx.import "subfile" # This puts statement is just for demonstration puts 'initialized import "my/filecopy"' end # Note that we could define anything in this file. Rant # doesn't require that we define a FileCopy class # just because this file is called filecopy.rb! module Generators::My; end class Generators::My::FileCopy def self.rant_gen(rant, ch, args, &block) cx = rant.context # we omit argument validation... # i.e. # if block # rant.abort_at(ch, "My::FileCopy doesn't take a block") # end target, source = nil args.first.each { |key, value| # only one key => value pair expected target = key source = value } # SubFile creates parent directories, if necessary # Note that we pass on rant and ch Rant::Generators::SubFile.rant_gen( rant, ch, [target => source]) do |t| cx.sys.cp source, target end # alternative: (without automatic parent # directory creation) # cx.file({:__caller__ => ch, target => source}) do |t| # cx.sys.cp source, target # end # The return value of "gen" is the return value of this # method. end end end # module Rant ##################################################################### The Rant application (which I've always named "rant" above) is an instance of Rant::RantApplication. It is defined in the file lib/rant/rantlib.rb together with the rant.context methods. Other things that might be useful: # project root directory rant.rootdir # e.g. "/home/stefan/myproject" # current build subdirectory rant.current_subdir # e.g. "lib" # Change pwd and to project_root_dir/"dir" rant.goto_project_dir "dir" # The following task definitions are like treated # as if they were define in "dir/sub.rant". rant.at_return do # this block is executed after rant is done end rant.at_return do # this too end Don't use anything related to the "plugin" method. This is highly deprecated and won't be in the 1.0.0 release. Regards, Stefan From langstefan at gmx.at Sun Dec 18 17:46:40 2005 From: langstefan at gmx.at (Stefan Lang) Date: Sun, 18 Dec 2005 23:46:40 +0100 Subject: [Rant] Rant 0.5.4 released Message-ID: <200512182346.40939.langstefan@gmx.at> == What's new in this release? This is mainly a bugfix release. Incompatible changes: * The undocumented method var.is which is deprecated since release 0.5.2 is not defined anymore. Fixes and minor improvements: * Fix a rule bug where a custom rule task wouldn't find it's prerequisites in subdirectories. * An non-backwards compatible change in the YAML library of Ruby 1.8.3 and newer causes gems to be non-backwards compatible. The fix for backwards compatibility of gems created with RubyPackage is enabled for all newer Ruby versions now. (See changes of last Rant release.) * The new method sys.write_to_binfile. (Kevin Burge's idea.) Read doc/sys.rdoc for documentation. == Installing Rant You can install Rant as a RubyGem: ? ? % gem install --remote rant or download the package from RubyForge(http://rubyforge.org/frs/?group_id=615) and install with install.rb: ? ? % ruby install.rb == Resources Homepage:: visit http://make.ruby-co.de Rubyforge page:: http://rubyforge.org/projects/make/ Repository:: http://developer.berlios.de/svn/?group_id=5046 Naming suggestions, feature requests for further Rant development, etc. are welcome! -- Stefan From kevin.burge at systemware.com Mon Dec 19 12:26:45 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Mon, 19 Dec 2005 11:26:45 -0600 Subject: [Rant] Bug: packager not including a file Message-ID: <43A6ED55.4070402@systemware.com> Here's my rant file: files = sys['**/*.rb', '**/*.rant'] name = "raven" task :default => :deploy pkg = nil if Env.on_windows? import 'package/zip' pkg = gen Package::Zip, name, :files => files else import 'package/tgz' pkg = gen Package::Tgz, name, :files => files end desc "Deploy raven" task :deploy => pkg.path do if Env.on_windows? sys "pscp -p -q -i #{sys.sp var[:cache_web_ssh_key]} #{pkg.path} #{var[:cache_web_user]}@#{var :cache_web_host}:#{var :cache_web_path}/system/" else sys "scp #{pkg.path} #{var[:cache_web_user]}@#{var :cache_web_host}:#{var :cache_web_path}/system/" end end the file it's ignored is "raven.rb", in the same directory as sub.rant. I renamed to "r.rb", and it picked it up. This is with 0.5.4. Looks like in archive.rb it should be: @res_files.exclude(/^#{Regexp.escape @dist_path}(\/.*)?$/) Yep, that fixed it. Kevin Please visit http://www.systemware.com/. From langstefan at gmx.at Mon Dec 19 17:15:04 2005 From: langstefan at gmx.at (Stefan Lang) Date: Mon, 19 Dec 2005 23:15:04 +0100 Subject: [Rant] Bug: packager not including a file In-Reply-To: <43A6ED55.4070402@systemware.com> References: <43A6ED55.4070402@systemware.com> Message-ID: <200512192315.05093.langstefan@gmx.at> On Monday 19 December 2005 18:26, Kevin Burge wrote: > Looks like in archive.rb it should be: > > ? ? ? ? ? ? ? ? @res_files.exclude(/^#{Regexp.escape > @dist_path}(\/.*)?$/) > > Yep, that fixed it. Test case added and fixed in svn. Thank you! Regards, Stefan From kevin.burge at systemware.com Wed Dec 21 20:34:28 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Wed, 21 Dec 2005 19:34:28 -0600 Subject: [Rant] How to abort with helpful info - the rant way? Message-ID: <43AA02A4.2090509@systemware.com> Stefan, I'm getting an error like: rant: [ERROR] in file `C:/home/kevin/work/openssl/root.rant', line 31: # couldn't locate project file for dependency "zlib_zlib" Exception `Rant::RantAbortException' at C:/home/kevin/work/dev/run/ruby/lib/ruby/site_ruby/1.8/rant/rantlib.rb:765 - Ran t::RantAbortException The generator is defined in import/raven.rb, but nowhere in this output do I have any indication of the location in raven.rb. Can you give a quick run-down on ways of "getting out" of a rant file. rant.abort, rant.abort_at, ruby's exit? What do you recommend? Thanks, Kevin Please visit http://www.systemware.com/. From langstefan at gmx.at Thu Dec 22 12:20:45 2005 From: langstefan at gmx.at (Stefan Lang) Date: Thu, 22 Dec 2005 18:20:45 +0100 Subject: [Rant] How to abort with helpful info - the rant way? In-Reply-To: <43AA02A4.2090509@systemware.com> References: <43AA02A4.2090509@systemware.com> Message-ID: <200512221820.46179.langstefan@gmx.at> On Thursday 22 December 2005 02:34, Kevin Burge wrote: > Stefan, > > I'm getting an error like: > > rant: [ERROR] in file `C:/home/kevin/work/openssl/root.rant', line > 31: # couldn't locate project > file for dependency "zlib_zlib" > Exception `Rant::RantAbortException' at > C:/home/kevin/work/dev/run/ruby/lib/ruby/site_ruby/1.8/rant/rantlib >.rb:765 - Ran > t::RantAbortException > > The generator is defined in import/raven.rb, but nowhere in this > output do I have any indication of the location in raven.rb. > > Can you give a quick run-down on ways of "getting out" of a rant > file. rant.abort, rant.abort_at, ruby's exit? What do you > recommend? To allow better understanding, first some more bits on Rant's internals: The "rant" command creates a new Rant::RantApp instance and calls its "run" method, which initiates Rantfile reading, task invocation etc. The "run" method catches any exception, prints information about it to stderr and returns 1 (0 if no exception is thrown). The ususal way to abort Rant would be to raise an Rant::RantAbortException. The method "rant.abort" does just that, and printsan optionally given error message to stderr first. The method "rant.abort_at" is like "rant.abort", except that it takes a hash { :file => "file name", :ln => } as first argument, which it will interpret as error location. Use this method to report wrong usage of a generator, e.g. def Project.rant_gen(rant, ch, args, &block) if args.empty? rant.abort_at(ch, "Project: project name required as first argument") end end If the file "sub.rant", in line number 45, contains the code gen Project Running rant will print the error message: rant: [ERROR] in file `/home/stefan/project/foo/sub.rant', line 45: Project: project name required as first argument rant aborted! If you run rant with the option --trace-abort (not officially supported), the abort/abort_at method will print a full backtrace. (Sadly enough, this backtrace often won't be useful, because an exception thrown from within a task block is catched and a new one thrown => original backtrace lost :( ). To abort from within an Rantfile, I'd recommend to just throw an exception, either of a custom class or a simple StandardError. task :default do # ... raise "some error" end Running this task will give something like: rant: [ERROR] in file `/home/stefan/Rantfile', line 30: some error rant: [ERROR] Task `default' fail. rant aborted! To just print an error/warning message but continue: rant.warn_msg "there is something suspicious" rant.err_msg "something is faulty" Don't do a direct "exit". Regards, Stefan From kevin.burge at systemware.com Thu Dec 22 14:22:35 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Thu, 22 Dec 2005 13:22:35 -0600 Subject: [Rant] Internals question: when to use @rac vs. explicit rant_gen Message-ID: <43AAFCFB.1010609@systemware.com> Hi Stefan, I've noticed that I can do (in a generator): ::Rant::Generators::Task.rant_gen(@rac, @ch, ['setup']) OR @rac.cx.task 'setup' The former is a lot more complicated. Is there a reason that I'd want to do the former over the latter? Is it because it generates a new app as you indicated in the previous post? I also noticed that I can do: @rac.cx.sys.cp or just @rac.sys.cp Which is the preferred method in a custom generator? Why? Thanks, Kevin Please visit http://www.systemware.com/. From langstefan at gmx.at Thu Dec 22 17:19:15 2005 From: langstefan at gmx.at (Stefan Lang) Date: Thu, 22 Dec 2005 23:19:15 +0100 Subject: [Rant] Internals question: when to use @rac vs. explicit rant_gen In-Reply-To: <43AAFCFB.1010609@systemware.com> References: <43AAFCFB.1010609@systemware.com> Message-ID: <200512222319.15973.langstefan@gmx.at> On Thursday 22 December 2005 20:22, Kevin Burge wrote: > Hi Stefan, > > I've noticed that I can do (in a generator): > ::Rant::Generators::Task.rant_gen(@rac, @ch, ['setup']) This corresponds to a "gen Task, 'setup'" from within an Rantfile. > OR > > @rac.cx.task 'setup' This corresponds to a "task 'setup'" from within an Rantfile. > The former is a lot more complicated. Is there a reason that I'd > want to do the former over the latter? Is it because it generates > a new app as you indicated in the previous post? > > I also noticed that I can do: > > @rac.cx.sys.cp > > or just > > @rac.sys.cp > > Which is the preferred method in a custom generator? Why? @rac.cx.sys.cp will stay, @rac.sys is not guaranteed to stay (but it probably will at least some time, since Rant uses it much internally). @rac.cx is the context in which Rantfiles are eval'd. (resolves to something like @rac.cx.instance_eval(File.read("Rantfile")) ) So the code: sys.cp in an Rantfile calls the method sys of @rac.cx. This in turn (currently) delegates to @rac.sys. Regards, Stefan From kevin.burge at systemware.com Fri Dec 23 00:17:05 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Thu, 22 Dec 2005 23:17:05 -0600 Subject: [Rant] sys call to just replace \'s? Message-ID: <43AB8851.4060000@systemware.com> Stefan, Is there a sys call to just replace \'s. I've run into the situation where I have spaces in the name, BUT, I cannot have quotes around it, i.e. for INCLUDE environment variable: INCLUDE="C:\bla bla\etc";.... causes problems (didn't work for me - but might have been something else wrong). Had to be: INCLUDE=C:\bla bla\etc;.... to work. I don't know of a good name. Just a thought, Kevin Please visit http://www.systemware.com/. From langstefan at gmx.at Fri Dec 23 09:26:39 2005 From: langstefan at gmx.at (Stefan Lang) Date: Fri, 23 Dec 2005 15:26:39 +0100 Subject: [Rant] sys call to just replace \'s? In-Reply-To: <43AB8851.4060000@systemware.com> References: <43AB8851.4060000@systemware.com> Message-ID: <200512231526.39584.langstefan@gmx.at> On Friday 23 December 2005 06:17, Kevin Burge wrote: > Stefan, > > Is there a sys call to just replace \'s. I've run into the > situation where I have spaces in the name, BUT, I cannot have > quotes around it, i.e. for INCLUDE environment variable: > > INCLUDE="C:\bla bla\etc";.... > > causes problems (didn't work for me - but might have been something > else wrong). Had to be: > INCLUDE=C:\bla bla\etc;.... > > to work. > > I don't know of a good name. If you just want to remove the quotes from a string, use the String#delete method. pathes = '"C:\bla bla\etc";....' pathes_without_quotes = pathes.delete('"') Or do you want something else? Regards, Stefan From kevin.burge at systemware.com Fri Dec 23 15:43:45 2005 From: kevin.burge at systemware.com (Kevin Burge) Date: Fri, 23 Dec 2005 14:43:45 -0600 Subject: [Rant] sys call to just replace \'s? In-Reply-To: <200512231526.39584.langstefan@gmx.at> References: <43AB8851.4060000@systemware.com> <200512231526.39584.langstefan@gmx.at> Message-ID: <43AC6181.3000701@systemware.com> Hi Stefan, Below is what I added. Although, I'm not sure what the Unix regex is doing. I haven't looked it up yet (nor have I tested my rant extension stuff on Unix). BTW, once I have my stuff mostly working, I'm going to send what I have to you, if for no other reason to provoke ideas (don't care if you use the code or not). I'm trying to make things as "generic" as makes sense within my time constraints. Thanks for all the help, Kevin (my func) # rant/import/sys/slash.rb module Rant module Sys def slash(arg) if arg.respond_to? :to_ary arg.to_ary.map{ |e| slash e }.join(' ') else _slashed arg.to_s end end if Env.on_windows? def _slashed(path) return path.tr("/", "\\") end else def _slashed(path) path.gsub(/(?=\s)/, "\\") end end private :_slashed alias sl slash end end (used like) stlport = t.dep('stlport') ENV['INCLUDE'] = "#{*sys.sl* stlport.c.include.join(';')};#{ENV['INCLUDE']}" ENV['LIB'] = "#{*sys.sl* stlport.c.lib.join(';')};#{ENV['LIB']}" ENV['STLPORT_ROOT'] = *sys.sl* stlport.dir ps: Just reviewing this code made me think you might provide an optional argument for the join character (instead of hardcoding it to ' '). I'm thinking of adding a sys call to make constructing platform independent environment variables easier. (take care of the ':' vs ';' problem, as well as the slashes). Please visit http://www.systemware.com/. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/make-cafe/attachments/20051223/b37e36aa/attachment.htm