On Sun, May 31, 2020 at 12:50 AM Craig Russell <apache....@gmail.com> wrote:
>
> So now I just need an example of svn code executed with no update block and 
> some code executed inside the update block.

Publishing minutes after a board meeting involves a number of updates
to different svn repositories:

https://github.com/apache/whimsy/blob/master/www/board/agenda/views/actions/publish.json.rb

This example shows issuing svn commands within the block.

A few things to note:

1) If the block only takes one argument, then it is provided with a
tmpdir only.  It is up to you to do any and all svn commands except
for the final commit.

2) While you can spawn any command within the block (svn or otherwise)
any way you like, wunderbar provides an _.system method that will
capture the stdout and stderr and add it to the transcript provided in
the response back to the client.

3) As sebb points out, a full temporary checkout of a directory like
https://svn.apache.org/repos/private//documents would be impractical.
Perhaps instead of emeritus-rejoined, emeritus-requests-received, and
emeritus-requests-rescinded directories that are sister directories to
the emeritus directory, there could be a single emeritus directory
which contains a number of subdirectories.  An example of such a
structure is https://svn.apache.org/repos/private/financials/Bills.

> Thanks,
> Craig

- Sam Ruby

> >> It looks like the code in memstat.json.rb is a co-routine with the code in 
> >> lib...svn.rb, where the svn.rb code opens the members_txt file, passes 
> >> control to the code in memstat.json.rb to update the members.txt data and 
> >> when that's done, svn.rb takes over and completes the commit operation.
> >>
> >> So now we are in the _svn.update do block and need to execute an svn mv 
> >> command.
> >>
> >>  # determine where to put the entry
> >>  if @action == 'emeritus'
> >>    index = text.index(/^\s\*\)\s/, text.index(/^Emeritus/))
> >>    entry.sub! %r{\s*/\* deceased, .+?\*/},'' # drop the deceased comment 
> >> if necessary
> >>
> >> dir = ASF:SVN:find!('documents') # this is the root directory
> >> from = 'emeritus-requests-received'
> >> to = 'emeritus'
> >> # execute the code to move the file from one directory to another
> >> svn.move(dir, from, to, @emeritus-file-name)
> >>
> >> Over to you...
> >>
> >> Craig
> >>>
> >>>> Thanks,
> >>>> Craig
> >>>>
> >>>>> On May 26, 2020, at 10:37 PM, Sam Ruby <ru...@intertwingly.net> wrote:
> >>>>>
> >>>>> On Wed, May 27, 2020 at 12:38 AM Craig Russell <apache....@gmail.com> 
> >>>>> wrote:
> >>>>>>
> >>>>>> I'm not having any success understanding the memstat.json.rb code:
> >>>>>> # update members.txt
> >>>>>> _svn.update members_txt, message: message do |dir, text|
> >>>>>>
> >>>>>> Does this call the code in svn.rb?
> >>>>>>  def self.update(path, msg, env, _, options={})
> >>>>>>
> >>>>>> I guess I'm not so good at reading the ruby...
> >>>>>
> >>>>> The definition of _svn is here:
> >>>>>
> >>>>> https://github.com/apache/whimsy/blob/4e89c0e2a1069fbe7b6f4472722836c12a846e6c/www/roster/models/svn.rb#L29
> >>>>>
> >>>>> It does indeed call the update method in lib/whimsy/asf/svn.rb.
> >>>>>
> >>>>> As an aside, the JavaScript module system, like Python, requires each
> >>>>> module to explicitly import what it needs, this makes it easier to
> >>>>> identify where the definition of a given method is.  Enough so that
> >>>>> IDEs like VSCode allow you to control-click (or command-click on
> >>>>> MacOS) on a function call and it will take you to its definition.
> >>>>>
> >>>>>> I'm more used to the read/update/write/repeat/commit style of database 
> >>>>>> access, where the memstat.json.rb would
> >>>>>> - read the members.txt
> >>>>>> - using the action (emeritus, active, deceased, request_emeritus, 
> >>>>>> rescind_emeritus) edit the members.txt
> >>>>>> - move the file from emeritus-requests-received to emeritus (emeritus)
> >>>>>> - remove the file from emeritus-requests-received (rescind)
> >>>>>> - svn commit the changes
> >>>>>
> >>>>> That's indeed how it was done on the original whimsy_vm (effectively
> >>>>> whimsy_vm1).  It routinely would get 'wedged' (that's the term you
> >>>>> used at the time) and I would have to ssh into that machine, run a
> >>>>> combination of svn reverts and svn cleanups until the directory was
> >>>>> clean again, then the operation could be attempted again.  Perhaps you
> >>>>> might remember this happening.
> >>>>>
> >>>>> The second iteration creates a fresh checkout of the directory in
> >>>>> question, runs your block against that directory and commits the
> >>>>> results.  Should the directory get 'wedged', the operation will fail,
> >>>>> but no matter what happens that temporary directory will be thrown
> >>>>> away, so the operation can be attempted again.  This is the code you
> >>>>> are now looking at.
> >>>>>
> >>>>> The third iteration (present only in the Ruby board agenda tool at the
> >>>>> moment) takes this a step further and retries operations.  Unlike the
> >>>>> secretary workbench and even to some extent the roster tool, the board
> >>>>> agenda tool is often used by multiple people concurrently, often with
> >>>>> changes to the same lines (most notably, the approval lines) on the
> >>>>> day before the board meeting.  If a commit fails, a sleep for a random
> >>>>> time occurs and the operation is attempted again with a fresh checkout
> >>>>> and re-invoking the same block.  I even have a test tool that
> >>>>> simulates 9 directors committing at once:
> >>>>>
> >>>>> https://github.com/apache/whimsy/blob/master/www/board/agenda/test/stresstest.rb
> >>>>>
> >>>>> The fourth iteration (currently being prototyped in
> >>>>> JavaScript/Node.js) is intended to incorporate the above retry logic
> >>>>> in production, but will also employ different strategies in
> >>>>> development and test.
> >>>>>
> >>>>> In the fullness of time, all of this should hopefully converge.
> >>>>> Meanwhile, build on the strategy that you feel most comfortable with,
> >>>>> and over time it will likely be rewritten as new strategies emerge.
> >>>>>
> >>>>>> Craig
> >>>>>
> >>>>> - Sam Ruby
> >>>>>
> >>>>>>> On May 26, 2020, at 6:09 PM, Sam Ruby <ru...@intertwingly.net> wrote:
> >>>>>>>
> >>>>>>> On Tue, May 26, 2020 at 8:44 PM Craig Russell <apache....@gmail.com> 
> >>>>>>> wrote:
> >>>>>>>>
> >>>>>>>> Sorry for not being clear. In the whimsy/lib there is a helper file 
> >>>>>>>> svn.rb that has a number of functions including update(path, msg, 
> >>>>>>>> env, _, options={}) that is used by roster memstat.json.rb and it 
> >>>>>>>> contains the commit in the function.
> >>>>>>>>
> >>>>>>>> I did not see a move or remove function in svn.rb. Should I be 
> >>>>>>>> looking somewhere else for examples of svn commands? Should I look 
> >>>>>>>> at adding move and remove functions to svn.rb?
> >>>>>>>
> >>>>>>> Not currently.
> >>>>>>>
> >>>>>>> I'm convinced that the right way forward is for all svn access to be
> >>>>>>> done via what you are calling helpers.  This not only makes the code
> >>>>>>> cleaner
> >>>>>>>
> >>>>>>> Ruby: File.read(File.join(ASF::SVN['foundation_board'],
> >>>>>>> 'board_agenda_06_17.txt')
> >>>>>>> JS: Board.read('board_agenda_06_17.txt')
> >>>>>>>
> >>>>>>> ... it also enables redirecting all commits to a local repository in
> >>>>>>> development, and mocking the repository in test.
> >>>>>>>
> >>>>>>> In any case, all of the svn operations should be updated to make use
> >>>>>>> of --password-from-stdin where available, which unfortunately won't be
> >>>>>>> until whimsy-vm is upgraded to Ubuntu 20.04.
> >>>>>>>
> >>>>>>>> Thanks,
> >>>>>>>> Craig
> >>>>>>>
> >>>>>>> - Sam Ruby
> >>>>>>>
> >>>>>>>>> On May 26, 2020, at 5:23 PM, Sam Ruby <ru...@intertwingly.net> 
> >>>>>>>>> wrote:
> >>>>>>>>>
> >>>>>>>>> On Tue, May 26, 2020 at 8:15 PM Craig Russell 
> >>>>>>>>> <apache....@gmail.com> wrote:
> >>>>>>>>>>
> >>>>>>>>>> The cancel button now works (thanks, Sam). On to the server side.
> >>>>>>>>>>
> >>>>>>>>>> To implement active->emeritus we need to update members.txt and 
> >>>>>>>>>> move the request file from emeritus-requests-received to emeritus.
> >>>>>>>>>>
> >>>>>>>>>> - Is there an svn function to move a file from one directory to 
> >>>>>>>>>> another?
> >>>>>>>>>
> >>>>>>>>> http://svnbook.red-bean.com/en/1.6/svn.ref.svn.c.move.html
> >>>>>>>>>
> >>>>>>>>>> - Is there a way to have both things done in the same svn commit?
> >>>>>>>>>
> >>>>>>>>> If both the source and target have a common parent, do the svn 
> >>>>>>>>> commit
> >>>>>>>>> from that parent.
> >>>>>>>>>
> >>>>>>>>> When the secretary files board minutes,
> >>>>>>>>> 1) the minutes are moved to the website.  Those source and target
> >>>>>>>>> don't share a common parent, so two commits are required.
> >>>>>>>>> 2) the agenda is moved to a subdirectory.  The source and target 
> >>>>>>>>> share
> >>>>>>>>> a common parent, so one commit suffices.
> >>>>>>>>>
> >>>>>>>>>> To implement request_emeritus_status we need to create an email. 
> >>>>>>>>>> Easy..
> >>>>>>>>>>
> >>>>>>>>>> To implement rescind_emeritus_request we need to svn rm the file 
> >>>>>>>>>> from emeritus-requests-received.
> >>>>>>>>>>
> >>>>>>>>>> - Is there an svn function to delete a file?
> >>>>>>>>>
> >>>>>>>>> http://svnbook.red-bean.com/en/1.6/svn.ref.svn.c.delete.html
> >>>>>>>>>
> >>>>>>>>>> Thanks,
> >>>>>>>>>> Craig
> >>>>>>>>>
> >>>>>>>>> - Sam Ruby
> >>>>>>>>>
> >>>>>>>>>>> On May 26, 2020, at 3:20 PM, Craig Russell <apache....@gmail.com> 
> >>>>>>>>>>> wrote:
> >>>>>>>>>>>
> >>>>>>>>>>> Here are the files.
> >>>>>>>>>>> <main.js.rb><memstat.js.rb>
> >>>>>>>>>>> And the console logs:
> >>>>>>>>>>> [Log]  dblclick event.currentTarget: [object HTMLDivElement] 
> >>>>>>>>>>> (app.js, line 3268)
> >>>>>>>>>>> [Log]  dblclick event.currentTarget.dataset: [object 
> >>>>>>>>>>> DOMStringMap] (app.js, line 3269)
> >>>>>>>>>>> [Log]  dblclick event.currentTarget.dataset.edit: memstat 
> >>>>>>>>>>> (app.js, line 3270)
> >>>>>>>>>>> [Log] canx called from Cancel button (app.js, line 4021)
> >>>>>>>>>>> [Log] event: [object MouseEvent] parent: [object 
> >>>>>>>>>>> HTMLButtonElement] (app.js, line 4024)
> >>>>>>>>>>> [Log] parent: [object HTMLButtonElement] memstatElement: [object 
> >>>>>>>>>>> HTMLDivElement] (app.js, line 4025)
> >>>>>>>>>>> [Log] preventing default (app.js, line 4026)
> >>>>>>>>>>> [Log] memstatElement.dataset: [object DOMStringMap] (app.js, line 
> >>>>>>>>>>> 4027)
> >>>>>>>>>>> [Log] memstatElement.dataset.edit: memstat (app.js, line 4028)
> >>>>>>>>>>> [Log]  submit event: [object Object] (app.js, line 3291)
> >>>>>>>>>>> [Log]  submit target: [object HTMLButtonElement] (app.js, line 
> >>>>>>>>>>> 3292)
> >>>>>>>>>>> [Log]  submit parent: [object HTMLButtonElement] (app.js, line 
> >>>>>>>>>>> 3293)
> >>>>>>>>>>> [Log]  submit parent.getAttribute(data_cancel): null (app.js, 
> >>>>>>>>>>> line 3294)
> >>>>>>>>>>> [Log]  submit target.dataset_edit: undefined (app.js, line 3295)
> >>>>>>>>>>> [Log]  submit target.dataset: [object DOMStringMap] (app.js, line 
> >>>>>>>>>>> 3296)
> >>>>>>>>>>> [Log]  submit target.dataset.edit: undefined (app.js, line 3297)
> >>>>>>>>>>> [Log]  submit memstatElement.dataset.edit: memstat (app.js, line 
> >>>>>>>>>>> 3298)
> >>>>>>>>>>> [Log]  submit cancel_submit: null (app.js, line 3300)
> >>>>>>>>>>>
> >>>>>>>>>>>> On May 26, 2020, at 2:19 PM, Sam Ruby <ru...@intertwingly.net> 
> >>>>>>>>>>>> wrote:
> >>>>>>>>>>>>
> >>>>>>>>>>>> On Tue, May 26, 2020 at 1:32 AM Craig Russell 
> >>>>>>>>>>>> <apache....@gmail.com> wrote:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> But calling preventDefault on the event doesn't appear to do 
> >>>>>>>>>>>>> anything. It still calls the POST behavior, and does not cause 
> >>>>>>>>>>>>> the inline edit menu to disappear. And setting the edit 
> >>>>>>>>>>>>> function to nil doesn't do anything either.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Maybe there is something else that I need to do?
> >>>>>>>>>>>>
> >>>>>>>>>>>> I'll admit that I'm not clear on what you are trying to 
> >>>>>>>>>>>> accomplish,
> >>>>>>>>>>>> but apparently the problem here is that there is another piece 
> >>>>>>>>>>>> of code
> >>>>>>>>>>>> that attaches an event handler (and calls preventDefault):
> >>>>>>>>>>>>
> >>>>>>>>>>>> https://github.com/apache/whimsy/blob/d3246f107a35f4d989350f4c1ca64366c98ef423/www/roster/views/person/main.js.rb#L341
> >>>>>>>>>>>>
> >>>>>>>>>>>> Perhaps it would be best to add an attribute to the button, and 
> >>>>>>>>>>>> have
> >>>>>>>>>>>> the submit method remove the buttons and exit early:
> >>>>>>>>>>>>
> >>>>>>>>>>>> diff --git a/www/roster/views/person/main.js.rb
> >>>>>>>>>>>> b/www/roster/views/person/main.js.rb
> >>>>>>>>>>>> index 1b5ffdb8..f498489f 100644
> >>>>>>>>>>>> --- a/www/roster/views/person/main.js.rb
> >>>>>>>>>>>> +++ b/www/roster/views/person/main.js.rb
> >>>>>>>>>>>> @@ -355,6 +355,12 @@ class Person < Vue
> >>>>>>>>>>>> form = jQuery(event.currentTarget).closest('form')
> >>>>>>>>>>>> target = event.target
> >>>>>>>>>>>>
> >>>>>>>>>>>> +    # if button is a cancel button, don't submit and remove 
> >>>>>>>>>>>> buttons
> >>>>>>>>>>>> +    if target.getAttribute('data-cancel')
> >>>>>>>>>>>> +      @edit = null
> >>>>>>>>>>>> +      return
> >>>>>>>>>>>> +    end
> >>>>>>>>>>>> +
> >>>>>>>>>>>> # serialize form
> >>>>>>>>>>>> formData = form.serializeArray();
> >>>>>>>>>>>>
> >>>>>>>>>>>> diff --git a/www/roster/views/person/memstat.js.rb
> >>>>>>>>>>>> b/www/roster/views/person/memstat.js.rb
> >>>>>>>>>>>> index 39367c40..e8d3d318 100644
> >>>>>>>>>>>> --- a/www/roster/views/person/memstat.js.rb
> >>>>>>>>>>>> +++ b/www/roster/views/person/memstat.js.rb
> >>>>>>>>>>>> @@ -35,6 +35,8 @@ class PersonMemberStatus < Vue
> >>>>>>>>>>>>          _button.btn.btn_primary 'move to emeritus',
> >>>>>>>>>>>>            name: 'action', value: 'emeritus'
> >>>>>>>>>>>>        end
> >>>>>>>>>>>> +
> >>>>>>>>>>>> +              _button.btn.btn_secondary 'cancel', data_cancel: 
> >>>>>>>>>>>> true
> >>>>>>>>>>>>      end
> >>>>>>>>>>>>    end
> >>>>>>>>>>>>   end
> >>>>>>>>>>>>
> >>>>>>>>>>>> - Sam Ruby
> >>>>>>>>>>>
> >>>>>>>>>>> Craig L Russell
> >>>>>>>>>>> c...@apache.org
> >>>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> Craig L Russell
> >>>>>>>>>> c...@apache.org
> >>>>>>>>>>
> >>>>>>>>
> >>>>>>>> Craig L Russell
> >>>>>>>> c...@apache.org
> >>>>>>>>
> >>>>>>
> >>>>>> Craig L Russell
> >>>>>> c...@apache.org
> >>>>>>
> >>>>
> >>>> Craig L Russell
> >>>> c...@apache.org
> >>>>
> >>
> >> Craig L Russell
> >> c...@apache.org
>
> Craig L Russell
> c...@apache.org
>

Reply via email to