# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem                  1.0
PortGroup                   active_variants 1.1
PortGroup                   app 1.0
PortGroup                   cmake 1.1
PortGroup                   conflicts_build 1.0
PortGroup                   github 1.0

name                        Aseprite
categories                  graphics
platforms                   {macosx >= 13}
maintainers                 {ryandesign @ryandesign} openmaintainer
license                     Restrictive

# We are allowed to redistribute the source code but not binaries.

# https://github.com/aseprite/aseprite/blob/master/EULA.txt
# "The Licensor grants you the right to install and use copies of the
# SOFTWARE PRODUCT on your computer [...]"
# "You may not distribute copies of the SOFTWARE PRODUCT to third
# parties."
# "You may only compile and modify the source code of the SOFTWARE
# PRODUCT for your own personal purpose or to propose a contribution to
# the SOFTWARE PRODUCT."

# https://aseprite.org/faq/#if-aseprite-source-code-is-available-how-is-that-you-are-selling-it
# "Now you can still download its source code, compile it, and use it
# for your personal purposes. You can make commercial art/assets with it
# too. The only restriction in Aseprite EULA is that you cannot
# redistribute Aseprite to third parties."

# https://github.com/aseprite/aseprite/issues/2266#issuecomment-586600478
# "[...] we considerer that the source code can be distributed (even
# modified copies). And only binaries cannot be distributed. We might
# modify the EULA soon to clarify these aspects (separation between
# Binary vs. Source Code)."

# https://community.aseprite.org/t/eula-and-faq-confusion/9377
# "[...] the FAQ is making reference to assets/sprites, so you can
# create art for personal or commercial products with any version of
# Aseprite (official or compiled). About the EULA is that you cannot
# compile Aseprite for commercial purposes (e.g. resell it)."

github.setup                aseprite aseprite 1.3.12 v
revision                    0
checksums                   rmd160  528255cdd95464a86ba5a4e703d1ba4692dd7066 \
                            sha256  e44401463b66fc1267a1865ab75f5a9d1ae46e989c19a4ec7aadbaa315634e34 \
                            size    73751262

# Aseprite doesn't specify which commit of depot_tools we should use, so I'm
# using the most recent commit before this version of Aseprite was tagged.
set depot_tools_commit      af7eadb0240739a9a5bcd2018c6b0c2baf794852

# Latest commit in the skia branch indicated in INSTALL.md at the time this
# version of Aseprite was released.
set skia_branch             m102
set skia_commit             857111b32703e9e8cb14053e25f56b21d636a3c2

# Also fetch extra code not in distfiles. The maintainer can use "sudo port
# -dn checksum fetch.extra=no" and "sudo port -dn patch fetch.extra=no" to
# avoid unnecessary fetching when preparing a port update.
options fetch.extra
default fetch.extra         yes

homepage                    https://aseprite.org
github.tarball_from         releases
distname                    ${name}-v${version}-Source
use_zip                     yes

set main_distfile           [lindex ${distfiles} 0]
set skia_distfile           skia-${skia_branch}-${skia_commit}.tar.gz

checksums-prepend           ${main_distfile}
checksums-append            ${skia_distfile} \
                            rmd160  33e81b70e01bdda6830a2de99d6a7cbfa8d54ac2 \
                            sha256  5b9020eefe37751a55edcdd47853f9379028d4fe8281f8c9ac670250396e6236 \
                            size    53948269

distfiles                   ${main_distfile}:main \
                            ${skia_distfile}:skia

extract.only                ${main_distfile}

master_sites                ${github.master_sites}:main \
                            https://github.com/${github.author}/skia/archive/${skia_commit}:skia

description                 animated sprite editor & pixel art tool

long_description            ${name} is an image editor for creating animated \
                            sprites and other pixel art.

set python_branch           3.13
set python_version          [string map {. {}} ${python_branch}]
configure.python            ${prefix}/bin/python${python_branch}

if {${fetch.extra}} {
    # TODO: Don't use git to fetch depot_tools or skia's dependencies.
    if {${os.platform} eq "darwin" && ${os.major} < 14} {
        set git_dep         port:git
    } else {
        set git_dep         bin:git:git
    }

    depends_fetch-append    ${git_dep}

    depends_extract-append  ${git_dep} \
                            port:python${python_version}
}

depends_build-append        path:bin/pkg-config:pkgconfig \
                            port:python${python_version}

depends_lib-append          port:cmark \
                            port:curl \
                            port:expat \
                            port:freetype \
                            port:giflib \
                            path:lib/pkgconfig/harfbuzz.pc:harfbuzz \
                            port:libarchive \
                            port:libb2 \
                            port:libdeflate \
                            path:include/turbojpeg.h:libjpeg-turbo \
                            path:lib/pkgconfig/pixman-1.pc:libpixman \
                            port:libpng \
                            port:lz4 \
                            port:mesa \
                            port:tiff \
                            port:TinyEXIF \
                            port:tinyxml2 \
                            port:webp \
                            port:zlib \
                            port:zstd

# TODO: Use MacPorts lua, after updating it to 5.4
# or figure out how to prevent this build from seeing it.
conflicts_build             lua lua50

# aseprite/laf/os/osx/dnd.mm:56:8: error: unknown type name 'NSPasteboardType'
set min_sdk_version         10.13
if {${os.platform} eq "darwin" && [vercmp ${configure.sdk_version} < ${min_sdk_version}]} {
    configure.sdk_version   ${min_sdk_version}
    configure.sdkroot       ${prefix}/Developer/SDKs/MacOSX${configure.sdk_version}.sdk
    depends_build-append    port:MacOSX${configure.sdk_version}.sdk
    # This SDK requires an ld with tapi support.
    if {[vercmp ${xcodeversion} < 8.3]} {
        depends_build-append \
                            port:ld64
        require_active_variants \
                            ld64 {} {ld64_97 ld64_127 ld64_236 ld64_274 ld64_xcode ld64_xtools}
    }
}

# Invoke a procedure on each item in a list.
# You'd think this would be in Tcl or MacPorts base already.
# http://wiki.tcl.tk/4884
proc map {prefix list} {
    set result {}
    foreach item ${list} {
        lappend result [{*}${prefix} ${item}]
    }
    return ${result}
}

proc quoted_shellescape {arg} {
    return "\"[shellescape ${arg}]\""
}

worksrcdir                  ${github.project}
extract.mkdir               yes

if {${fetch.extra}} {
    post-fetch {
        # depot_tools is hosted on googlesource.com which doesn't generate
        # deterministic tarballs. https://github.com/google/gitiles/issues/84
        file mkdir ${workpath}/depot_tools
        system -W ${workpath}/depot_tools "\
            git -c init.defaultBranch=main init &&\
            git remote add origin https://chromium.googlesource.com/chromium/tools/depot_tools &&\
            git fetch --depth 1 origin ${depot_tools_commit} &&\
            git -c advice.detachedHead=false checkout FETCH_HEAD\
            "
    }
}

set user_notified no
proc one_moment_please {} {
    global user_notified
    if {!${user_notified}} {
        if {[option fetch.extra]} {
            ui_msg "The extract, configure, and build phases may each take several minutes to complete."
        } else {
            ui_msg "The configure and build phases may each take several minutes to complete."
        }
        set user_notified yes
    }
}

if {${fetch.extra}} {
    pre-extract {
        one_moment_please
    }
}

pre-configure {
    one_moment_please
}

pre-build {
    one_moment_please
}

post-extract {
    system -W ${workpath} \
        "tar -xzf [shellescape ${distpath}/${skia_distfile}]"

    foreach submodule {../skia} {
        delete ${worksrcpath}/${submodule}
        move {*}[glob ${workpath}/[file tail ${submodule}]-*] ${worksrcpath}/${submodule}
    }

    if {${fetch.extra}} {
        # Various skia gn scripts run "python" but are compatible with python 3.
        ln -s ${configure.python} ${workpath}/depot_tools/python

        # depot_tools runs "python3".
        ln -s ${configure.python} ${workpath}/depot_tools/python3

        # Avoid fetching unnecessary dependencies.
        system -W ${workpath} "${patch.cmd} ${patch.pre_args} < [shellescape ${filespath}/DEPS.patch]"

        # Avoid fetching unnecessary data for necessary dependencies.
        system -W ${workpath} "${patch.cmd} ${patch.pre_args} < [shellescape ${filespath}/git-sync-deps.patch]"

        # Fetch skia's dependencies.
        # TODO: Fetch these as distfiles instead, maybe using a strategy similar
        # to the one formerly used by the MoltenVK port. Many of them aren't even
        # needed since we're using MacPorts deps rather than bundled versions.
        system -W ${workpath}/skia "${configure.python} tools/git-sync-deps"
    }
}

patch.dir                   ${workpath}
patch.pre_args-append       -b
patchfiles                  json11.patch \
                            no-base_aligned_alloc.patch \
                            prefix.patch \
                            USE_SHARED_LIBARCHIVE.patch \
                            USE_SHARED_LIBWEBP.patch

post-patch {
    # https://github.com/aseprite/skia/issues/19
    reinplace -W ${workpath}/skia/third_party "s|@PREFIX@|${prefix}|g" \
        freetype2/BUILD.gn harfbuzz/BUILD.gn
}

compiler.cxx_standard       2017

cmake.build_type            Release
cmake.generator             Ninja

supported_archs             arm64 x86_64
universal_variant           no

# https://github.com/aseprite/laf/issues/108
if {[vercmp ${macosx_deployment_target} >= 15.0]} {
    macosx_deployment_target 14.0
}

# The cmake portgroup clears configure.*_archflags at pre-configure time
# so we have to save it before then.
set archflags               [get_canonical_archflags]

configure.cppflags-replace  -I${prefix}/include -isystem${prefix}/include

pre-configure {
    switch ${build_arch} {
        x86_64 {
            set skia_cpu    x64
        }
        default {
            set skia_cpu    ${build_arch}
        }
    }
    # Using is_official_build=true and -frtti as suggested here:
    # https://github.com/aseprite/skia#skia-on-macos
    # is_official_build=true also turns on the use of system libraries.
    lappend skia_cflags     {*}${configure.cflags} \
                            {*}${archflags}
    lappend skia_cxxflags   {*}${configure.cxxflags} \
                            -frtti \
                            {*}${archflags}
    lappend skia_ldflags    {*}${configure.ldflags} \
                            {*}${archflags}
    lappend skia_configure_args \
                            cc="${configure.cc}" \
                            cxx="${configure.cxx}" \
                            extra_cflags_c=\[[join [map quoted_shellescape ${skia_cflags}] ,]\] \
                            extra_cflags_cc=\[[join [map quoted_shellescape ${skia_cxxflags}] ,]\] \
                            extra_ldflags=\[[join [map quoted_shellescape ${skia_ldflags}] ,]\] \
                            is_debug=false \
                            is_official_build=true \
                            skia_pdf_subset_harfbuzz=true \
                            skia_use_freetype=true \
                            skia_use_harfbuzz=true \
                            target_cpu="${skia_cpu}"
    if {${configure.ccache}} {
        lappend skia_configure_args \
                            cc_wrapper="${prefix}/bin/ccache"
    }
    system -W ${workpath}/skia "\
        PATH=${workpath}/depot_tools:$env(PATH) &&\
        export PATH &&\
        gn gen out/Release --args=[shellescape [join ${skia_configure_args}]] &&\
        ${prefix}/bin/ninja -vC out/Release skia modules\
        "
}

# Path to libskia.a (and the libraries it uses, to avoid undefined symbol errors).
lappend skia_libraries      ${workpath}/skia/out/Release/libskia.a \
                            ${prefix}/lib/libjpeg.dylib \
                            ${prefix}/lib/libpng.dylib \
                            ${prefix}/lib/libwebp.dylib \
                            ${prefix}/lib/libwebpdemux.dylib \
                            ${prefix}/lib/libwebpmux.dylib \
                            ${prefix}/lib/libz.dylib

# https://github.com/aseprite/aseprite/issues/4849
# This puts the "right" -I flags after the "wrong" ones but it's ok because
# DEPS.patch ensures the "wrong" directories won't exist.
configure.cppflags-append   -I${prefix}/include/freetype2 \
                            -I${prefix}/include/harfbuzz

configure.args              -DENABLE_BZip2=ON \
                            -DENABLE_LIBXML2=ON \
                            -DENABLE_LZMA=ON \
                            -DENABLE_UPDATER=OFF \
                            -DENABLE_WEBP=ON \
                            -DHARFBUZZ_LIBRARY=${prefix}/lib/libharfbuzz.dylib \
                            -DLAF_BACKEND=skia \
                            -DLAF_WITH_EXAMPLES=OFF \
                            -DPNG_SHARED=ON \
                            -DSKIA_DIR=${workpath}/skia \
                            -DSKIA_LIBRARY=[join ${skia_libraries} {\;}] \
                            -DSKIA_LIBRARY_DIR=${workpath}/skia/out/Release \
                            -DUSE_SHARED_CMARK=YES \
                            -DUSE_SHARED_CURL=YES \
                            -DUSE_SHARED_FREETYPE=YES \
                            -DUSE_SHARED_GIFLIB=YES \
                            -DUSE_SHARED_HARFBUZZ=YES \
                            -DUSE_SHARED_JPEGLIB=YES \
                            -DUSE_SHARED_LIBARCHIVE=YES \
                            -DUSE_SHARED_LIBPNG=YES \
                            -DUSE_SHARED_LIBWEBP=YES \
                            -DUSE_SHARED_PIXMAN=YES \
                            -DUSE_SHARED_TINYEXIF=YES \
                            -DUSE_SHARED_TINYXML=YES \
                            -DUSE_SHARED_ZLIB=YES \
                            -DWITH_BZip2=ON

app.executable              ${build.dir}/bin/aseprite
app.retina                  yes
# High-definition app icons are available in the hd subdirectory but
# the corresponding document and extension icons are not there yet
# so continue using the matched set of pixelated icons for now.
app.icon                    data/icons/ase256.png
set document_icon           data/icons/doc256.png
set extension_icon          data/icons/ext256.png

# The program is coded to look for its data in a relative path that assumes
# an app bundle layout, so we can't use the install target because it doesn't
# create an app bundle. https://github.com/aseprite/aseprite/issues/1366
destroot {
    copy ${worksrcpath}/data ${destroot}${applications_dir}/${app.name}.app/Contents/Resources
}

post-destroot {
    # Add extra keys, like document types, to Info.plist.
    set merge "Merge [shellescape ${filespath}/extra-Info.plist]"
    system -W ${destroot}${applications_dir}/${app.name}.app/Contents \
        "/usr/libexec/PlistBuddy Info.plist -c [shellescape ${merge}]"

    system -W ${destroot}${applications_dir}/${app.name}.app/Contents/Resources \
        "${prefix}/bin/makeicns -in [shellescape ${worksrcpath}/${document_icon}] -out Document.icns"
    system -W ${destroot}${applications_dir}/${app.name}.app/Contents/Resources \
        "${prefix}/bin/makeicns -in [shellescape ${worksrcpath}/${extension_icon}] -out Extension.icns"
}

# https://aseprite.org/faq/#if-aseprite-source-code-is-available-how-is-that-you-are-selling-it
notes "
${name} is free for personal and commercial use provided you compile it\
from source and that you do not redistribute the compiled binary. The\
MacPorts project does not distribute binaries of ${name}; instead, it\
compiles ${name} from source on your system, which is why it takes some\
time.

To support the developers and to show your appreciation, and to avoid\
the need to compile ${name} from source and instead receive an official\
binary from the developers, please purchase a license:

${homepage}/#buy

By using ${name} you agree to be bound by the terms of the end user\
license agreement which you can read here:

${github.raw}/${github.tag_prefix}${github.version}/EULA.txt

Documentation is available:

${homepage}/docs/

You may also find it helpful to read the frequently-asked questions:

${homepage}/faq/
"

github.livecheck.regex  {([0-9.]+)}