Skip to content

Commit

Permalink
feat: added static library support + custom build dir (#256)
Browse files Browse the repository at this point in the history
Resolves #253
  • Loading branch information
wojciech-kulik authored Nov 23, 2024
1 parent ab1bd22 commit c1979bd
Show file tree
Hide file tree
Showing 18 changed files with 208 additions and 59 deletions.
25 changes: 20 additions & 5 deletions doc/xcodebuild.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,7 @@ XcodeBuildSettings *xcodebuild.core.xcode.XcodeBuildSettings*
{appPath} (string)
{productName} (string)
{bundleId} (string)
{buildDir} (string|nil)


XcodeScheme *xcodebuild.core.xcode.XcodeScheme*
Expand Down Expand Up @@ -1708,6 +1709,7 @@ ProjectSettings
{destination} (string|nil) destination (ex. "28B52DAA-BC2F-410B-A5BE-F485A3AFB0BC")
{bundleId} (string|nil) bundle identifier (ex. "com.mycompany.myapp")
{appPath} (string|nil) app path (ex. "path/to/MyApp.app")
{buildDir} (string|nil) buildDir (ex. "/path/to/DerivedData/app-abc123/Build/Products")
{productName} (string|nil) product name (ex. "MyApp")
{testPlan} (string|nil) test plan name (ex. "MyAppTests")
{xcodeproj} (string|nil) xcodeproj file path (ex. "path/to/Project.xcodeproj")
Expand Down Expand Up @@ -1783,9 +1785,17 @@ M.is_spm_configured()
(boolean)


*xcodebuild.project.config.is_project_configured*
M.is_project_configured()
Checks if Xcode project is configured.
*xcodebuild.project.config.is_library_configured*
M.is_library_configured()
Checks if Xcode static library is configured.

Returns: ~
(boolean)


*xcodebuild.project.config.is_app_configured*
M.is_app_configured()
Checks if Xcode app project is configured.

Returns: ~
(boolean)
Expand Down Expand Up @@ -4144,6 +4154,11 @@ M.show_spm_actions()
Shows available actions for Swift Package project.


*xcodebuild.ui.picker_actions.show_library_project_actions*
M.show_library_project_actions()
Shows available actions for Xcode library project.


*xcodebuild.ui.picker_actions.show_xcode_project_actions*
M.show_xcode_project_actions()
Shows available actions for Xcode project.
Expand All @@ -4168,12 +4183,12 @@ M.cancel_actions() *xcodebuild.helpers.cancel_actions*
Cancels all running actions from all modules.


M.validate_project({requiresXcodeproj}) *xcodebuild.helpers.validate_project*
M.validate_project({opts}) *xcodebuild.helpers.validate_project*
Validates if the project is configured.
It sends an error notification if the project is not configured.

Parameters: ~
{requiresXcodeproj} (boolean)
{opts} ({requiresXcodeproj:boolean|nil,requiresApp:boolean|nil}|nil)

Returns: ~
(boolean)
Expand Down
4 changes: 2 additions & 2 deletions lua/xcodebuild/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ end

---Opens the project in Xcode.
function M.open_in_xcode()
if helpers.validate_project(false) then
if helpers.validate_project() then
vim.fn.system({
"open",
"-a",
Expand Down Expand Up @@ -219,7 +219,7 @@ end

---Sends a notification with the current project settings.
function M.show_current_config()
if not helpers.validate_project(false) then
if not helpers.validate_project() then
return
end

Expand Down
2 changes: 2 additions & 0 deletions lua/xcodebuild/broadcasting/notifications.lua
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ function M.send_project_settings(settings)
- productName: ]] .. (settings.productName or "-") .. [[
- buildDir: ]] .. (settings.buildDir or "-") .. [[
- appPath: ]] .. (settings.appPath or "-") .. [[
]])
end
Expand Down
2 changes: 1 addition & 1 deletion lua/xcodebuild/code_coverage/coverage.lua
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ end
---First, the code coverage must be exported using |export_coverage| function.
---@param isVisible boolean|nil
function M.toggle_code_coverage(isVisible)
if not helpers.validate_project(false) then
if not helpers.validate_project() then
return
elseif not config.enabled then
notifications.send_error("Code coverage is disabled in xcodebuild.nvim config")
Expand Down
18 changes: 13 additions & 5 deletions lua/xcodebuild/core/xcode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
---@field appPath string
---@field productName string
---@field bundleId string
---@field buildDir string|nil

---@class XcodeScheme
---@field name string
Expand Down Expand Up @@ -184,7 +185,6 @@ function M.get_targets_filemap(derivedDataPath)
end

if not util.dir_exists(searchPath) then
notifications.send_error("Could not locate build dir. Please run Build.")
return {}
end

Expand Down Expand Up @@ -555,24 +555,31 @@ function M.get_build_settings(platform, projectFile, scheme, xcodeprojPath, call
local bundleId = nil
local productName = nil
local wrapperName = nil
local targetBuildDir = nil
local buildDir = nil

for _, line in ipairs(output) do
bundleId = bundleId or find_setting(line, "PRODUCT_BUNDLE_IDENTIFIER")
productName = productName or find_setting(line, "PRODUCT_NAME")
wrapperName = wrapperName or find_setting(line, "WRAPPER_NAME")
buildDir = buildDir or find_setting(line, "TARGET_BUILD_DIR")
targetBuildDir = targetBuildDir or find_setting(line, "TARGET_BUILD_DIR")
buildDir = buildDir or find_setting(line, "BUILD_DIR")

if bundleId and productName and buildDir and wrapperName then
if bundleId and productName and targetBuildDir and wrapperName and buildDir then
break
end
end

if not bundleId or (not productName and not wrapperName) or not buildDir then
if (not productName and not wrapperName) or not targetBuildDir then
notifications.send_error("Could not get build settings")
return
end

--- Static library does not have a bundle id
if not bundleId then
notifications.send_warning("Could not find bundle id. Ignore if it's a static library.")
end

if wrapperName then
wrapperName = wrapperName:gsub("%.app$", "")

Expand All @@ -582,9 +589,10 @@ function M.get_build_settings(platform, projectFile, scheme, xcodeprojPath, call
end

local result = {
appPath = buildDir .. "/" .. productName .. ".app",
appPath = targetBuildDir .. "/" .. productName .. ".app",
productName = productName,
bundleId = bundleId,
buildDir = buildDir,
}

util.call(callback, result)
Expand Down
23 changes: 20 additions & 3 deletions lua/xcodebuild/helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,35 @@ end

---Validates if the project is configured.
---It sends an error notification if the project is not configured.
---@param requiresXcodeproj boolean
---@param opts {requiresXcodeproj:boolean|nil, requiresApp:boolean|nil}|nil
---@return boolean
function M.validate_project(requiresXcodeproj)
function M.validate_project(opts)
opts = opts or {}
local projectConfig = require("xcodebuild.project.config")
local notifications = require("xcodebuild.broadcasting.notifications")
local requiresApp = opts.requiresApp
local requiresXcodeproj = opts.requiresXcodeproj or requiresApp

if requiresXcodeproj and projectConfig.is_spm_configured() then
notifications.send_error("This operation is not supported for Swift Package.")
return false
end

if requiresXcodeproj and not projectConfig.is_project_configured() then
if requiresApp and projectConfig.is_library_configured() then
notifications.send_error("This operation is not supported for Xcode Library.")
return false
end

if requiresApp and not projectConfig.is_app_configured() then
notifications.send_error("The project is missing some details. Please run XcodebuildSetup first.")
return false
end

if
requiresXcodeproj
and not projectConfig.is_app_configured()
and not projectConfig.is_library_configured()
then
notifications.send_error("The project is missing some details. Please run XcodebuildSetup first.")
return false
end
Expand Down
6 changes: 3 additions & 3 deletions lua/xcodebuild/integrations/dap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function M.build_and_debug(callback)
return
end

if not helpers.validate_project(true) then
if not helpers.validate_project({ requiresApp = true }) then
return
end

Expand Down Expand Up @@ -138,7 +138,7 @@ end
---the project.
---@param callback function|nil
function M.debug_without_build(callback)
if not helpers.validate_project(true) then
if not helpers.validate_project({ requiresApp = true }) then
return
end

Expand Down Expand Up @@ -184,7 +184,7 @@ function M.attach_debugger_for_tests()
return
end

if not helpers.validate_project(true) then
if not helpers.validate_project({ requiresApp = true }) then
return
end

Expand Down
3 changes: 2 additions & 1 deletion lua/xcodebuild/integrations/neo-tree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ function M.setup()
local cwd = vim.fn.getcwd()

local function isProjectFile(path)
return projectConfig.is_project_configured() and vim.startswith(path, cwd)
return (projectConfig.is_app_configured() or projectConfig.is_library_configured())
and vim.startswith(path, cwd)
end

local function shouldUpdateProject(path)
Expand Down
3 changes: 2 additions & 1 deletion lua/xcodebuild/integrations/nvim-tree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ function M.setup()
local cwd = vim.fn.getcwd()

local function isProjectFile(path)
return projectConfig.is_project_configured() and vim.startswith(path, cwd)
return (projectConfig.is_app_configured() or projectConfig.is_library_configured())
and vim.startswith(path, cwd)
end

local function shouldUpdateProject(path)
Expand Down
3 changes: 2 additions & 1 deletion lua/xcodebuild/integrations/oil-nvim.lua
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ function M.setup()
local cwd = vim.fn.getcwd()

local function isProjectFile(path)
return projectConfig.is_project_configured() and vim.startswith(path, cwd)
return (projectConfig.is_app_configured() or projectConfig.is_library_configured())
and vim.startswith(path, cwd)
end

local function shouldUpdateProject(path)
Expand Down
10 changes: 5 additions & 5 deletions lua/xcodebuild/platform/device.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ end
---Kills the application on device, simulator, or macOS.
---@param callback function|nil
function M.kill_app(callback)
if not helpers.validate_project(true) then
if not helpers.validate_project({ requiresApp = true }) then
return
end

Expand All @@ -81,7 +81,7 @@ end
---@param waitForDebugger boolean
---@param callback function|nil
function M.run_app(waitForDebugger, callback)
if not helpers.validate_project(true) then
if not helpers.validate_project({ requiresApp = true }) then
return
end

Expand All @@ -104,7 +104,7 @@ end
---Boots the simulator.
---@param callback function|nil
function M.boot_simulator(callback)
if not helpers.validate_project(false) then
if not helpers.validate_project() then
return
end

Expand All @@ -129,7 +129,7 @@ end
---Does not support macOS.
---@param callback function|nil
function M.install_app(callback)
if not helpers.validate_project(true) then
if not helpers.validate_project({ requiresApp = true }) then
return
end

Expand Down Expand Up @@ -157,7 +157,7 @@ end
---Does not support macOS.
---@param callback function|nil
function M.uninstall_app(callback)
if not helpers.validate_project(true) then
if not helpers.validate_project({ requiresApp = true }) then
return
end

Expand Down
9 changes: 6 additions & 3 deletions lua/xcodebuild/project/builder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ local CANCELLED_CODE = 143
---@see xcodebuild.platform.device.run_app
---@see xcodebuild.project.builder.build_project
function M.build_and_run_app(waitForDebugger, callback)
if not helpers.validate_project(true) then
if not helpers.validate_project({ requiresApp = true }) then
return
end

Expand Down Expand Up @@ -53,7 +53,7 @@ end
function M.build_project(opts, callback)
opts = opts or {}

if not helpers.validate_project(false) then
if not helpers.validate_project() then
return
end

Expand Down Expand Up @@ -127,7 +127,10 @@ end
function M.clean_derived_data()
local derivedDataPath

if projectConfig.settings.appPath then
if projectConfig.settings.buildDir then
local buildDir = projectConfig.settings.buildDir or ""
derivedDataPath = string.match(buildDir, "(.+/DerivedData/[^/]+)/.+") or buildDir
elseif projectConfig.settings.appPath then
derivedDataPath = string.match(projectConfig.settings.appPath, "(.+/DerivedData/[^/]+)/.+")
else
derivedDataPath = require("xcodebuild.core.xcode").find_derived_data_path(
Expand Down
29 changes: 26 additions & 3 deletions lua/xcodebuild/project/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
---@field destination string|nil destination (ex. "28B52DAA-BC2F-410B-A5BE-F485A3AFB0BC")
---@field bundleId string|nil bundle identifier (ex. "com.mycompany.myapp")
---@field appPath string|nil app path (ex. "path/to/MyApp.app")
---@field buildDir string|nil buildDir (ex. "/path/to/DerivedData/app-abc123/Build/Products")
---@field productName string|nil product name (ex. "MyApp")
---@field testPlan string|nil test plan name (ex. "MyAppTests")
---@field xcodeproj string|nil xcodeproj file path (ex. "path/to/Project.xcodeproj")
Expand Down Expand Up @@ -146,9 +147,29 @@ function M.is_spm_configured()
end
end

---Checks if Xcode project is configured.
---Checks if Xcode static library is configured.
---@return boolean
function M.is_project_configured()
function M.is_library_configured()
local settings = M.settings
--- no bundle id
if
settings.platform
and settings.projectFile
and settings.scheme
and settings.destination
and not settings.bundleId
and settings.appPath
and settings.productName
then
return true
else
return false
end
end

---Checks if Xcode app project is configured.
---@return boolean
function M.is_app_configured()
local settings = M.settings
if
settings.platform
Expand All @@ -168,7 +189,7 @@ end
---Checks if project is configured.
---@return boolean
function M.is_configured()
return M.is_project_configured() or M.is_spm_configured()
return M.is_app_configured() or M.is_spm_configured() or M.is_library_configured()
end

---Updates the settings (`appPath`, `productName`, and `bundleId`) based on
Expand All @@ -190,6 +211,7 @@ function M.update_settings(opts, callback)
M.settings.appPath = nil
M.settings.productName = nil
M.settings.bundleId = nil
M.settings.buildDir = nil
M.save_settings()
last_platform = nil
util.call(callback)
Expand All @@ -207,6 +229,7 @@ function M.update_settings(opts, callback)
M.settings.appPath = buildSettings.appPath
M.settings.productName = buildSettings.productName
M.settings.bundleId = buildSettings.bundleId
M.settings.buildDir = buildSettings.buildDir
M.save_settings()
last_platform = M.settings.platform
util.call(callback)
Expand Down
Loading

0 comments on commit c1979bd

Please sign in to comment.