/ prelude / http_archive.bzl
http_archive.bzl
 1  # http_archive rule implementation
 2  #
 3  # Downloads and extracts an archive from a URL.
 4  
 5  def _http_archive_impl(ctx: AnalysisContext) -> list[Provider]:
 6      """Download and extract an archive."""
 7      
 8      # Download the archive
 9      archive = ctx.actions.declare_output("_archive")
10      url = ctx.attrs.urls[0]  # Just use first URL for now
11      
12      ctx.actions.download_file(
13          archive,
14          url,
15          sha256 = ctx.attrs.sha256,
16      )
17      
18      # Extract it
19      output_dir = ctx.actions.declare_output("_extracted", dir = True)
20      
21      # Use tar to extract (works for .tar.gz, .tgz, .crate)
22      strip_prefix = ctx.attrs.strip_prefix
23      if strip_prefix:
24          # Extract to temp, then move stripped content
25          extract_cmd = cmd_args([
26              "sh", "-c",
27              cmd_args(
28                  "mkdir -p $2 && tar -xzf $1 -C $2 --strip-components=1",
29                  delimiter = " ",
30              ),
31              "--",
32              archive,
33              output_dir.as_output(),
34          ])
35      else:
36          extract_cmd = cmd_args([
37              "sh", "-c",
38              cmd_args("mkdir -p $2 && tar -xzf $1 -C $2", delimiter = " "),
39              "--",
40              archive,
41              output_dir.as_output(),
42          ])
43      
44      ctx.actions.run(extract_cmd, category = "extract", identifier = ctx.label.name)
45      
46      return [DefaultInfo(default_output = output_dir)]
47  
48  http_archive = rule(
49      impl = _http_archive_impl,
50      attrs = {
51          "urls": attrs.list(attrs.string()),
52          "sha256": attrs.option(attrs.string(), default = None),
53          "strip_prefix": attrs.option(attrs.string(), default = None),
54      },
55  )