#64326 closed defect (invalid)

app PortGroup: app.name unable to handle names with spaces

Reported by: jasonliu-- (Jason Liu) Owned by:
Priority: Normal Milestone:
Component: ports Version: 2.7.1
Keywords: Cc:
Port: pg-app-1.0

Description

Similar to ticket #64325, when an app.name is specified with spaces in it, the resulting app bundle has curly braces around the name. The iterations that I've tried are:

app.name    "AppName With Spaces"
app.name    "AppName\ With\ Spaces"
app.name    {AppName With Spaces}
app.name    AppName\ With\ Spaces}

All of them result in the app bundle being created with a name of {AppName With Spaces}.app, with literal curly braces surrounding the name, or {AppName\ With\ Spaces}.app, with literal curly braces and backslashes.

Attachments (1)

Portfile (982 bytes) - added by jasonliu-- (Jason Liu) 13 months ago.
I'm attaching a simple mock-up Portfile that I've been using, for ease of testing. Simply place it inside of a "testpgapp" directory, which can be created inside any of the categories folders.

Download all attachments as: .zip

Change History (11)

comment:1 Changed 13 months ago by ryandesign (Ryan Schmidt)

Did you try:

app.name    AppName With Spaces

Works fine in the chromium-bsu, frozenbubble2, and wesnoth ports, for example.

comment:2 Changed 13 months ago by jmroot (Joshua Root)

There might be an issue in _write_launch_script due to ${executable} not being quoted.

comment:3 in reply to:  1 Changed 13 months ago by jasonliu-- (Jason Liu)

Replying to ryandesign:

Did you try:

app.name    AppName With Spaces

Works fine in the chromium-bsu, frozenbubble2, and wesnoth ports, for example.

Ironically no, that was the one iteration I didn't try! And yes you're right, it does work, although years of programming has been drilled into me to never try to use a string naked like that, lol! Also, it would seem to preclude the use of names that have been stored in a variables, since

set foo  AppName With Spaces
app.name $foo

throws a Tcl error of wrong # args: should be "set varName ?newValue?", and

set foo  "AppName With Spaces"
# or
set foo  {AppName With Spaces}

# in combination with any of

app.name $foo
# or
app.name "$foo"
# or
app.name {$foo}

goes right back to resulting in an output of {AppName With Spaces}.app. (The last app.name actually results in {$foo}.app, lol)

Last edited 13 months ago by jasonliu-- (Jason Liu) (previous) (diff)

Changed 13 months ago by jasonliu-- (Jason Liu)

Attachment: Portfile added

I'm attaching a simple mock-up Portfile that I've been using, for ease of testing. Simply place it inside of a "testpgapp" directory, which can be created inside any of the categories folders.

comment:4 in reply to:  2 ; Changed 13 months ago by ryandesign (Ryan Schmidt)

Replying to jmroot:

There might be an issue in _write_launch_script due to ${executable} not being quoted.

No idea. Haven't looked at it. I wasn't involved in the "launch script" improvements that were added to the portgroup.

Replying to jasonliu--:

Replying to ryandesign:

Did you try:

app.name    AppName With Spaces

Works fine in the chromium-bsu, frozenbubble2, and wesnoth ports, for example.

Ironically no, that was the one iteration I didn't try! And yes you're right, it does work, although years of programming has been drilled into me to never try to use a string naked like that, lol!

One of the main reasons why Tcl was chosen as the language to use for MacPorts Portfiles is that it makes a bunch of extra quoting like that unnecessary.

Also, it would seem to preclude the use of names that have been stored in a variables, since

set foo  AppName With Spaces
app.name $foo

throws a Tcl error of wrong # args: should be "set varName ?newValue?",

Correct; what you wrote is a syntax error. set accepts two arguments: the name of the variable followed by the value.

MacPorts options (like app.name) are treated not as simple variables but as lists with an arbitrary number of elements. However some options (like app.name) for which a list of items doesn't make any sense instead treat it as a single value. app.name some long name technically sets the app.name option to a three item list ("some", "long", "name") but since a list doesn't make sense in this context, the app portgroup concatenates all the values into a single string separated by spaces.

set foo  "AppName With Spaces"
# or
set foo  {AppName With Spaces}

Right, that's the correct way to set a variable to that string. What quoting character you use — quote or curly brace — is irrelevant if you don't have any variable substitutions within the string.

app.name $foo
# or
app.name "$foo"
# or
app.name {$foo}

If you want to do it this way, you'll have to expand the variable:

app.name {*}$foo

It was not anticipated that anyone would have a need to use a separate variable here. Why do you?

Last edited 13 months ago by ryandesign (Ryan Schmidt) (previous) (diff)

comment:5 in reply to:  4 ; Changed 13 months ago by jasonliu-- (Jason Liu)

Replying to ryandesign:

It was not anticipated that anyone would have a need to use a separate variable here. Why do you?

Really? I'm a bit surprised that no one has encountered the following situation when writing a portfile:

name            shortname
set pretty_name "Long Name with Capitalization and Spaces"

app.name        $pretty_name
app.executable  ${name}

(Of course, based on your previous comment, as things currently stand, that would have to be app.name {*}$pretty_name.)

To me, this scenario makes the most sense, because you want to be able to launch the application from the command line using shortname, but you want to see the long, proper name in the Finder window.

comment:6 in reply to:  5 ; Changed 13 months ago by ryandesign (Ryan Schmidt)

Replying to jasonliu--:

Replying to ryandesign:

It was not anticipated that anyone would have a need to use a separate variable here. Why do you?

Really? I'm a bit surprised that no one has encountered the following situation when writing a portfile:

name            shortname
set pretty_name "Long Name with Capitalization and Spaces"

app.name        $pretty_name
app.executable  ${name}

Again: why do you want to create two variables when one is sufficient?

name            shortname
app.name        Long Name with Capitalization and Spaces

The default for app.executable is $name so most times you don't need to override it either. Please read the extensive comments I left in the app portgroup explaining how it is intended to be used.

comment:7 in reply to:  6 ; Changed 13 months ago by jasonliu-- (Jason Liu)

Replying to ryandesign:

Replying to jasonliu--:

Replying to ryandesign:

It was not anticipated that anyone would have a need to use a separate variable here. Why do you?

Really? I'm a bit surprised that no one has encountered the following situation when writing a portfile:

name            shortname
set pretty_name "Long Name with Capitalization and Spaces"

app.name        $pretty_name
app.executable  ${name}

Again: why do you want to create two variables when one is sufficient?

name            shortname
app.name        Long Name with Capitalization and Spaces

The default for app.executable is $name so most times you don't need to override it either. Please read the extensive comments I left in the app portgroup explaining how it is intended to be used.

I never created two variables, at least not intentionally. Particularly if a port has multiple subports, only one of which uses the app PortGroup, defining $pretty_name near the top of the file allows it to be used in all of the subports, including the ones that don't use the app PortGroup. A more complete example than the snippet I provided would have been:

name                short name
set pretty_name     "Long Name with Capitalization and Spaces"

long_description    $pretty_name is a blah blah blah...

if {$subport eq "${name}-auxiliary"} {
    # Other code that uses $pretty_name
}

patchfiles ...
post-patch {
    ...
}

configure.args-append ...

if {$subport eq ${name}} {
    PortGroup app 1.0

    app.name  $pretty_name
    app.icon  ...
}
post-destroot {
    ...
}

And yes, including the app.executable $name in the example snippet was unnecessary, but that's not what this ticket is about anyway.

comment:8 in reply to:  7 Changed 13 months ago by ryandesign (Ryan Schmidt)

Replying to jasonliu--:

I never created two variables, at least not intentionally.

Well the app.name option ("variable") already exists, and you're creating a new variable pretty_name and then setting app.name to it, for what to me was is discernible reason other than making things more confusing.

Particularly if a port has multiple subports, only one of which uses the app PortGroup, defining $pretty_name near the top of the file allows it to be used in all of the subports, including the ones that don't use the app PortGroup.

You have multiple subports that install apps of the same name? That's weird.

Include the app portgroup at the top of the portfile, unconditionally. Indeed the app portgroup was not designed with subports in mind, in that it does have consequences the moment it is included, however by setting app.create no soon after, those consequences are disabled. Then, in the subports in which you want apps created, use app.create yes. Now you can use the existing app.name option as intended, even globally, and not need a second variable.

comment:9 Changed 13 months ago by ryandesign (Ryan Schmidt)

In 77b0ef9d4f22af40106e3f376a4a1e1d229ae49a/macports-ports (master):

app-1.0.tcl: Use shellescape

See: #64326

comment:10 Changed 13 months ago by ryandesign (Ryan Schmidt)

Resolution: invalid
Status: newclosed

I'll close this now, since app.name is able to handle spaces.

Note: See TracTickets for help on using tickets.