comparison gui_ze/gui_ze.bzl @ 195:f8f5004a920a

Merging back hg-web-tip
author MrJuneJune <me@mrjunejune.com>
date Tue, 27 Jan 2026 06:51:44 -0800
parents 9f4429c49733
children
comparison
equal deleted inserted replaced
189:14cc84ba35a0 195:f8f5004a920a
89 "src_folder": attr.string(), 89 "src_folder": attr.string(),
90 }, 90 },
91 executable = True, 91 executable = True,
92 ) 92 )
93 93
94 def _bun_bundle_impl(ctx):
95 """
96 Bundle TypeScript/JavaScript with Bun, resolving imports from bazel root.
97
98 Copies all dependencies (dereferencing symlinks) to create a flat structure
99 where imports can resolve correctly relative to the bazel workspace root.
100 """
101 out = ctx.actions.declare_file(ctx.label.name + ".js")
102
103 inputs = depset(
104 direct = [ctx.file.src],
105 transitive = [dep[DefaultInfo].files for dep in ctx.attr.deps]
106 )
107
108 # Get the source file's package directory (e.g., "hg-web" from "hg-web/src/main.tsx")
109 src_package = ctx.file.src.path.split("/")[0]
110
111 # Collect unique root directories to copy (deduped), excluding src_package (handled separately)
112 dirs_to_copy = {}
113 for f in ctx.files.deps:
114 # Find the root directory path by locating where short_path starts in full path
115 short_path_suffix = "/".join(f.short_path.split("/")[1:])
116 pos = f.path.find(short_path_suffix)
117 if pos > 0:
118 root_dir = f.path[:pos].rstrip("/")
119 # Skip src_package - it's a symlink that needs special handling
120 if not root_dir.endswith(src_package):
121 dirs_to_copy[root_dir] = True
122
123 # Build copy commands for each unique directory
124 copy_commands = ["cp -rL {dir} .".format(dir = d) for d in dirs_to_copy.keys()]
125
126 ctx.actions.run_shell(
127 inputs = inputs,
128 outputs = [out],
129 tools = [ctx.executable._bun] + [ctx.file.src] + ctx.files.deps + ctx.files.node_modules,
130 command = """
131 cp -rL {src_package} {src_package}_tmp && rm -rf {src_package} && mv {src_package}_tmp {src_package}
132 {copy_commands}
133 export NODE_PATH=./third_party/bun/node_modules
134 cp ./third_party/bun/tsconfig.json .
135 {bun} build {entry} --outfile {output} --target browser
136 """.format(
137 copy_commands = "\n".join(copy_commands),
138 src_package = src_package,
139 bun = ctx.executable._bun.path,
140 entry = ctx.file.src.path,
141 output = out.path,
142 ),
143 progress_message = "Bundling %s with Bun" % ctx.file.src.short_path,
144 )
145
146 return [DefaultInfo(files = depset([out]))]
147
148 bun_bundle = rule(
149 implementation = _bun_bundle_impl,
150 attrs = {
151 "src": attr.label(
152 allow_single_file = [".ts", ".tsx", ".js", ".jsx"],
153 doc = "Entry point file to bundle",
154 ),
155 "deps": attr.label_list(
156 allow_files = True,
157 doc = "Source files and other dependencies to include",
158 ),
159 "node_modules": attr.label_list(
160 allow_files = True,
161 default = [Label("//third_party/bun:bun_files")],
162 doc = "Node modules for bundling (defaults to //third_party/bun:bun_files)",
163 ),
164 "_bun": attr.label(
165 default = Label("//third_party/bun:bun"),
166 executable = True,
167 cfg = "exec",
168 ),
169 },
170 doc = "Bundle TypeScript/JavaScript using Bun with bazel root imports",
171 )
172
173
174
94 def _bun_build_impl(ctx): 175 def _bun_build_impl(ctx):
95 """ 176 """
96 Run bun build on the folder 177 Run bun build on the folder
97 178
98 This sucks because you need to either copy node module into the root folder where main.ts file 179 This sucks because you need to either copy node module into the root folder where main.ts file
109 outputs = [out], 190 outputs = [out],
110 tools = [ctx.executable._bun] + inputs, 191 tools = [ctx.executable._bun] + inputs,
111 command = """ 192 command = """
112 cp -r third_party/bun/** . \ 193 cp -r third_party/bun/** . \
113 && cp -r {src_folder}/** . \ 194 && cp -r {src_folder}/** . \
114 && export NODE_PATH=./node_modules && {bun_path} build {input_path} --outfile {output_path} 195 && cp -r ./bazel-out/k8-fastbuild/bin/hg-web/src/** src \
196 && ls src \
197 && pwd \
198 && export NODE_PATH=./node_modules && {bun_path} build {input_path} --outfile {output_path} --target browser
115 """.format( 199 """.format(
116 bun_path = ctx.executable._bun.path, 200 bun_path = ctx.executable._bun.path,
117 src_folder = ctx.attr.src_folder, 201 src_folder = ctx.attr.src_folder,
118 input_path = ctx.file.src.path.split("/")[-1], 202 # Fix this lol
203 input_path = "/".join(ctx.file.src.path.split("/")[-2:]),
119 output_path = out.path, 204 output_path = out.path,
120 ), 205 ),
121 progress_message = "Bundling {} with Bun!\n\n".format(ctx.file.src.path), 206 progress_message = "Bundling {} with Bun!\n\n".format(ctx.file.src.path),
122 ) 207 )
123 208
206 for src in srcs: 291 for src in srcs:
207 out = ctx.actions.declare_file(ctx.attr.dest + "/" + src.basename) 292 out = ctx.actions.declare_file(ctx.attr.dest + "/" + src.basename)
208 ctx.actions.run_shell( 293 ctx.actions.run_shell(
209 inputs = [src], 294 inputs = [src],
210 outputs = [out], 295 outputs = [out],
211 command = "cp \"$1\" \"$2\"", 296 command = "cp -r \"$1\" \"$2\"",
212 arguments = [src.path, out.path], 297 arguments = [src.path, out.path],
213 ) 298 )
214 outs.append(out) 299 outs.append(out)
215 return [DefaultInfo(files = depset(outs))] 300 return [DefaultInfo(files = depset(outs), runfiles = ctx.runfiles(files = outs))]
216 301
217 move_files_into_dir = rule( 302 move_files_into_dir = rule(
218 implementation = _move_files_into_dir_impl, 303 implementation = _move_files_into_dir_impl,
219 attrs = { 304 attrs = {
220 "srcs": attr.label_list(allow_files=True), 305 "srcs": attr.label_list(allow_files=True),