Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New export command (issue #435) #2510

Merged
merged 27 commits into from
Jun 11, 2017
Merged

Conversation

SpirosChadoulos
Copy link
Contributor

Could you help me with the errors that I am getting?

@mention-bot
Copy link

@SpirosChadoulos, thanks for your PR! By analyzing the history of the files in this pull request, we identified @sampsyo, @pkess and @geigerzaehler to be potential reviewers.

@@ -1450,7 +1450,7 @@ def modify_func(lib, opts, args):

# move: Move/copy files to the library or a new base directory.

def move_items(lib, dest, query, copy, album, pretend, confirm=False):
def move_items(lib, dest, query, copy, album, pretend, confirm=False, export):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This:

ERROR: Failure: SyntaxError (non-default argument follows default argument (commands.py, line 1453))

Means that export must either come before confirm or have a default value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still have an error at line 1483 with item

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please be a little more specific? I can't quite find the error you're talking about; maybe you can include the error text?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unresolved reference 'item' less... (Ctrl+F1)
This inspection detects names that should resolve but don't. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases. Top-level and class-level items are supported better than instance items.

lambda o: show_path_changes(
[(o.path, o.destination(basedir=dest))]))
if export:
util.copy(item.path, item.destination(basedir=dest))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the line you're referring to? If so, item is indeed an undefined variable. You will need to assign to it before using it. Did you mean obj? But obj might be an item or an album, so you may need to check which it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the line I'm refering to util.copy(item.path, item.destination(basedir=dest))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sampsyo how should I handle item ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned above, that variable is not defined. I suggested that you might have intended to use obj instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used it and I got no errors but appveyor and travis failed..Could you help me with that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should only care about the failures, not the errors right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Errors are important too—that's when an unexpected exception is thrown.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed something weird. AppVeyor and Travis say that I have 4 failures but when I run the command nosetests locally I get 3 failures and when I run the command python setup.py test locally I get 7 failures. How is that possible? Also in the local tests, no matter what I change in my if export statement the failures remain exactly the same.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's odd! Which test do the two runs disagree on?

To help debug the failures, sometimes it can be helpful to try deleting the code you added and confirming that all the tests pass, as expected. Then you can add changes in one at a time to see when things break.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deleted all the code I added to this file and the failures are still the same.. That's really weird..

@SpirosChadoulos
Copy link
Contributor Author

@sampsyo I fixed some issues and now my code passes the tests. Is everything okay?

@sampsyo
Copy link
Member

sampsyo commented Apr 19, 2017

Yes; this looks great! Thank you for sorting out the various problems! ✨

To make this ready to merge, we'll need at least an update to the docs (to describe the new option) and a changelog entry. It would also be super nice to have a unit test, which shouldn't be too hard—it can be pretty similar to a copy n' paste of one of the existing tests for the move command, but it should check that the item's path in the database doesn't change.

@SpirosChadoulos
Copy link
Contributor Author

Okay I'll do these the following days.

@SpirosChadoulos
Copy link
Contributor Author

Should I copy n' paste the MoveTest class (test_ui.py)??

@sampsyo
Copy link
Member

sampsyo commented Apr 29, 2017

Yeah, that seems like a great place to start!

@SpirosChadoulos
Copy link
Contributor Author

@sampsyo I need some help with the errors I am getting because it is the first time I am writting a test for beets

@sampsyo
Copy link
Member

sampsyo commented May 1, 2017

Cool! Happy to help, but to make this easy, would you mind pasting the specific errors you have questions about and give a little context? Then I can totally help with some answers.

@SpirosChadoulos
Copy link
Contributor Author

SpirosChadoulos commented May 3, 2017

All my errors are about no such filed or directory errors.. Maybe I've done something wrong that affects all of them.

@sampsyo
Copy link
Member

sampsyo commented May 3, 2017

OK! As usual, though, your part of the bargain is to lay out the problem clearly so your collaborators have a hope of being helpful. Specifically:

  1. Copy and paste the error message.
  2. Refer (perhaps link) to the part of the code where you think it's coming from.
  3. Give your theories so far about what might be going wrong.
  4. Ask specific questions about where you're confused.

@SpirosChadoulos
Copy link
Contributor Author

https://travis-ci.org/beetbox/beets/jobs/227346244#L887-L901

Here the error I get is AttributeError: no such field 'destination', but I can't figure out what this means and where this field is.
Also, I did what you told me and I copy n pasted the MoveTest in order to create the ExportTest and I added export=True. I noticed that the test methods that fail in the new class are those that go through the new code I added in commands.py(which you told me was okay). I can't figure out if the test methods need some tweaking or if the main code is the problem and the tests fail because the new feature isn't doing what it is supposed to do.

@sampsyo
Copy link
Member

sampsyo commented May 4, 2017

Ah, I see—thanks for clarifying!

The problem here is that obj might be an Album object or it might be an Item object. On this line, your code assumes it's an Item—only Items have a destination method. You'll need an if album: condition, just like the one earlier in the method, to iterate over the album's items in album mode.

@SpirosChadoulos
Copy link
Contributor Author

Perfect, that was very helpfull! I will do exactly that.Thanks a lot for the help!!

@SpirosChadoulos
Copy link
Contributor Author

@sampsyo https://travis-ci.org/beetbox/beets/jobs/228798906#L887-L899
TypeError: copy() missing 1 required positional argument: 'dest'..Why is this happening? My copy function has a dest parameter. Didn't I did what you told me above the right way?

for obj in objs for item in obj.items()])
else:
util.copy([(obj.path, obj.destination(basedir=dest))
for obj in objs])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, you're just passing one argument—a list, produced by a list comprehension—to the copy function. Maybe you mean something like:

for item in objs:
    util.copy(item.path, item.destination...)

and then again with for item in obj.items().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://travis-ci.org/beetbox/beets/jobs/228909615#L898
To which file is it refering to? Didn't I do what you explained right?

@sampsyo
Copy link
Member

sampsyo commented May 8, 2017

Hmm; yes, that's not showing you the precise traceback. One way to test a theory is to run the test locally and add print statements around where you think the failure might be occurring. That can help you narrow down both where things are going wrong and why.

@SpirosChadoulos
Copy link
Contributor Author

I did some research and some testing and I think that the tests are okay and the problem is the util.copy(item.path, item.destination(basedir=dest)) call, especially the 2 parameters the method gets.I also think that the problem is the destination path (2nd parameter) and not the first one. Any thoughts and suggestions?

@sampsyo
Copy link
Member

sampsyo commented May 9, 2017

Hmm; what do you think the problem is there? That call looks (to me) like it copies the file from its original location to the path where it needs to go. Seems correct, I guess?

@SpirosChadoulos
Copy link
Contributor Author

But if this is the case why do we get this error? https://travis-ci.org/beetbox/beets/jobs/229424482#L983
Note that this error occurs just when self._move() is executed in our tests and not when the assertions happen.

@sampsyo
Copy link
Member

sampsyo commented May 11, 2017

Good question. Since the error says this:

beets.util.FilesystemError: No such file or directory while copying /tmp/tmppqnmxzp9/testlibdir/srcfile to /tmp/tmppqnmxzp9/testotherdir/the artist/the album/02 full

that can actually mean either the source or the destination doesn't exist. I suspect it's the destination. Specifically, the destination path comes from here:

self.otherdir = os.path.join(self.temp_dir, b'testotherdir')

but that directory is never created!

The solution is probably to add code to the export functionality to create parent directories. For example, you can see that the move method on Item uses this code:

# Create necessary ancestry for the move.
util.mkdirall(dest)

to make sure that the destination directory will exist.

@SpirosChadoulos
Copy link
Contributor Author

I fixed it!! I think it works fine now. What should I do now in order to merge this pull request?

Copy link
Member

@sampsyo sampsyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay yay yay! That's great! 🎉 ✨

I have a few code suggestions above, where the two themes are removing redundancy and thinking carefully about the naming of test cases.

There's one last thing we'll need in order to merge: documentation! Can you please add a brief description of the new flag to docs/reference/cli.rst under the move command?

@@ -1479,6 +1480,19 @@ def move_items(lib, dest, query, copy, album, pretend, confirm=False):
show_path_changes([(obj.path, obj.destination(basedir=dest))
for obj in objs])
else:
if export:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please clean up this extra blank space, and instead add a brief comment about what's going on here?

for obj in objs:
# Create necessary ancestry for the copy.
util.mkdirall(obj.destination(basedir=dest))
util.copy(obj.path, obj.destination(basedir=dest))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since these two lines are identical to the above, a "helper function" to encapsulate them would help with maintainability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean lines 1489&1490 and 1494&1495?? They are not exactly identical, one uses item and the other uses obj. Do you want me to create a helper function that takes as a parameter either item or obj?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly.

test/test_ui.py Outdated
#
# self.run_command('--config', cli_config_path,
# '--config', cli_overwrite_config_path, 'test')
# self.assertEqual(config['anoption'].get(), 'cli overwrite')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks like it's just unrelated noise—would you mind reverting it?

test/test_ui.py Outdated
self.i.load()
self.assertTrue(b'testlibdir' in self.i.path)
self.assertExists(self.i.path)
self.assertExists(self.itempath)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Export mode ignores the copy flag, so this test is probably redundant and can be removed. (The album versions with this flag are the same way.)

test/test_ui.py Outdated
commands.move_items(self.lib, dest, query, copy, album,
pretend, export)

def test_move_item(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_move_item no longer really accurately describes what's going on here. Maybe you mean test_export_item? (And move -> export in other test names below?)

test/test_ui.py Outdated
self.i.load()
self.assertTrue(b'testlibdir' in self.i.path)
self.assertExists(self.i.path)
self.assertNotExists(self.itempath)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The move flag is also ignored, right? So this test seems similarly redundant.

@SpirosChadoulos
Copy link
Contributor Author

@sampsyo Are all of your change requests covered? Do you want anything else before I write the docs?

@sampsyo
Copy link
Member

sampsyo commented May 13, 2017

Yes; this all looks great! I think the last missing piece is the docs.

@SpirosChadoulos
Copy link
Contributor Author

Ready to merge?

@SpirosChadoulos
Copy link
Contributor Author

SpirosChadoulos commented May 15, 2017

@sampsyo Sorry for tagging you but I thought you might have missed my comment..Are we ready to merge?

@sampsyo
Copy link
Member

sampsyo commented May 16, 2017

Hi! Sorry, I did see your comment—things look good, and it's on my to-do list to do a complete review and merge.

@SpirosChadoulos
Copy link
Contributor Author

Okay thanks a lot!!

The calls didn't match up with the parameter order.
The old tests were wrong but the incorrectness was hidden by the incorrect
parameter passing fixed in the previous commit. Now we actually test that the
item's path did not change.
@sampsyo sampsyo merged commit ca4f96e into beetbox:master Jun 11, 2017
sampsyo added a commit that referenced this pull request Jun 11, 2017
sampsyo added a commit that referenced this pull request Jun 11, 2017
@sampsyo
Copy link
Member

sampsyo commented Jun 11, 2017

Sorry I missed the May deadline! I finally had a moment to give this the attention it deserved. I simplified a few things, revised the tests, fixed some parameter-passing issues, and merged. ✨ Thank you for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants