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

(Request) Adding ZTI Commands #125

Open
john-craig opened this issue Aug 29, 2024 · 4 comments
Open

(Request) Adding ZTI Commands #125

john-craig opened this issue Aug 29, 2024 · 4 comments
Labels
enhancement New feature or request

Comments

@john-craig
Copy link

It would be nice if there were a way to add user-defined commands or macros to ZTI.

For example, a directory somewhere that a user can just drop-in a Python file, like myfunc.py, and then have that Python script invoked when a user runs the myfunc command in the ZTI REPL.

@najohnsn najohnsn added the enhancement New feature or request label Aug 29, 2024
@najohnsn
Copy link
Member

I think that what is described for this issue is a good idea.

I'll call that an informal way to run scripts.

There is currently a formal way that is not yet documented. Put something like this in your pyproject.toml:

[project.entry-points."zti.commands"]
myfunc = "mymodule:myfunc"

The target function (myfunc() in the above example) should accept a single argument of a command-line string. The function can use the tnz.ati module functions to perform the desired actions.

There are ways other than pyproject.toml to supply entry-points. Any way should do. But that is a requirement to use this formal mechanism.

@john-craig
Copy link
Author

Okay. I've done a bit of research into this. I won't have time to take a crack at it until the holidays. Here's my basic idea for a design:

The default path for user macros will be something like ~/.zti-macros.d, and this can be overriden with the ZTI_MACROS_DIR environment variable.

When the Zti class loads, it will check if the user macros directory exists, and if it does, it will iterate over each file located inside with a .py extension.

These files will be expected to each contain a function with the same name which can accept two arguments, a self and an arg. So, if I had a file mymacro.py, it should contain at least one function with a method signature such as:

def mymacro(self, arg):
  print(arg)

For each Python file in the user macros directory, Zti will import its contents. There's a couple of ways to do this. My preferred approach would be using execfile since it's simple, although it's got some drawbacks. This function just executes the contents of the file unconditionally, so if there was some malicious code in there it would get executed as well. Although I argue that malicious code getting into a user defined macro is an inherent danger of user defined macros.

Anyways once the mymacro function has been imported, Zti will need to make it into a bound method of its own class instance with a name like do_mymacro so that the Cmd class that it uses displays it as an available command in the REPL. This should be doable based on this StackOverflow answer.

@john-craig
Copy link
Author

So I've got some code written up for this, but I have as of yet been unable to build it successfully. I don't see any specific build instructions, so I'm using the command python3.11 -m build. However, the build fails with the following logs:

* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
  - setuptools >= 40.8.0
* Getting build dependencies for sdist...
fatal: No names found, cannot describe anything.
running egg_info
writing tnz.egg-info/PKG-INFO
writing dependency_links to tnz.egg-info/dependency_links.txt
writing entry points to tnz.egg-info/entry_points.txt
writing requirements to tnz.egg-info/requires.txt
writing top-level names to tnz.egg-info/top_level.txt
reading manifest file 'tnz.egg-info/SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'tnz.egg-info/SOURCES.txt'
* Building sdist...
fatal: No names found, cannot describe anything.
running sdist
running egg_info
writing tnz.egg-info/PKG-INFO
writing dependency_links to tnz.egg-info/dependency_links.txt
writing entry points to tnz.egg-info/entry_points.txt
writing requirements to tnz.egg-info/requires.txt
writing top-level names to tnz.egg-info/top_level.txt
reading manifest file 'tnz.egg-info/SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'tnz.egg-info/SOURCES.txt'
running check
creating tnz-0.0.0
creating tnz-0.0.0/tnz
creating tnz-0.0.0/test
creating tnz-0.0.0/tnz.egg-info
copying files to tnz-0.0.0...
copying LICENSE -> tnz-0.0.0
copying README.md -> tnz-0.0.0
copying setup.cfg -> tnz-0.0.0
copying setup.py -> tnz-0.0.0
copying ./tnz/__init__.py -> tnz-0.0.0/./tnz
copying ./tnz/_termlib.py -> tnz-0.0.0/./tnz
copying ./tnz/_util.py -> tnz-0.0.0/./tnz
copying ./tnz/_version.py -> tnz-0.0.0/./tnz
copying ./tnz/ati.py -> tnz-0.0.0/./tnz
copying ./tnz/cp310.py -> tnz-0.0.0/./tnz
copying ./tnz/ditto.py -> tnz-0.0.0/./tnz
copying ./tnz/logging.json -> tnz-0.0.0/./tnz
copying ./tnz/py3270.py -> tnz-0.0.0/./tnz
copying ./tnz/rexx.py -> tnz-0.0.0/./tnz
copying ./tnz/tnz.py -> tnz-0.0.0/./tnz
copying ./tnz/zti.py -> tnz-0.0.0/./tnz
copying test/test_ati.py -> tnz-0.0.0/test
copying test/test_rexx.py -> tnz-0.0.0/test
copying test/test_tnz.py -> tnz-0.0.0/test
copying tnz/__init__.py -> tnz-0.0.0/tnz
copying tnz/_termlib.py -> tnz-0.0.0/tnz
copying tnz/_util.py -> tnz-0.0.0/tnz
copying tnz/_version.py -> tnz-0.0.0/tnz
copying tnz/ati.py -> tnz-0.0.0/tnz
copying tnz/cp310.py -> tnz-0.0.0/tnz
copying tnz/ditto.py -> tnz-0.0.0/tnz
copying tnz/logging.json -> tnz-0.0.0/tnz
copying tnz/py3270.py -> tnz-0.0.0/tnz
copying tnz/rexx.py -> tnz-0.0.0/tnz
copying tnz/tnz.py -> tnz-0.0.0/tnz
copying tnz/zti.py -> tnz-0.0.0/tnz
copying tnz.egg-info/PKG-INFO -> tnz-0.0.0/tnz.egg-info
copying tnz.egg-info/SOURCES.txt -> tnz-0.0.0/tnz.egg-info
copying tnz.egg-info/dependency_links.txt -> tnz-0.0.0/tnz.egg-info
copying tnz.egg-info/entry_points.txt -> tnz-0.0.0/tnz.egg-info
copying tnz.egg-info/requires.txt -> tnz-0.0.0/tnz.egg-info
copying tnz.egg-info/top_level.txt -> tnz-0.0.0/tnz.egg-info
copying tnz.egg-info/SOURCES.txt -> tnz-0.0.0/tnz.egg-info
Writing tnz-0.0.0/setup.cfg
Creating tar archive
removing 'tnz-0.0.0' (and everything under it)
* Building wheel from sdist
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
  - setuptools >= 40.8.0
* Getting build dependencies for wheel...
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
Traceback (most recent call last):
  File "/home/ibmuser/.local/lib/python3.11/site-packages/pyproject_hooks/_in_process/_in_process.py", line 373, in <module>
    main()
  File "/home/ibmuser/.local/lib/python3.11/site-packages/pyproject_hooks/_in_process/_in_process.py", line 357, in main
    json_out["return_val"] = hook(**hook_input["kwargs"])
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ibmuser/.local/lib/python3.11/site-packages/pyproject_hooks/_in_process/_in_process.py", line 134, in get_requires_for_build_wheel
    return hook(config_settings)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/build-env-qnzqkutt/lib64/python3.11/site-packages/setuptools/build_meta.py", line 332, in get_requires_for_build_wheel
    return self._get_build_requires(config_settings, requirements=[])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/build-env-qnzqkutt/lib64/python3.11/site-packages/setuptools/build_meta.py", line 302, in _get_build_requires
    self.run_setup()
  File "/tmp/build-env-qnzqkutt/lib64/python3.11/site-packages/setuptools/build_meta.py", line 503, in run_setup
    super().run_setup(setup_script=setup_script)
  File "/tmp/build-env-qnzqkutt/lib64/python3.11/site-packages/setuptools/build_meta.py", line 318, in run_setup
    exec(code, locals())
  File "<string>", line 29, in <module>
FileExistsError: [Errno 17] File exists: '/tmp/build-via-sdist-uqj_oick/tnz-0.0.0/tnz/_version.py'

ERROR Backend subprocess exited when trying to invoke get_requires_for_build_wheel

Any guidance on how to build this successfully would be helpful. Once I can build and test it successfully I will probably add an example under the examples directory.

@najohnsn
Copy link
Member

najohnsn commented Oct 3, 2024

@john-craig, you may be over-thinking this. If your current working directory is your cloned tnz repo, you should just be able to python3.11 -m tnz.zti to test it - python should look in your current directory first to find the tnz package. There is not much advantage to building it unless you are going to distribute the package.

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

No branches or pull requests

2 participants