• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37610

03 Sep 2023 03:55PM UTC coverage: 86.433% (-0.8%) from 87.218%
#37610

push

local

web-flow
Standardize the entry-point for Julia execution (#50974)

This is a bit of a straw-man proposal (though I think mergable if people
agree) to standardize the execution entrypoint for Julia scripts. I
think there's at least four different ways that people might run a
script:

- As `julia main.jl`
- As a PkgCompiler sysimage, then calling the main entry point
- As a PkgCompiler "app", with the magic `julia_main` function
- As a StaticCompiler product with an explicit entrypoint specified on
the API.

The main problem I have with all of these variants is that they're all
different and it's kind of a pain to move between them. Here I propose
that we standardize on `Main.main(ARGS)` as the entrypoint for all
scripts. Downstream from that proposal, this PR then makes the following
changes:

1. If a system image has an existing `Main.main`, that is the entry
point for `julia -Jsysimage.so`.
2. If not, and the sysimage has a REPL, we call REPL.main (we could
handle this by defaulting `Main.main` to a weak import of `REPL.main`,
but for the purpose of this PR, it's an explicit fallback. That said, I
do want to emhpasize the direction of moving the REPL to be "just
another app".
3. If the REPL code is called and passed a script file, the REPL
executes any newly defined Main.main after loading the script file. As a
result, `julia` behaves the same as if we had generated a new system
image after loading `main.jl` and then running julia with that system
image.

The further downstream implication of this is that I'd like to get rid
of the distinction between PkgCompiler apps and system images. An app is
simply a system image with a `Main.main` function defined (note that
currently PkgCompiler uses `julia_main` instead).

---------

Co-authored-by: Martijn Visser <mgvisser@gmail.com>

25 of 25 new or added lines in 2 files covered. (100.0%)

73492 of 85028 relevant lines covered (86.43%)

13617619.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

38.74
/stdlib/Markdown/src/render/terminal/render.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
include("formatting.jl")
4

5
cols(io) = displaysize(io)[2]
3✔
6

7
function term(io::IO, content::Vector, cols)
8✔
8
    isempty(content) && return
8✔
9
    for md in content[1:end-1]
14✔
10
        term(io, md, cols)
10✔
11
        print(io, '\n', '\n')
10✔
12
    end
12✔
13
    term(io, content[end], cols)
8✔
14
end
15

16
term(io::IO, md::MD, columns = cols(io)) = term(io, md.content, columns)
11✔
17

18
function term(io::IO, md::Paragraph, columns)
9✔
19
    print(io, ' '^margin)
9✔
20
    print_wrapped(io, width = columns-2margin, pre = ' '^margin) do io
9✔
21
        terminline(io, md.content)
9✔
22
    end
23
end
24

25
function term(io::IO, md::BlockQuote, columns)
×
26
    s = sprint(term, md.content, columns - 10; context=io)
×
27
    lines = split(rstrip(s), '\n')
×
28
    print(io, ' '^margin, '│', lines[1])
×
29
    for i = 2:length(lines)
×
30
        print(io, '\n', ' '^margin, '│', lines[i])
×
31
    end
×
32
end
33

34
function term(io::IO, md::Admonition, columns)
×
35
    col = :default
×
36
    # If the types below are modified, the page manual/documentation.md must be updated accordingly.
37
    if md.category == "danger"
×
38
        col = Base.error_color()
×
39
    elseif md.category == "warning"
×
40
        col = Base.warn_color()
×
41
    elseif md.category in ("info", "note")
×
42
        col = Base.info_color()
×
43
    elseif md.category == "tip"
×
44
        col = :green
×
45
    end
46
    printstyled(io, ' '^margin, "│ "; color=col, bold=true)
×
47
    printstyled(io, isempty(md.title) ? md.category : md.title; color=col, bold=true)
×
48
    printstyled(io, '\n', ' '^margin, '│', '\n'; color=col, bold=true)
×
49
    s = sprint(term, md.content, columns - 10; context=io)
×
50
    lines = split(rstrip(s), '\n')
×
51
    for i in eachindex(lines)
×
52
        printstyled(io, ' '^margin, '│'; color=col, bold=true)
×
53
        print(io, lines[i])
×
54
        i < lastindex(lines) && println(io)
×
55
    end
×
56
end
57

58
function term(io::IO, f::Footnote, columns)
×
59
    print(io, ' '^margin, "│ ")
×
60
    printstyled(io, "[^$(f.id)]", bold=true)
×
61
    println(io, '\n', ' '^margin, '│')
×
62
    s = sprint(term, f.text, columns - 10; context=io)
×
63
    lines = split(rstrip(s), '\n')
×
64
    for i in eachindex(lines)
×
65
        print(io, ' '^margin, '│', lines[i])
×
66
        i < lastindex(lines) && println(io)
×
67
    end
×
68
end
69

70
function term(io::IO, md::List, columns)
×
71
    for (i, point) in enumerate(md.items)
×
72
        print(io, ' '^2margin, isordered(md) ? "$(i + md.ordered - 1). " : "•  ")
×
73
        print_wrapped(io, width = columns-(4margin+2), pre = ' '^(2margin+3),
×
74
                          i = 2margin+2) do io
75
            term(io, point, columns - 10)
×
76
        end
77
        i < lastindex(md.items) && print(io, '\n', '\n')
×
78
    end
×
79
end
80

81
function _term_header(io::IO, md, char, columns)
1✔
82
    text = terminline_string(io, md.text)
1✔
83
    with_output_color(:bold, io) do io
1✔
84
        pre = ' '^margin
1✔
85
        print(io, pre)
1✔
86
        line_no, lastline_width = print_wrapped(io, text,
1✔
87
                                                width=columns - 4margin; pre)
88
        line_width = min(lastline_width, columns)
1✔
89
        if line_no > 1
1✔
90
            line_width = max(line_width, div(columns, 3)+length(pre))
×
91
        end
92
        header_width = max(0, line_width-length(pre))
1✔
93
        char != ' ' && header_width > 0 && print(io, '\n', ' '^(margin), char^header_width)
1✔
94
    end
95
end
96

97
const _header_underlines = collect("≡=–-⋅ ")
98
# TODO settle on another option with unicode e.g. "≡=≃–∼⋅" ?
99

100
function term(io::IO, md::Header{l}, columns) where l
1✔
101
    underline = _header_underlines[l]
1✔
102
    _term_header(io, md, underline, columns)
1✔
103
end
104

105
function term(io::IO, md::Code, columns)
3✔
106
    with_output_color(:cyan, io) do io
3✔
107
        L = lines(md.code)
3✔
108
        for i in eachindex(L)
6✔
109
            print(io, ' '^margin, L[i])
57✔
110
            i < lastindex(L) && println(io)
57✔
111
        end
57✔
112
    end
113
end
114

115
function term(io::IO, tex::LaTeX, columns)
×
116
    printstyled(io, ' '^margin, tex.formula, color=:magenta)
×
117
end
118

119
term(io::IO, br::LineBreak, columns) = nothing # line breaks already printed between subsequent elements
×
120

121
function term(io::IO, br::HorizontalRule, columns)
×
122
   print(io, ' '^margin, '─'^(columns - 2margin))
×
123
end
124

125
term(io::IO, x, _) = show(io, MIME"text/plain"(), x)
×
126

127
# Inline Content
128

129
terminline_string(io::IO, md) = sprint(terminline, md; context=io)
1✔
130

131
terminline(io::IO, content...) = terminline(io, collect(content))
×
132

133
function terminline(io::IO, content::Vector)
10✔
134
    for md in content
10✔
135
        terminline(io, md)
28✔
136
    end
28✔
137
end
138

139
function terminline(io::IO, md::AbstractString)
18✔
140
    print(io, replace(md, r"[\s\t\n]+" => ' '))
18✔
141
end
142

143
function terminline(io::IO, md::Bold)
×
144
    with_output_color(terminline, :bold, io, md.text)
×
145
end
146

147
function terminline(io::IO, md::Italic)
×
148
    with_output_color(terminline, :underline, io, md.text)
×
149
end
150

151
function terminline(io::IO, md::LineBreak)
×
152
    println(io)
×
153
end
154

155
function terminline(io::IO, md::Image)
×
156
    terminline(io, "(Image: $(md.alt))")
×
157
end
158

159
terminline(io::IO, f::Footnote) = with_output_color(terminline, :bold, io, "[^$(f.id)]")
×
160

161
function terminline(io::IO, md::Link)
×
162
    url = !Base.startswith(md.url, "@ref") ? " ($(md.url))" : ""
×
163
    text = terminline_string(io, md.text)
×
164
    terminline(io, text, url)
×
165
end
166

167
function terminline(io::IO, code::Code)
10✔
168
    printstyled(io, code.code, color=:cyan)
10✔
169
end
170

171
function terminline(io::IO, tex::LaTeX)
×
172
    printstyled(io, tex.formula, color=:magenta)
×
173
end
174

175
terminline(io::IO, x) = show(io, MIME"text/plain"(), x)
×
176

177
# Show in terminal
178
Base.show(io::IO, ::MIME"text/plain", md::MD) = (term(io, md); nothing)
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc