Repository: conan-io/conan
Pull request #17398 (2024-12-01 19:29:30)

[Feature] Added features to the premake cli wrapper
Changelog: Feature: 
Addes features to the preamke5 cli wrapper:
- premake5 action (vsXXXX or gmake2) gets auto-detected in constructor but can be changed via public member. 
- The path and filename to the root `premake5.lua` file is changeable
- Custom premake5 command line arguments can be specified via public dict `arguments`

Thees changes are required in order to fully support calling the premake5 executable. This lays the foundation for a `PremakeToolchain`. 

This is one of the key components of #14724 but in a modified version. I plan to add the other main feature (build) as a follow up under `PremakeToolchain`. As I have understand as long as premake does not have a build feature. Which it does not have. It should be "chained" as a Toolchain that would utilize the cli wrapper and the platform specific build system wrapper (`MSBuild` or a direct `make` call) other than being integrated in the cli wrapper. Correct?

Would we need to add any test coverage other than the "basic" test @memsharded added? Like checking that arguments work etc.)

Currently there is (as previously discussed) no documentation for the whole premake feature set. I assume we will stay like this for now. I would however recommend to document the feature as soon as premake is feature complete.

- [x] Refer to the issue that supports this Pull Request.
- [x] If the issue has missing info, explain the purpose/use case/pain/need that covers this Pull Request.
- [x] I've read the [Contributing guide](https://github.com/conan-io/conan/blob/develop2/.github/CONTRIBUTING.md).
- [x] I've followed the PEP8 style guides for Python code.
- [ ] I've opened another PR in the Conan docs repo to the ``develop`` branch, documenting this one.


memsharded: Hi @Ohjurot 

It would be nice to get this merged, do you think you will be able to add a couple of small tests? 
If not let me know and I will try to add them myself. Thanks!
Ohjurot: Hi @memsharded 
Sorry for the delays. I’m currently quit constraint in time. So I would be really grateful if you could help me out with the tests. I would also appreciate a quit reference to the „ideal“ tests the full integration would need. The I can directly work on that in the next contribution step, when I have time. 
Thank you! 

Patch:
diff --git a/conan/tools/premake/premake.py b/conan/tools/premake/premake.py
index b685c77dd..69765dd3c 100644
--- a/conan/tools/premake/premake.py
+++ b/conan/tools/premake/premake.py
@@ -1,17 +1,40 @@
+# Source: https://learn.microsoft.com/en-us/cpp/overview/compiler-versions?view=msvc-170
+PREMAKE_VS_VERSION = {
+    '190': '2015',
+    '191': '2017',
+    '192': '2019',
+    '193': '2022',
+    '194': '2022',  # still 2022
+}
+
+
 class Premake:
+    """
+    Premake cli wrapper
+    """
+
     def __init__(self, conanfile):
         self._conanfile = conanfile
 
-    # automatically chooses premake action based on used compiler
-    def configure(self):
+        self.action = None              # premake5 action to use (Autogenerated)
+        self.luafile = 'premake5.lua'   # Path to the root (premake5) lua file
+        # (key value pairs. Will translate to "--{key}={value}")
+        self.arguments = {}             # https://premake.github.io/docs/Command-Line-Arguments/
+
         if "msvc" in self._conanfile.settings.compiler:
-            _visuals = {'190': '2015',
-                        '191': '2017',
-                        '192': '2019',
-                        '193': '2022',
-                        '194': '2023'}
-            version = _visuals.get(str(self._conanfile.settings.compiler.version))
-            premake_command = f"premake5 vs{version}"
-            self._conanfile.run(premake_command)
+            msvc_version = PREMAKE_VS_VERSION.get(str(self._conanfile.settings.compiler.version))
+            self.action = f'vs{msvc_version}'
         else:
-            self._conanfile.run("premake5 gmake2")
+            self.action = 'gmake2'
+
+    @staticmethod
+    def _expand_args(args):
+        return ' '.join([f'--{key}={value}' for key, value in args.items()])
+
+    def configure(self):
+        premake_options = dict()
+        premake_options["file"] = self.luafile
+
+        premake_command = f'premake5 {self._expand_args(premake_options)} {self.action} ' \
+                          f'{self._expand_args(self.arguments)}'
+        self._conanfile.run(premake_command)


Test patch:
diff --git a/test/integration/toolchains/premake/test_premake.py b/test/integration/toolchains/premake/test_premake.py
new file mode 100644
index 000000000..a7d8bce37
--- /dev/null
+++ b/test/integration/toolchains/premake/test_premake.py
@@ -0,0 +1,24 @@
+import textwrap
+
+from conan.test.utils.tools import TestClient
+
+
+def test_premake_args():
+    c = TestClient()
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.premake import Premake
+
+        class Pkg(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            def run(self, cmd, *args, **kwargs):
+                self.output.info(f"Running {cmd}!!")
+            def build(self):
+                premake = Premake(self)
+                premake.luafile = "myproject.lua"
+                premake.arguments = {"myarg": "myvalue"}
+                premake.configure()
+                """)
+    c.save({"conanfile.py": conanfile})
+    c.run("build . -s compiler=msvc -s compiler.version=193 -s compiler.runtime=dynamic")
+    assert "conanfile.py: Running premake5 --file=myproject.lua vs2022 --myarg=myvalue!!" in c.out