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

Add cli package, allow pack music from command line, not require qt anymore. #105

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Neboer
Copy link

@Neboer Neboer commented Oct 20, 2023

It'll be more convenient for users if this program can support generating dp/rp from the command line. So I add the feature. Users can add musics and change settings from the cli, it can be used without gui, this may make the server users happy.

@bradytheinventor bradytheinventor self-assigned this Oct 25, 2023
Copy link
Contributor

@bradytheinventor bradytheinventor left a comment

Choose a reason for hiding this comment

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

I think this looks pretty good, but I did see some things that should be changed before merging. My comments that start with "Fix:" need to be fixed before I will merge this pull request; comments that start with "Recommend:" don't necessarily need to be fixed but it would be great if you could fix at least some of them. If you disagree with any of my comments I think you can reply to them to start a conversation.

2 suggestions:

  • Add more comments, especially comments explaining why you did what you did. It's easy to see how everything works but the why is sometimes not as clear.
  • Try not to redefine constants that are already defined for you. If you can pull some values from src.definitions it will be much easier to maintain this code.

Copy link
Contributor

Choose a reason for hiding this comment

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

What's the intended way to run the CLI? I can copy this file to the top level and run it with python, but that doesn't feel like the way you intended it to work.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, is the CLI application completely separate from the GUI app? Like if I run the GUI app it won't run any of the CLI code and vice versa?

Copy link
Author

Choose a reason for hiding this comment

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

The intended way to run the CLI is by using it as a Python package. When you're in the root directory of the 'infinite-music-discs' folder, you can run a command like python -m src.cli -g 1.20.2 -f TestMusicEntries.csv -d C:\temp\test_autobuild_output -c to invoke the CLI.

The CLI program depends on modules from the GUI program to function properly. The CLI program relies on the factory class in the src.generator module, which you defined in the original GUI program. However, when the GUI program is running, it doesn't require any code from the CLI package.

I suggest that we collaborate to abstract the code further by separating the GUI part from the core program logic. This will ensure better maintainability. I know the current code abstraction is quite good -- you can start the whole process by passing parameters to the GeneratePackWorker. However, some adjustments may be needed in terms of code organization and package structure. For example, you could consider splitting the code into three packages: core, cli, and gui.

The way you've currently distributed this Python program isn't quite standard. I recommend using setuptools to package and publish the amazing project to PyPi. By using the setuptools, you can define entry points in your program, which precisely control which Python function a binary command runs, making it easier to run and distribute your program.

Thank you for your great work, hope we can work together to make it better.

setting = cli_parser.get_settings()
chdir(cli_parser.output_dir)
worker = HeadlessGeneratePackWorker(musics, setting)
worker.run()
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix: call worker.generate() instead of worker.run() to be consistent with the QT-based worker

from src.cli.types import DPRPVerPair, Settings
from src.definitions import PackFormatsDict, DiscListEntryContents, DiscListContents

from src.cli.logger import *
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix: IIRC import * is bad practice. Explicitly import what you need from your logger module, and consider designing the logger module with importability in mind. Or you could expose a setup() function in the logger module and do something like:

import src.cli.logger as cli_logger
cli_logger.setup()

# package_name='infinite_music_discs', dest_dir='.', compress_output=False)

def __init__(self):
parser = ArgumentParser(prog="mc music packer")
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix: program should be named "imd" or "infinite-music-discs" or something similar, to associate it with the project name

help="a csv file delimited by semicolon, "
"each line of which contains texture_file;track_file;title;internal_name.")
parser.add_argument("-g", "--minecraft-version", type=str, required=True,
help="specify a game version, support 1.14 - 1.20.2",
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix: import PackFormatsDict from src.definitions and parse it to determine the range of supported game versions. Otherwise, someone has to remember to come here and update the help message whenever a new version is added.


def is_legacy_version(mc_ver: str) -> bool:
mc_ver_val: list[int] = [int(i) for i in mc_ver.split(".")]
return mc_ver_val <= [1, 19, 3]
Copy link
Contributor

Choose a reason for hiding this comment

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

Recommend: Reference LEGACY_DP_LATEST_VERSION in src.definitions instead of hardcoding 1.19.3 here. You can compare that pre-defined legacy datapack version against the datapack pack_format you get from get_dp_rp_version

parser.add_argument("-g", "--minecraft-version", type=str, required=True,
help="specify a game version, support 1.14 - 1.20.2",
default="1.20.2")
parser.add_argument("-p", "--use-parallel", action='store_true',
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix: use_parallel implies that the user should set this flag if they want to use the parallel processing, but this flag is connected to the skip_proc setting which will skip the parallel processing if it's set to True. This flag should be renamed to something like proc-serially or proc-sequential so the user knows that setting it will disable the parallel processing.

@@ -0,0 +1,11 @@
from src.cli.cli_parser import CLIParser
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix: copy the shebang from main.pyw so you can run the CLI directly:

#!/usr/bin/env python3

self._progress += 1


def generate(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Recommend: Catch IMDException here and sample its status (which will be of type Status from src.definitions) to print the appropriate helpful message from StatusMessageDict so the user isn't guessing what a particular custom exception means. If you want, you could also reraise the IMDException you caught to crash the program afterward so the user gets a stack trace.

help="package name")
parser.add_argument("-o", "--output-dir", type=str, default=".", help="the output directory of rp&dp.")
parser.add_argument("-z", "--compress-output", action='store_true', help="compress output pack to zip")
parser.add_argument("-c", "--cover-image", type=str, default='', help="cover image of the pack")
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix: the CLI throws an exception if you don't set the cover-image flag. Are you changing the value somewhere between here and when it's used in the generator? Because if the pack.png path is set to an empty string like you've done here, it should work without throwing an exception.

@Neboer
Copy link
Author

Neboer commented Oct 30, 2023

Thank you for your review and reply! I am working on it.

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.

2 participants