brick-module 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,6 +43,88 @@ ext.readPackageJson = { File packageJsonFile ->
43
43
  }
44
44
  }
45
45
 
46
+ ext.findBrickJson = { startDir ->
47
+ // Walk up the directory tree looking for brick.json
48
+ if (!startDir) {
49
+ return null
50
+ }
51
+
52
+ try {
53
+ def current = new File(startDir).canonicalFile
54
+ def root = new File('/').canonicalFile
55
+
56
+ while (current != root && current != null) {
57
+ def brickJsonFile = new File(current, 'brick.json')
58
+ if (brickJsonFile.exists()) {
59
+ return brickJsonFile
60
+ }
61
+ def parent = current.parentFile
62
+ if (parent == current || parent == null) break // Reached filesystem root
63
+ current = parent
64
+ }
65
+ } catch (Exception e) {
66
+ // Failed to process directory, return null
67
+ }
68
+
69
+ return null
70
+ }
71
+
72
+ ext.resolveProjectRoot = { projectRootPath, configDir ->
73
+ // Handle both absolute and relative paths
74
+ if (!projectRootPath || !configDir) {
75
+ return null
76
+ }
77
+
78
+ try {
79
+ def projectRootFile = new File(projectRootPath)
80
+ if (projectRootFile.isAbsolute()) {
81
+ return projectRootFile.exists() ? projectRootFile : null
82
+ } else {
83
+ // Relative to brick.json location
84
+ def resolvedFile = new File(configDir, projectRootPath).canonicalFile
85
+ return resolvedFile.exists() ? resolvedFile : null
86
+ }
87
+ } catch (Exception e) {
88
+ return null
89
+ }
90
+ }
91
+
92
+ ext.getBrickAndroidPath = { searchRoot ->
93
+ // Walk up directory tree to find brick.json
94
+ def brickConfigFile = findBrickJson(searchRoot)
95
+
96
+ if (brickConfigFile && brickConfigFile.exists()) {
97
+ try {
98
+ def config = new JsonSlurper().parse(brickConfigFile)
99
+
100
+ // Get the effective project root
101
+ def effectiveRoot = brickConfigFile.parentFile
102
+ if (config.projectRoot) {
103
+ def resolvedRoot = resolveProjectRoot(config.projectRoot, brickConfigFile.parentFile)
104
+ if (resolvedRoot) {
105
+ effectiveRoot = resolvedRoot
106
+ }
107
+ }
108
+
109
+ def androidPath = config?.output?.android
110
+ if (androidPath && !androidPath.isEmpty()) {
111
+ // Handle absolute paths (though not recommended)
112
+ if (new File(androidPath).isAbsolute()) {
113
+ println("[Brick] Warning: Using absolute path for Android output is not recommended: ${androidPath}")
114
+ return androidPath
115
+ }
116
+ // Otherwise, treat as relative to effective project root
117
+ return new File(effectiveRoot, androidPath).canonicalPath
118
+ }
119
+ } catch (Exception e) {
120
+ println("[Brick] Warning: Failed to parse brick.json: ${e.message}")
121
+ }
122
+ }
123
+
124
+ // Default: .brick directory in the Android project root
125
+ return new File(searchRoot, '.brick').canonicalPath
126
+ }
127
+
46
128
  ext.getAllDependencies = { packageJson ->
47
129
  def deps = []
48
130
  deps.addAll(packageJson.dependencies?.keySet() ?: [])
@@ -54,6 +136,44 @@ ext.isBrickModule = { packageJson ->
54
136
  return packageJson?.brickModule != null
55
137
  }
56
138
 
139
+ ext.findProjectRoot = { androidDir ->
140
+ // 1. Walk up directory tree to find brick.json
141
+ def brickConfigFile = findBrickJson(androidDir)
142
+ if (brickConfigFile) {
143
+ brickLog("Found brick.json at: ${brickConfigFile.canonicalPath}")
144
+ try {
145
+ def config = new JsonSlurper().parse(brickConfigFile)
146
+ if (config.projectRoot) {
147
+ def projectRoot = resolveProjectRoot(config.projectRoot, brickConfigFile.parentFile)
148
+ if (projectRoot) {
149
+ brickLog("Using projectRoot from brick.json: ${projectRoot.canonicalPath}")
150
+ return projectRoot
151
+ }
152
+ }
153
+ // If brick.json exists but has no projectRoot, use its directory as project root
154
+ return brickConfigFile.parentFile
155
+ } catch (Exception e) {
156
+ println("[Brick] Warning: Failed to parse brick.json: ${e.message}")
157
+ }
158
+ }
159
+
160
+ // 2. Walk up to find package.json with node_modules
161
+ def current = androidDir
162
+ while (current != null && current != new File('/')) {
163
+ if (new File(current, 'package.json').exists() && new File(current, 'node_modules').exists()) {
164
+ brickLog("Found project root via package.json: ${current.canonicalPath}")
165
+ return current
166
+ }
167
+ def parent = current.parentFile
168
+ if (parent == current) break
169
+ current = parent
170
+ }
171
+
172
+ // If no project root found, use default fallback
173
+ brickLog("Warning: Failed to find project root via brick.json or package.json. Using default: ${androidDir.parentFile.canonicalPath}")
174
+ return androidDir.parentFile
175
+ }
176
+
57
177
  ext.runBrickCodegen = { workingDir ->
58
178
  def brickModuleDir = resolveModule(workingDir, "brick-module")
59
179
  if (brickModuleDir == null) {
@@ -82,7 +202,7 @@ ext.runBrickCodegen = { workingDir ->
82
202
  // =============================================================================
83
203
 
84
204
  ext.applyBrickModules = { settings ->
85
- def projectRoot = settings.rootDir.parentFile
205
+ def projectRoot = findProjectRoot(settings.rootDir)
86
206
  def foundModules = []
87
207
  def brickModulesData = [:]
88
208
 
@@ -144,15 +264,16 @@ ext.applyBrickModules = { settings ->
144
264
  }
145
265
  }
146
266
 
147
- // Check if codegen is needed
148
- def brickDir = new File(settings.rootDir, ".brick")
267
+ // Check if codegen is needed (use configured path)
268
+ def androidBrickPath = getBrickAndroidPath(settings.rootDir)
269
+ def brickDir = new File(androidBrickPath)
149
270
  def needsCodegen = !brickDir.exists() || !new File(brickDir, "src/main/kotlin/BrickModule.kt").exists()
150
271
 
151
272
  if (needsCodegen) {
152
273
  runBrickCodegen(projectRoot)
153
274
  }
154
275
 
155
- // Include generated module
276
+ // Include generated module (use configured path)
156
277
  if (brickDir.exists()) {
157
278
  settings.include(":brick-codegen")
158
279
  settings.project(":brick-codegen").projectDir = brickDir
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brick-module",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Better React Native native module development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -51,7 +51,7 @@
51
51
  "brick-codegen": "./bin/brick-codegen.js"
52
52
  },
53
53
  "dependencies": {
54
- "brick-codegen": "0.1.5"
54
+ "brick-codegen": "0.1.6"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "react": ">=18.2.0",
package/podfile_helper.rb CHANGED
@@ -6,8 +6,79 @@
6
6
  require 'json'
7
7
  require 'pathname'
8
8
 
9
+ def find_brick_json(start_dir)
10
+ # Walk up the directory tree looking for brick.json
11
+ current = File.expand_path(start_dir)
12
+ root = File.expand_path('/')
13
+
14
+ while current != root
15
+ brick_json_path = File.join(current, 'brick.json')
16
+ if File.exist?(brick_json_path)
17
+ return brick_json_path
18
+ end
19
+ parent = File.dirname(current)
20
+ break if parent == current # Reached filesystem root
21
+ current = parent
22
+ end
23
+
24
+ return nil
25
+ end
26
+
27
+ def find_project_root
28
+ ios_root = Pod::Config.instance.installation_root
29
+
30
+ # 1. Walk up directory tree to find brick.json
31
+ brick_json_path = find_brick_json(ios_root)
32
+ if brick_json_path
33
+ Pod::UI.puts "[Brick] Found brick.json at: #{brick_json_path}"
34
+ begin
35
+ config = JSON.parse(File.read(brick_json_path))
36
+ if config['projectRoot']
37
+ project_root = resolve_project_root(config['projectRoot'], File.dirname(brick_json_path))
38
+ if project_root
39
+ Pod::UI.puts "[Brick] Using projectRoot from brick.json: #{project_root}"
40
+ return project_root
41
+ end
42
+ end
43
+ # If brick.json exists but has no projectRoot, use its directory as project root
44
+ return File.dirname(brick_json_path)
45
+ rescue => e
46
+ Pod::UI.warn "[Brick] Failed to parse brick.json: #{e.message}"
47
+ end
48
+ end
49
+
50
+ # 2. Walk up to find package.json with node_modules
51
+ current = ios_root
52
+ while current != '/'
53
+ if File.exist?(File.join(current, 'package.json')) && File.exist?(File.join(current, 'node_modules'))
54
+ Pod::UI.puts "[Brick] Found project root via package.json: #{current}"
55
+ return current
56
+ end
57
+ parent = File.dirname(current)
58
+ break if parent == current
59
+ current = parent
60
+ end
61
+
62
+ # If no project root found, use default fallback
63
+ default_root = File.expand_path(File.join(ios_root, '..'))
64
+ Pod::UI.warn "[Brick] Warning: Failed to find project root via brick.json or package.json. Using default: #{default_root}"
65
+ return default_root
66
+ end
67
+
68
+ def resolve_project_root(project_root_path, config_dir)
69
+ # Handle both absolute and relative paths
70
+ if Pathname.new(project_root_path).absolute?
71
+ return project_root_path if File.exist?(project_root_path)
72
+ else
73
+ # Relative to brick.json location
74
+ resolved_path = File.expand_path(File.join(config_dir, project_root_path))
75
+ return resolved_path if File.exist?(resolved_path)
76
+ end
77
+ return nil
78
+ end
79
+
9
80
  def use_brick_modules!
10
- brick_root = "#{Pod::Config.instance.installation_root}/.."
81
+ brick_root = find_project_root
11
82
  discovered_modules = []
12
83
 
13
84
  begin
@@ -21,9 +92,12 @@ def use_brick_modules!
21
92
  # Generate BrickModuleProvider.swift for auto-registration
22
93
  generate_brick_module_provider(brick_root, discovered_modules)
23
94
 
95
+ # Get iOS output path from brick.json if it exists
96
+ ios_brick_path = get_brick_ios_path(brick_root)
97
+
24
98
  # Add generated BrickCodegen pod if it exists
25
- brick_codegen_podspec_path = "#{brick_root}/ios/.brick/BrickCodegen.podspec"
26
- brick_codegen_pod_path = "#{brick_root}/ios/.brick"
99
+ brick_codegen_podspec_path = "#{brick_root}/#{ios_brick_path}/BrickCodegen.podspec"
100
+ brick_codegen_pod_path = "#{brick_root}/#{ios_brick_path}"
27
101
 
28
102
  if File.exist?(brick_codegen_podspec_path)
29
103
  begin
@@ -98,11 +172,49 @@ def discover_brick_modules(project_root)
98
172
  modules
99
173
  end
100
174
 
175
+ def get_brick_ios_path(project_root)
176
+ # Walk up from project_root to find brick.json
177
+ brick_config_path = find_brick_json(project_root)
178
+
179
+ if brick_config_path && File.exist?(brick_config_path)
180
+ begin
181
+ config = JSON.parse(File.read(brick_config_path))
182
+
183
+ # Get the effective project root
184
+ effective_root = project_root
185
+ if config['projectRoot']
186
+ resolved_root = resolve_project_root(config['projectRoot'], File.dirname(brick_config_path))
187
+ effective_root = resolved_root if resolved_root
188
+ end
189
+
190
+ ios_path = config.dig('output', 'ios')
191
+ if ios_path && !ios_path.empty?
192
+ # Handle absolute paths (though not recommended)
193
+ if Pathname.new(ios_path).absolute?
194
+ Pod::UI.warn "[Brick] Using absolute path for iOS output is not recommended: #{ios_path}"
195
+ return ios_path
196
+ else
197
+ # Relative to effective project root
198
+ return File.join(effective_root, ios_path)
199
+ end
200
+ end
201
+ rescue => e
202
+ Pod::UI.warn "[Brick] Failed to parse brick.json: #{e.message}"
203
+ end
204
+ end
205
+
206
+ # Return default path relative to project root
207
+ return File.join(project_root, 'ios/.brick')
208
+ end
209
+
101
210
  def generate_brick_module_provider(project_root, modules)
102
211
  return if modules.empty?
103
212
 
104
- # Create the .brick directory if it doesn't exist
105
- brick_dir = File.join(project_root, 'ios', '.brick')
213
+ # Get iOS output path from brick.json
214
+ ios_brick_path = get_brick_ios_path(project_root)
215
+
216
+ # Create the brick directory if it doesn't exist
217
+ brick_dir = File.join(project_root, ios_brick_path)
106
218
  FileUtils.mkdir_p(brick_dir) unless File.exist?(brick_dir)
107
219
 
108
220
  # Generate imports and module instances