Skip to content

Commit 6b35206

Browse files
committed
Merge pull request #11476 from JuliaLang/teh/Pkg.free_many
Let Pkg.free take an iterable to free multiple packages
2 parents ec37d6d + 3872dd6 commit 6b35206

File tree

5 files changed

+145
-49
lines changed

5 files changed

+145
-49
lines changed

base/pkg.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ clone(url::AbstractString, pkg::AbstractString) = cd(Entry.clone,url,pkg)
3737
checkout(pkg::AbstractString, branch::AbstractString="master"; merge::Bool=true, pull::Bool=true) =
3838
cd(Entry.checkout,pkg,branch,merge,pull)
3939

40-
free(pkg::AbstractString) = cd(Entry.free,pkg)
40+
free(pkg) = cd(Entry.free,pkg)
4141

4242
pin(pkg::AbstractString) = cd(Entry.pin,pkg)
4343
pin(pkg::AbstractString, ver::VersionNumber) = cd(Entry.pin,pkg,ver)

base/pkg/entry.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,30 @@ function free(pkg::AbstractString)
217217
end
218218
end
219219

220+
function free(pkgs)
221+
try
222+
for pkg in pkgs
223+
ispath(pkg,".git") || error("$pkg is not a git repo")
224+
Read.isinstalled(pkg) || error("$pkg cannot be freed – not an installed package")
225+
avail = Read.available(pkg)
226+
isempty(avail) && error("$pkg cannot be freed – not a registered package")
227+
Git.dirty(dir=pkg) && error("$pkg cannot be freed – repo is dirty")
228+
info("Freeing $pkg")
229+
vers = sort!(collect(keys(avail)), rev=true)
230+
for ver in vers
231+
sha1 = avail[ver].sha1
232+
Git.iscommit(sha1, dir=pkg) || continue
233+
Git.run(`checkout -q $sha1`, dir=pkg)
234+
break
235+
end
236+
isempty(Cache.prefetch(pkg, Read.url(pkg), [a.sha1 for (v,a)=avail])) && continue
237+
error("can't find any registered versions of $pkg to checkout")
238+
end
239+
finally
240+
resolve()
241+
end
242+
end
243+
220244
function pin(pkg::AbstractString, head::AbstractString)
221245
ispath(pkg,".git") || error("$pkg is not a git repo")
222246
branch = "pinned.$(head[1:8]).tmp"

doc/helpdb.jl

Lines changed: 100 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,7 +1904,7 @@ Any[
19041904
19051905
julia> @enum FRUIT apple=1 orange=2 kiwi=3
19061906
1907-
julia> f(x::FRUIT) = \"I'm a FRUIT with value: \$(int(x))\"
1907+
julia> f(x::FRUIT) = \"I'm a FRUIT with value: \$(Int(x))\"
19081908
f (generic function with 1 method)
19091909
19101910
julia> f(apple)
@@ -2299,8 +2299,25 @@ Any[
22992299
("Base","@time","@time()
23002300
23012301
A macro to execute an expression, printing the time it took to
2302-
execute and the total number of bytes its execution caused to be
2303-
allocated, before returning the value of the expression.
2302+
execute, the number of allocations, and the total number of bytes
2303+
its execution caused to be allocated, before returning the value of
2304+
the expression.
2305+
2306+
"),
2307+
2308+
("Base","@timev","@timev()
2309+
2310+
This is a verbose version of the \"@time\" macro, it first prints
2311+
the same information as \"@time\", then any non-zero memory
2312+
allocation counters, and then returns the value of the expression.
2313+
2314+
"),
2315+
2316+
("Base","@timed","@timed()
2317+
2318+
A macro to execute an expression, and return the value of the
2319+
expression, elapsed time, total bytes allocated, garbage collection
2320+
time, and an object with various memory allocation counters.
23042321
23052322
"),
23062323

@@ -2316,7 +2333,12 @@ Any[
23162333
23172334
A macro to evaluate an expression, discarding the resulting value,
23182335
instead returning the total number of bytes allocated during
2319-
evaluation of the expression.
2336+
evaluation of the expression. Note: the expression is evaluated
2337+
inside a local function, instead of the current context, in order
2338+
to eliminate the effects of compilation, however, there still may
2339+
be some allocations due to JIT compilation. This also makes the
2340+
results inconsistent with the \"@time\" macros, which do not try to
2341+
adjust for the effects of compilation.
23202342
23212343
"),
23222344

@@ -5261,10 +5283,10 @@ Millisecond(v)
52615283
52625284
"),
52635285

5264-
("Base","mv","mv(src::AbstractString,dst::AbstractString; remove_destination::Bool=false)
5286+
("Base","mv","mv(src::AbstractString, dst::AbstractString; remove_destination::Bool=false)
52655287
52665288
Move the file, link, or directory from *src* to *dest*.
5267-
\"remove_destination=true\" will first remove an existing `dst`.
5289+
\"remove_destination=true\" will first remove an existing *dst*.
52685290
52695291
"),
52705292

@@ -5295,16 +5317,18 @@ Millisecond(v)
52955317
52965318
"),
52975319

5298-
("Base","mktemp","mktemp()
5320+
("Base","mktemp","mktemp([parent=tempdir()])
52995321
53005322
Returns \"(path, io)\", where \"path\" is the path of a new
5301-
temporary file and \"io\" is an open file object for this path.
5323+
temporary file in \"parent\" and \"io\" is an open file object for
5324+
this path.
53025325
53035326
"),
53045327

5305-
("Base","mktempdir","mktempdir()
5328+
("Base","mktempdir","mktempdir([parent=tempdir()])
53065329
5307-
Create a temporary directory and return its path.
5330+
Create a temporary directory in the \"parent\" directory and return
5331+
its path.
53085332
53095333
"),
53105334

@@ -5355,6 +5379,12 @@ Millisecond(v)
53555379
53565380
"),
53575381

5382+
("Base","ismount","ismount(path) -> Bool
5383+
5384+
Returns \"true\" if \"path\" is a mount point, \"false\" otherwise.
5385+
5386+
"),
5387+
53585388
("Base","ispath","ispath(path) -> Bool
53595389
53605390
Returns \"true\" if \"path\" is a valid filesystem path, \"false\"
@@ -6199,8 +6229,8 @@ base64encode(args...)
61996229

62006230
("Base","base64decode","base64decode(string)
62016231
6202-
Decodes the base64-encoded \"string\" and returns the obtained
6203-
bytes.
6232+
Decodes the base64-encoded \"string\" and returns a
6233+
\"Vector{UInt8}\" of the decoded bytes.
62046234
62056235
"),
62066236

@@ -6901,6 +6931,15 @@ popdisplay(d::Display)
69016931
69026932
"),
69036933

6934+
("Base","vecdot","vecdot(x, y)
6935+
6936+
For any iterable containers \"x\" and \"y\" (including arrays of
6937+
any dimension) of numbers (or any element type for which \"dot\" is
6938+
defined), compute the Euclidean dot product (the sum of
6939+
\"dot(x[i],y[i])\") as if they were vectors.
6940+
6941+
"),
6942+
69046943
("Base","cross","cross(x, y)
69056944
×(x, y)
69066945
@@ -7715,8 +7754,9 @@ popdisplay(d::Display)
77157754
("Base","vecnorm","vecnorm(A[, p])
77167755
77177756
For any iterable container \"A\" (including arrays of any
7718-
dimension) of numbers, compute the \"p\"-norm (defaulting to
7719-
\"p=2\") as if \"A\" were a vector of the corresponding length.
7757+
dimension) of numbers (or any element type for which \"norm\" is
7758+
defined), compute the \"p\"-norm (defaulting to \"p=2\") as if
7759+
\"A\" were a vector of the corresponding length.
77207760
77217761
For example, if \"A\" is a matrix and \"p=2\", then this is
77227762
equivalent to the Frobenius norm.
@@ -11539,8 +11579,8 @@ golden
1153911579

1154011580
("Base","@task","@task()
1154111581
11542-
Wrap an expression in a Task executing it, and return the Task.
11543-
This only creates a task, and does not run it.
11582+
Wrap an expression in a Task without executing it, and return the
11583+
Task. This only creates a task, and does not run it.
1154411584
1154511585
"),
1154611586

@@ -12143,6 +12183,10 @@ golden
1214312183
versions after. This is an inverse for both \"Pkg.checkout\" and
1214412184
\"Pkg.pin\".
1214512185
12186+
You can also supply an iterable collection of package names, e.g.,
12187+
\"Pkg.free((\"Pkg1\", \"Pkg2\"))\" to free multiple packages at
12188+
once.
12189+
1214612190
"),
1214712191

1214812192
("Base.Pkg","build","build()
@@ -12508,12 +12552,30 @@ golden
1250812552
1250912553
"),
1251012554

12555+
("Base","ascii","ascii(::Ptr{UInt8}[, length])
12556+
12557+
Create an ASCII string from the address of a C (0-terminated)
12558+
string encoded in ASCII. A copy is made; the ptr can be safely
12559+
freed. If \"length\" is specified, the string does not have to be
12560+
0-terminated.
12561+
12562+
"),
12563+
1251112564
("Base","utf8","utf8(::Array{UInt8, 1})
1251212565
1251312566
Create a UTF-8 string from a byte array.
1251412567
1251512568
"),
1251612569

12570+
("Base","utf8","utf8(::Ptr{UInt8}[, length])
12571+
12572+
Create a UTF-8 string from the address of a C (0-terminated) string
12573+
encoded in UTF-8. A copy is made; the ptr can be safely freed. If
12574+
\"length\" is specified, the string does not have to be
12575+
0-terminated.
12576+
12577+
"),
12578+
1251712579
("Base","utf8","utf8(s)
1251812580
1251912581
Convert a string to a contiguous UTF-8 string (all characters must
@@ -12584,24 +12646,24 @@ golden
1258412646
1258512647
"),
1258612648

12587-
("Base","is_valid_ascii","is_valid_ascii(s) -> Bool
12649+
("Base","isvalid","isvalid(value) -> Bool
1258812650
12589-
Returns true if the argument (\"ASCIIString\", \"UTF8String\", or
12590-
byte vector) is valid ASCII, false otherwise.
12651+
Returns true if the given value is valid for its type, which
12652+
currently can be one of \"Char\", \"ASCIIString\", \"UTF8String\",
12653+
\"UTF16String\", or \"UTF32String\"
1259112654
1259212655
"),
1259312656

12594-
("Base","is_valid_utf8","is_valid_utf8(s) -> Bool
12657+
("Base","isvalid","isvalid(T, value) -> Bool
1259512658
12596-
Returns true if the argument (\"ASCIIString\", \"UTF8String\", or
12597-
byte vector) is valid UTF-8, false otherwise.
12598-
12599-
"),
12600-
12601-
("Base","is_valid_char","is_valid_char(c) -> Bool
12602-
12603-
Returns true if the given char or integer is a valid Unicode code
12604-
point.
12659+
Returns true if the given value is valid for that type. Types
12660+
currently can be \"Char\", \"ASCIIString\", \"UTF8String\",
12661+
\"UTF16String\", or \"UTF32String\" Values for \"Char\" can be of
12662+
type \"Char\" or \"UInt32\" Values for \"ASCIIString\" and
12663+
\"UTF8String\" can be of that type, or \"Vector{UInt8}\" Values for
12664+
\"UTF16String\" can be \"UTF16String\" or \"Vector{UInt16}\" Values
12665+
for \"UTF32String\" can be \"UTF32String\", \"Vector{Char}\" or
12666+
\"Vector{UInt32}\"
1260512667
1260612668
"),
1260712669

@@ -13038,30 +13100,23 @@ golden
1303813100
1303913101
"),
1304013102

13041-
("Base","is_valid_utf16","is_valid_utf16(s) -> Bool
13042-
13043-
Returns true if the argument (\"UTF16String\" or \"UInt16\" array)
13044-
is valid UTF-16.
13045-
13046-
"),
13047-
1304813103
("Base","utf32","utf32(s)
1304913104
13050-
Create a UTF-32 string from a byte array, array of \"UInt32\", or
13051-
any other string type. (Conversions of byte arrays check for a
13052-
byte-order marker in the first four bytes, and do not include it in
13053-
the resulting string.)
13105+
Create a UTF-32 string from a byte array, array of \"Char\" or
13106+
\"UInt32\", or any other string type. (Conversions of byte arrays
13107+
check for a byte-order marker in the first four bytes, and do not
13108+
include it in the resulting string.)
1305413109
1305513110
Note that the resulting \"UTF32String\" data is terminated by the
1305613111
NUL codepoint (32-bit zero), which is not treated as a character in
1305713112
the string (so that it is mostly invisible in Julia); this allows
1305813113
the string to be passed directly to external functions requiring
1305913114
NUL-terminated data. This NUL is appended automatically by the
13060-
*utf32(s)* conversion function. If you have a \"UInt32\" array
13061-
\"A\" that is already NUL-terminated UTF-32 data, then you can
13062-
instead use *UTF32String(A)`* to construct the string without
13063-
making a copy of the data and treating the NUL as a terminator
13064-
rather than as part of the string.
13115+
*utf32(s)* conversion function. If you have a \"Char\" or
13116+
\"UInt32\" array \"A\" that is already NUL-terminated UTF-32 data,
13117+
then you can instead use *UTF32String(A)`* to construct the string
13118+
without making a copy of the data and treating the NUL as a
13119+
terminator rather than as part of the string.
1306513120
1306613121
"),
1306713122

doc/stdlib/pkg.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ to use them, you'll need to prefix each function call with an explicit ``Pkg.``,
105105
It calls ``Pkg.resolve()`` to determine optimal package versions after.
106106
This is an inverse for both ``Pkg.checkout`` and ``Pkg.pin``.
107107

108+
You can also supply an iterable collection of package names, e.g.,
109+
``Pkg.free(("Pkg1", "Pkg2"))`` to free multiple packages at once.
110+
108111
.. function:: build()
109112

110113
Run the build scripts for all installed packages in depth-first recursive order.
@@ -142,4 +145,3 @@ to use them, you'll need to prefix each function call with an explicit ``Pkg.``,
142145
.. function:: test(pkgs...)
143146

144147
Run the tests for each package in ``pkgs`` ensuring that each package's test dependencies are installed for the duration of the test. A package is tested by running its ``test/runtests.jl`` file and test dependencies are specified in ``test/REQUIRE``.
145-

test/pkg.jl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,29 @@ function temp_pkg_dir(fn::Function)
1515
end
1616
end
1717

18-
# Test adding or removing a package
19-
#Also test for the existence of REUIRE and META_Branch
18+
# Test basic operations: adding or removing a package, status, free
19+
#Also test for the existence of REQUIRE and META_Branch
2020
temp_pkg_dir() do
2121
@test isfile(joinpath(Pkg.dir(),"REQUIRE"))
2222
@test isfile(joinpath(Pkg.dir(),"META_BRANCH"))
2323
@test isempty(Pkg.installed())
2424
Pkg.add("Example")
2525
@test [keys(Pkg.installed())...] == ["Example"]
26+
iob = IOBuffer()
27+
Pkg.checkout("Example")
28+
Pkg.status("Example", iob)
29+
str = chomp(takebuf_string(iob))
30+
@test startswith(str, " - Example")
31+
@test endswith(str, "master")
32+
Pkg.free("Example")
33+
Pkg.status("Example", iob)
34+
str = chomp(takebuf_string(iob))
35+
@test endswith(str, string(Pkg.installed("Example")))
36+
Pkg.checkout("Example")
37+
Pkg.free(("Example",))
38+
Pkg.status("Example", iob)
39+
str = chomp(takebuf_string(iob))
40+
@test endswith(str, string(Pkg.installed("Example")))
2641
Pkg.rm("Example")
2742
@test isempty(Pkg.installed())
2843
end

0 commit comments

Comments
 (0)