tidev / titanium-sdk

🚀 Native iOS and Android Apps with JavaScript
https://titaniumsdk.com/
Other
2.76k stars 1.21k forks source link

Windows: building modules will fail with permission error #14077

Open m1ga opened 4 months ago

m1ga commented 4 months ago

I have searched and made sure there are no existing issues for the issue I am filing

Description

When trying to build an Android module on windows it will show

[ERROR] EPERM: operation not permitted, lstat 'C:\ProjectPath\module\android\build\build_android.log'.

which is located here: https://github.com/tidev/titanium-sdk/blob/master/cli/commands/build.js#L424

When I comment out that line it will build the module

Expected Behavior

build the module

Actual behavior

crash with permission error

Reproducible sample

ti create -t module --id com.test -n test --android-code-base java -p android -d . && cd test/android && ti build -p android -b

Steps to reproduce

run the command above

Platform

Android

SDK version you are using

12.3.1

Alloy version you are using

No response

m1ga commented 4 months ago

Possible fix with: https://github.com/tidev/titanium-sdk/pull/14078

cb1kenobi commented 4 months ago

Disabling the log file is not the solution. The problem is coming from the module build cleanup() function: https://github.com/tidev/titanium-sdk/blob/master/android/cli/commands/_buildModule.js#L423-L447.

When you build a module, the build command patches the logger so that it can redirect output to a file BEFORE the module build starts. When the module build runs, it calls cleanup() in an attempt to detect a dirty build directory. It empties the build dir (line 426), then proceeds to empty it again (line 433).

On a clean build, the only thing in that directory is the build_android.log. I'm not sure how this ever worked. LOL.

In any case, the solution is to fix cleanup() by:

  1. deleting everything besides the build_android.log file (e.g. manually do it) and
  2. rethink why we empty the build directory twice

I would argue that the first emptyDir() call should be removed and the second emptyDir() should be replaced with a readdir() loop and fs.remove() for each non-log file.

m1ga commented 4 months ago

Disabling the log file is not the solution

A module build never created that file before. I've tested it on Mac and Linux and I don't have that file in the module build/ folder. That's why I thought skipping it for "win + module" would be the quickest as it isn't there on the other platforms, as a workround of course :)

But I'll check the solution you've suggested.

For app builds the file is there and that works fine

cb1kenobi commented 4 months ago

How is this just breaking now? You think it's a v6 vs v7 thing? I wonder if v7 fixed something and exposed this issue. Regardless, it is suspicious that cleanup() calls emptyDir(buildDir) twice.

On a side note, cleanup() is a poor name. I think of cleanup as a post action. This is more of a init or reset.

m1ga commented 4 months ago

How is this just breaking now? You think it's a v6 vs v7 thing?

I think no one compiled modules on Windows for a while :smile: At least I never did and it was reported by a Slack user. But it could be a v6/v7 issue, I didn't check it with an older CLI yet. The user (and I) was using v7.

m1ga commented 4 months ago

I've just tested a module build without the emptyDir and yes, there is a build_android.log file but it just contains:


12.7.2024, 13:58:46

Operating System
  Name                        = Fedora
  Version                     = 40
  Architecture                = 64-bit
  # CPUs                      = 20
  Memory                      = 33300217856

Node.js
  Node.js Version             = 20.0.0
  npm Version                 = 9.6.4

Titanium CLI
  CLI Version                 = 7.1.0

Titanium SDK
  SDK Version                 = 12.3.1.GA
  SDK Path                    = /home/miga/.titanium/mobilesdk/linux/12.3.1.GA
  Target Platform             = android

Command
  /usr/local/bin/node /usr/local/bin/ti build -p android --build-only

no other log. A app build contains all the output. So I think it's a bit more work to get the build.log working for a module build.

Switching to Ti v6: still no log file in the build folder for a module. BUT: when I remove the emptyDir() I do get all the log output!

To summarize: with this PR (skipping the log output on Windows) it is the same output as with Ti v6. To get the log we would need to keep the build.log file AND fix the v7 to output all the logs to the file.