script/generate undo

Here is small idea I’ve had for sometime that I quickly knocked up yesterday.

Generators are great but we have all had those “Oops!” moments where you realised that what you created was not quite what you wanted to do. Enter script/generate undo….

script/generate model WrongName
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/wrong_name.rb
      create  test/unit/wrong_name_test.rb
      create  test/fixtures/wrong_names.yml
      exists  db/migrate
      create  db/migrate/001_create_wrong_names.rb

.. ….

oops.. didn’t want to do that.

script/generate undo
Undo'ing: model WrongName
    notempty  db/migrate
    notempty  db
          rm  db/migrate/001_create_wrong_names.rb
          rm  test/fixtures/wrong_names.yml
          rm  test/unit/wrong_name_test.rb
          rm  app/models/wrong_name.rb
    notempty  test/fixtures
    notempty  test
    notempty  test/unit
    notempty  test
    notempty  app/models
    notempty  app

Under the hood all it is doing is keeping a log of your generator history (see /log/generator.log). When undo is called it looks at the last log entry and passes it onto script/destroy. Pretty simple stuff but it saves you having to remember what it was that you typed previously.

The patch as it stands is pretty rough and ready. I’m posting this here to get some feedback to gauge whether it’s worth pursuing further.

UPDATE Plugin on the way. I’ve created a new project on Rubyforge for any plugins I make - it should be setup soon. (just waiting for approval)

UPDATE 2: Plugin now released. See this post

Posted by Martin on Thursday, September 20, 2007

Comments

Stephen Bartholomew said on Thursday, September 20, 2007:

I know exactly what you mean - I do this all the time! However, I'm not really sure of the benefit of this over just pressing 'up' in the terminal and changing 'generate' to 'destroy'.

I'm also not sure about using 'generate' to destroy - what about a ./script/undo script? That'd be a lot less to type and would probably be quicker than altering the previous command.

Oh and defiantly a prompt:

Destroy model WrongName? (y/n):

Steve

Martin said on Thursday, September 20, 2007:

Hi Steve,

Thanks for your comment. Glad to see I'm not alone :)

In regards to your points. I'd considered both approaches but I still felt their was some merit in doing it this way.

If you create a separate generator you loose the context of the command.
"script/undo" doesn't really give away what it does where as "script/generate undo" does.

Pressing up to view your past history works up to a point but only for the current session. What happens if you generated something a few days back and want to undo it?

"prompt: Destroy model WrongName? (y/n): " - great! like that.

Jeremy McAnally said on Thursday, September 20, 2007:

@Martin: If you generated the object a few days back, I would hope you can remember what you generated, otherwise running 'undo' would be a surprise, no?

I see the merit of an idea like this, and perhaps you'd want to consider making it a plugin, but I don't think it's going to make it into Rails core since there is already a method for this.

Shalev said on Thursday, September 20, 2007:

Finally!! I've been wishing for something like this forever. Rock on!!!

Wyatt said on Thursday, September 20, 2007:

Yep, I've needed to "undo" a generation many times. I think it would be a candidate for Rails core. The point is the improved interface, not the added functionality. And I don't think you would run 'undo' a few days later. I can't imagine starting the day, getting to a command prompt, and typing 'undo'. Even so, if you did that and it was an oops, just type 'redo'. :)

cn said on Friday, September 21, 2007:

Hey all!
Great tool though subversion can be used to control unwanted changes after a couple of days. Isn't?
I support Martin's idea in terms of more descriptive when running it.
Cheers,

Martin said on Friday, September 21, 2007:

@Jeremy - fair point. Perhaps "a few days back" wasn't the best example to cite in this case. A better example is where you have a more complex script/generate e.g. script/generate controller Article index new create
<br />
@Shalev - thanks!
<br />@cn - true, you could use subversion in this way but really only if you add+commit after each generator action.. and it would take more effort.

<br />
<br />
Thanks all for your comments so far - much appreciated

Mat Schaffer said on Wednesday, September 26, 2007:

Fun idea! But just for the record, bash could possibly come to the rescue assuming the last command you ran was the generate command:

<pre>$ ./script/generate model WrongName
exists app/models/ ...
$ ^generate^destroy
./script/destroy model WrongName ...</pre>

Granted your way is way more gooder. But still. A shell trick worth knowing.

Post a comment


(required, but not displayed)

(optional)