defmodule ExSwiftParser.MixProject do use Mix.Project def project do [ app: :ex_swift_parser, version: "0.1.2", elixir: "~> 1.15", start_permanent: Mix.env() == :prod, deps: deps(), compilers: Mix.compilers(), aliases: aliases(), escript: escript(), description: description(), package: package(), source_url: "https://github.com/dockyard/ex_swift_parser", docs: [ main: "readme", extras: ["README.md"] ] ] end defp escript do [ main_module: ExSwiftParser.CLI ] end # Run "mix help compile.app" to learn about applications. def application do [ extra_applications: [:logger] ] end # Run "mix help deps" to learn about dependencies. defp deps do [ {:jason, "~> 1.2"}, {:ex_doc, "~> 0.29", only: :dev, runtime: false} ] end defp description do "Elixir wrapper for Swift AST parsing using swift-ast-explorer" end defp package do [ maintainers: ["DockYard"], licenses: ["MIT"], links: %{"GitHub" => "https://github.com/dockyard/ex_swift_parser"}, files: [ "lib", "mix.exs", "README.md", "LICENSE", ".formatter.exs", "Makefile", "third_party/swift-ast-explorer/Resources/parsers/50800/Package.swift", "third_party/swift-ast-explorer/Resources/parsers/50800/Sources", "third_party/swift-ast-explorer/Resources/parsers/50900/Package.swift", "third_party/swift-ast-explorer/Resources/parsers/50900/Sources", "third_party/swift-ast-explorer/Resources/parsers/51000/Package.swift", "third_party/swift-ast-explorer/Resources/parsers/51000/Sources" ] ] end defp aliases do [ "deps.get": ["deps.get", "compile.swift_parsers"], "compile": ["compile.swift_parsers", "compile"] ] end end defmodule Mix.Tasks.Compile.SwiftParsers do @moduledoc """ Compiles Swift parsers for ExSwiftParser """ use Mix.Task @shortdoc "Compile Swift parsers" @recursive true def run(_args) do Mix.shell().info("Compiling Swift parsers...") # Ensure priv/parsers directory exists File.mkdir_p!("priv/parsers") parsers = [ {"50800", "parser_50800"}, {"50900", "parser_50900"}, {"51000", "parser_51000"} ] for {version, parser_name} <- parsers do parser_path = "third_party/swift-ast-explorer/Resources/parsers/#{version}" target_path = "priv/parsers/#{parser_name}" if File.exists?(parser_path) do Mix.shell().info("Building Swift parser for version #{version}...") case System.cmd("swift", ["build", "--package-path", parser_path], stderr_to_stdout: true) do {output, 0} -> Mix.shell().info("Successfully built parser #{version}") # Create symlink to the built parser built_parser = Path.join([parser_path, ".build", "debug", "parser"]) if File.exists?(built_parser) do # Remove existing symlink if it exists if File.exists?(target_path), do: File.rm!(target_path) # Create relative symlink relative_path = Path.relative_to(built_parser, "priv/parsers") File.ln_s!(relative_path, target_path) end {output, exit_code} -> Mix.shell().error("Failed to build parser #{version} (exit code: #{exit_code})") Mix.shell().error(output) end else Mix.shell().error("Parser source not found: #{parser_path}") end end :ok end end