Skip to content

Commit

Permalink
Merge pull request #11476 from JuliaLang/teh/Pkg.free_many
Browse files Browse the repository at this point in the history
Let Pkg.free take an iterable to free multiple packages
  • Loading branch information
timholy committed May 29, 2015
2 parents ec37d6d + 3872dd6 commit 6b35206
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 49 deletions.
2 changes: 1 addition & 1 deletion base/pkg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ clone(url::AbstractString, pkg::AbstractString) = cd(Entry.clone,url,pkg)
checkout(pkg::AbstractString, branch::AbstractString="master"; merge::Bool=true, pull::Bool=true) =
cd(Entry.checkout,pkg,branch,merge,pull)

free(pkg::AbstractString) = cd(Entry.free,pkg)
free(pkg) = cd(Entry.free,pkg)

pin(pkg::AbstractString) = cd(Entry.pin,pkg)
pin(pkg::AbstractString, ver::VersionNumber) = cd(Entry.pin,pkg,ver)
Expand Down
24 changes: 24 additions & 0 deletions base/pkg/entry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,30 @@ function free(pkg::AbstractString)
end
end

function free(pkgs)
try
for pkg in pkgs
ispath(pkg,".git") || error("$pkg is not a git repo")
Read.isinstalled(pkg) || error("$pkg cannot be freed – not an installed package")
avail = Read.available(pkg)
isempty(avail) && error("$pkg cannot be freed – not a registered package")
Git.dirty(dir=pkg) && error("$pkg cannot be freed – repo is dirty")
info("Freeing $pkg")
vers = sort!(collect(keys(avail)), rev=true)
for ver in vers
sha1 = avail[ver].sha1
Git.iscommit(sha1, dir=pkg) || continue
Git.run(`checkout -q $sha1`, dir=pkg)
break
end
isempty(Cache.prefetch(pkg, Read.url(pkg), [a.sha1 for (v,a)=avail])) && continue
error("can't find any registered versions of $pkg to checkout")
end
finally
resolve()
end
end

function pin(pkg::AbstractString, head::AbstractString)
ispath(pkg,".git") || error("$pkg is not a git repo")
branch = "pinned.$(head[1:8]).tmp"
Expand Down
145 changes: 100 additions & 45 deletions doc/helpdb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1904,7 +1904,7 @@ Any[
julia> @enum FRUIT apple=1 orange=2 kiwi=3
julia> f(x::FRUIT) = \"I'm a FRUIT with value: \$(int(x))\"
julia> f(x::FRUIT) = \"I'm a FRUIT with value: \$(Int(x))\"
f (generic function with 1 method)
julia> f(apple)
Expand Down Expand Up @@ -2299,8 +2299,25 @@ Any[
("Base","@time","@time()
A macro to execute an expression, printing the time it took to
execute and the total number of bytes its execution caused to be
allocated, before returning the value of the expression.
execute, the number of allocations, and the total number of bytes
its execution caused to be allocated, before returning the value of
the expression.
"),

("Base","@timev","@timev()
This is a verbose version of the \"@time\" macro, it first prints
the same information as \"@time\", then any non-zero memory
allocation counters, and then returns the value of the expression.
"),

("Base","@timed","@timed()
A macro to execute an expression, and return the value of the
expression, elapsed time, total bytes allocated, garbage collection
time, and an object with various memory allocation counters.
"),

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

Expand Down Expand Up @@ -5261,10 +5283,10 @@ Millisecond(v)
"),

("Base","mv","mv(src::AbstractString,dst::AbstractString; remove_destination::Bool=false)
("Base","mv","mv(src::AbstractString, dst::AbstractString; remove_destination::Bool=false)
Move the file, link, or directory from *src* to *dest*.
\"remove_destination=true\" will first remove an existing `dst`.
\"remove_destination=true\" will first remove an existing *dst*.
"),

Expand Down Expand Up @@ -5295,16 +5317,18 @@ Millisecond(v)
"),

("Base","mktemp","mktemp()
("Base","mktemp","mktemp([parent=tempdir()])
Returns \"(path, io)\", where \"path\" is the path of a new
temporary file and \"io\" is an open file object for this path.
temporary file in \"parent\" and \"io\" is an open file object for
this path.
"),

("Base","mktempdir","mktempdir()
("Base","mktempdir","mktempdir([parent=tempdir()])
Create a temporary directory and return its path.
Create a temporary directory in the \"parent\" directory and return
its path.
"),

Expand Down Expand Up @@ -5355,6 +5379,12 @@ Millisecond(v)
"),

("Base","ismount","ismount(path) -> Bool
Returns \"true\" if \"path\" is a mount point, \"false\" otherwise.
"),

("Base","ispath","ispath(path) -> Bool
Returns \"true\" if \"path\" is a valid filesystem path, \"false\"
Expand Down Expand Up @@ -6199,8 +6229,8 @@ base64encode(args...)

("Base","base64decode","base64decode(string)
Decodes the base64-encoded \"string\" and returns the obtained
bytes.
Decodes the base64-encoded \"string\" and returns a
\"Vector{UInt8}\" of the decoded bytes.
"),

Expand Down Expand Up @@ -6901,6 +6931,15 @@ popdisplay(d::Display)
"),

("Base","vecdot","vecdot(x, y)
For any iterable containers \"x\" and \"y\" (including arrays of
any dimension) of numbers (or any element type for which \"dot\" is
defined), compute the Euclidean dot product (the sum of
\"dot(x[i],y[i])\") as if they were vectors.
"),

("Base","cross","cross(x, y)
×(x, y)
Expand Down Expand Up @@ -7715,8 +7754,9 @@ popdisplay(d::Display)
("Base","vecnorm","vecnorm(A[, p])
For any iterable container \"A\" (including arrays of any
dimension) of numbers, compute the \"p\"-norm (defaulting to
\"p=2\") as if \"A\" were a vector of the corresponding length.
dimension) of numbers (or any element type for which \"norm\" is
defined), compute the \"p\"-norm (defaulting to \"p=2\") as if
\"A\" were a vector of the corresponding length.
For example, if \"A\" is a matrix and \"p=2\", then this is
equivalent to the Frobenius norm.
Expand Down Expand Up @@ -11539,8 +11579,8 @@ golden

("Base","@task","@task()
Wrap an expression in a Task executing it, and return the Task.
This only creates a task, and does not run it.
Wrap an expression in a Task without executing it, and return the
Task. This only creates a task, and does not run it.
"),

Expand Down Expand Up @@ -12143,6 +12183,10 @@ golden
versions after. This is an inverse for both \"Pkg.checkout\" and
\"Pkg.pin\".
You can also supply an iterable collection of package names, e.g.,
\"Pkg.free((\"Pkg1\", \"Pkg2\"))\" to free multiple packages at
once.
"),

("Base.Pkg","build","build()
Expand Down Expand Up @@ -12508,12 +12552,30 @@ golden
"),

("Base","ascii","ascii(::Ptr{UInt8}[, length])
Create an ASCII string from the address of a C (0-terminated)
string encoded in ASCII. A copy is made; the ptr can be safely
freed. If \"length\" is specified, the string does not have to be
0-terminated.
"),

("Base","utf8","utf8(::Array{UInt8, 1})
Create a UTF-8 string from a byte array.
"),

("Base","utf8","utf8(::Ptr{UInt8}[, length])
Create a UTF-8 string from the address of a C (0-terminated) string
encoded in UTF-8. A copy is made; the ptr can be safely freed. If
\"length\" is specified, the string does not have to be
0-terminated.
"),

("Base","utf8","utf8(s)
Convert a string to a contiguous UTF-8 string (all characters must
Expand Down Expand Up @@ -12584,24 +12646,24 @@ golden
"),

("Base","is_valid_ascii","is_valid_ascii(s) -> Bool
("Base","isvalid","isvalid(value) -> Bool
Returns true if the argument (\"ASCIIString\", \"UTF8String\", or
byte vector) is valid ASCII, false otherwise.
Returns true if the given value is valid for its type, which
currently can be one of \"Char\", \"ASCIIString\", \"UTF8String\",
\"UTF16String\", or \"UTF32String\"
"),

("Base","is_valid_utf8","is_valid_utf8(s) -> Bool
("Base","isvalid","isvalid(T, value) -> Bool
Returns true if the argument (\"ASCIIString\", \"UTF8String\", or
byte vector) is valid UTF-8, false otherwise.
"),

("Base","is_valid_char","is_valid_char(c) -> Bool
Returns true if the given char or integer is a valid Unicode code
point.
Returns true if the given value is valid for that type. Types
currently can be \"Char\", \"ASCIIString\", \"UTF8String\",
\"UTF16String\", or \"UTF32String\" Values for \"Char\" can be of
type \"Char\" or \"UInt32\" Values for \"ASCIIString\" and
\"UTF8String\" can be of that type, or \"Vector{UInt8}\" Values for
\"UTF16String\" can be \"UTF16String\" or \"Vector{UInt16}\" Values
for \"UTF32String\" can be \"UTF32String\", \"Vector{Char}\" or
\"Vector{UInt32}\"
"),

Expand Down Expand Up @@ -13038,30 +13100,23 @@ golden
"),

("Base","is_valid_utf16","is_valid_utf16(s) -> Bool
Returns true if the argument (\"UTF16String\" or \"UInt16\" array)
is valid UTF-16.
"),

("Base","utf32","utf32(s)
Create a UTF-32 string from a byte array, array of \"UInt32\", or
any other string type. (Conversions of byte arrays check for a
byte-order marker in the first four bytes, and do not include it in
the resulting string.)
Create a UTF-32 string from a byte array, array of \"Char\" or
\"UInt32\", or any other string type. (Conversions of byte arrays
check for a byte-order marker in the first four bytes, and do not
include it in the resulting string.)
Note that the resulting \"UTF32String\" data is terminated by the
NUL codepoint (32-bit zero), which is not treated as a character in
the string (so that it is mostly invisible in Julia); this allows
the string to be passed directly to external functions requiring
NUL-terminated data. This NUL is appended automatically by the
*utf32(s)* conversion function. If you have a \"UInt32\" array
\"A\" that is already NUL-terminated UTF-32 data, then you can
instead use *UTF32String(A)`* to construct the string without
making a copy of the data and treating the NUL as a terminator
rather than as part of the string.
*utf32(s)* conversion function. If you have a \"Char\" or
\"UInt32\" array \"A\" that is already NUL-terminated UTF-32 data,
then you can instead use *UTF32String(A)`* to construct the string
without making a copy of the data and treating the NUL as a
terminator rather than as part of the string.
"),

Expand Down
4 changes: 3 additions & 1 deletion doc/stdlib/pkg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ to use them, you'll need to prefix each function call with an explicit ``Pkg.``,
It calls ``Pkg.resolve()`` to determine optimal package versions after.
This is an inverse for both ``Pkg.checkout`` and ``Pkg.pin``.

You can also supply an iterable collection of package names, e.g.,
``Pkg.free(("Pkg1", "Pkg2"))`` to free multiple packages at once.

.. function:: build()

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

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``.

19 changes: 17 additions & 2 deletions test/pkg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,29 @@ function temp_pkg_dir(fn::Function)
end
end

# Test adding or removing a package
#Also test for the existence of REUIRE and META_Branch
# Test basic operations: adding or removing a package, status, free
#Also test for the existence of REQUIRE and META_Branch
temp_pkg_dir() do
@test isfile(joinpath(Pkg.dir(),"REQUIRE"))
@test isfile(joinpath(Pkg.dir(),"META_BRANCH"))
@test isempty(Pkg.installed())
Pkg.add("Example")
@test [keys(Pkg.installed())...] == ["Example"]
iob = IOBuffer()
Pkg.checkout("Example")
Pkg.status("Example", iob)
str = chomp(takebuf_string(iob))
@test startswith(str, " - Example")
@test endswith(str, "master")
Pkg.free("Example")
Pkg.status("Example", iob)
str = chomp(takebuf_string(iob))
@test endswith(str, string(Pkg.installed("Example")))
Pkg.checkout("Example")
Pkg.free(("Example",))
Pkg.status("Example", iob)
str = chomp(takebuf_string(iob))
@test endswith(str, string(Pkg.installed("Example")))
Pkg.rm("Example")
@test isempty(Pkg.installed())
end
Expand Down

0 comments on commit 6b35206

Please sign in to comment.