Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
only one function is called when two functions are bound to an extension
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  4 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Mihai Rotaru  
View profile  
 More options Oct 10 2012, 2:14 pm
From: Mihai Rotaru <mihai.rot...@gmx.com>
Date: Wed, 10 Oct 2012 11:14:21 -0700 (PDT)
Local: Wed, Oct 10 2012 2:14 pm
Subject: only one function is called when two functions are bound to an extension

Hi,

I'm using waf to create a build script for web projects (github link<https://github.com/mihai-rotaru/bricka>
).

This is what I intend it to do:
- by parsing an HTML file, detect referenced JavaScript files
- for each of these scripts, create a 'minify_js' task
- after all the minification tasks have been performed, create an
  'update_html' task, which would generate an HTML file referencing the
  new, minified JavaScript files.
- after the HTML file was updated, generate a 'compress_html' task.

I already implemented this functionality, in two different waf tools:
minfier.py and htmlcompressor.py. Everything works if I only load one of the
tools; but if I load both, only the last one executes. I mapped both task
generators to html using @extension.

If I try to use @feature, I get an error saying the task generating
functions
need 2 arguments, and only one is provided. By looking at the source code,
it
doesn't seem like feature and extension have different signatures, but I
guess
my Python skills are not enough to grasp these issues.

I attached a file which showcases the issue.

Any pointers would be very much appreciated.

Mihai

  wscript.py
1K Download

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Thomas Nagy  
View profile  
 More options Oct 10 2012, 5:10 pm
From: Thomas Nagy <tnagy1...@gmail.com>
Date: Wed, 10 Oct 2012 23:10:33 +0200
Local: Wed, Oct 10 2012 5:10 pm
Subject: Re: [waf-users 4648] only one function is called when two functions are bound to an extension

The methods bound by @feature have only one argument. The method bound
by @extension use the "source=" attribute.

Yet, the main problem is that it makes little sense to first copy the
file (1) before making changes to it (2). If (2) fails, for example,
if the program is interrupted, then (1) almost certainly has to be
performed again. The best thing is to have it done at once, and to
wrap the code executing the js compresor to prepare its output file:

class minify_base(Task):
   run_str = '${JSCOMPRESS} ${TGT}'
   vars = ... # additional conf.env.XYZ variables to depend on

class minify(minify_base):
   def run(self):
    self.outputs[0].write(self.inputs[0].read(flags='rb'), flags='wb')
    return minify_base.run(self)

@feature('html')
def html_feature(self):
   for node in self.source_list:
     output = node.get_bld()
     # use this when inputs == outputs in
     # the same virtual folder
     if not os.path.abspath(output.abspath()):
         output.sig = None
         output.parent.mkdir()

     inputs = [node]
     tsk = self.create_task('minify', inputs, output)

# user code in the wscript file
bld(features='html', source_list=[node])

Thomas


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Mihai Rotaru  
View profile  
 More options Oct 14 2012, 7:38 am
From: Mihai Rotaru <mihai.rot...@gmx.com>
Date: Sun, 14 Oct 2012 04:38:20 -0700 (PDT)
Local: Sun, Oct 14 2012 7:38 am
Subject: Re: [waf-users 4648] only one function is called when two functions are bound to an extension

Hi Thomas, thank you for taking the time to write an extensive reply.

About using copy, it was only for illustrative purposes; the task really
looks like
this:

class minify_js( Task ):
    run_str = 'java -jar ${closure_compiler} ${jsminifier_options} --js
${SRC} --js_output_file ${TGT}'

I ended up using @feature and setting source_list, but ran into another
problem: "Deadlock detected: check the build order for the tasks", as shown
in
the attached screenshot.

Task order is set as such:

class minify( Task ):
    ...

class update( Task ):
    after = [ 'minify' ]
    ...

class compress( Task ):
    after = [ 'update' ]
    ...

@feature( 'html' )
@after_method( 'generate_minification_tasks' )
def generate_html_compression_tasks( self ):
    ...

By looking at the task id's in the error message, (screenshot attached),  
'compress' is
set to run after 'update', which is expected, but also 'update' is set to
run
after the 'compress' task. I tried manually removing the compress task from
update task's 'after' list, but apparently 'after' lists are populated
after the
@feature methods run, sometime during the build phase.

Why is this behaviour occurring, and how can I prevent it ? Is there a
better
way of piping nodes produced by a tool to another tool, while having the
tools
decoupled ? minifier_tool' needs to work regardless of whether
compressor_tool
is loaded or not.

In Chapter 10 of the waf book, a similar scenario is described - the
`source`
attribute is `extend`ed to contain the outputs of a task. But `source` is
available on task generators created with `bld.program`, which is not the
case
here.

Pseudocode of the approach I used:

minifier_tool:
    parse HTML and produce minification tasks
    if 'compressor_tool' is loaded:
        generate build/<name>.tmp.html
    else
        generate build/<name>.html

compressor_tool:
    if 'minifier_tool' is loaded:
        look for build/<name>.tmp.html
        generate build/<name>.html from build/<name>.tmp.html
    else:
        generate build/<name>.html from <name>.html

I'm also a bit confused about the `html_feature` function in your reply.
1) The `if`'s condition will always evaluate to `true`, because
`os.path.abspath()` alwas seems to return a non-empty string, even when the
parameter is an invalid path or a non-existing file. I'm guessing the
purpose
of this `if` is to check whether the file exists, so it should be
`os.path.exists(...)` ?
2) The `if` block itself - if I understand correctly, signatures are set on
output nodes when a task is successfully executed. Setting it to None should
allow an output node to become an input node for another task ? It doesn't
seem
to work in this case.

I struggled with this deadlock for quite a while, but couldn't figure it
out;
any pointers would be appreciated.

Mihai

  wscript.py
2K Download

  error.png
48K Download

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Thomas Nagy  
View profile  
 More options Oct 14 2012, 8:15 am
From: Thomas Nagy <tnagy1...@gmail.com>
Date: Sun, 14 Oct 2012 14:15:02 +0200
Local: Sun, Oct 14 2012 8:15 am
Subject: Re: [waf-users 4655] only one function is called when two functions are bound to an extension

No, not really.

> Why is this behaviour occurring, and how can I prevent it ? Is there a
> better
> way of piping nodes produced by a tool to another tool, while having the
> tools
> decoupled ? minifier_tool' needs to work regardless of whether
> compressor_tool
> is loaded or not.

You have specified:
t1 runs after t2
t2 runs after t1

You have a cycle here.

Use the approach I gave in the previous email with a single task
object chaining all these operations at once.

If you really want to write all this manually (it will not make the
incremental builds any faster):
* specify all the files as node objects, even the temporary ones
* have your tasks declare the exact inputs/outputs
* remove the after/before constraints (implied by the input/output nodes)

> I'm also a bit confused about the `html_feature` function in your reply.
> 1) The `if`'s condition will always evaluate to `true`, because
> `os.path.abspath()` alwas seems to return a non-empty string, even when the
> parameter is an invalid path or a non-existing file. I'm guessing the
> purpose
> of this `if` is to check whether the file exists, so it should be
> `os.path.exists(...)` ?
> 2) The `if` block itself - if I understand correctly, signatures are set on
> output nodes when a task is successfully executed. Setting it to None should
> allow an output node to become an input node for another task ? It doesn't
> seem
> to work in this case.

The "if" block in question is related to having files in the same
virtual folder. The following structure is ambiguous, because
src/file.name can refer to a file in the source directory or in the
build directory:
src/file.name
build/src/file.name

If you do not want that "if" block, and perhaps use no build folder
(top=out='.'), have your files written to a sub-directory.

Thomas


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »