From c4a307806332282128e20c95215491335bb94735 Mon Sep 17 00:00:00 2001 From: Matthias BUSSONNIER Date: Sat, 26 Jul 2014 22:40:10 +0200 Subject: [PATCH 1/7] Add kernelspec for IPython 3.0 There is still the limitation that object inspection will not work with identifiers that have a bang (!) in the name while IJulia does not support the kernelspec v5. --- .gitignore | 1 + deps/build.jl | 44 ++++++++++++++++++++++++++++++++++++++++---- deps/logo-32x32.png | Bin 0 -> 1310 bytes deps/logo-64x64.png | Bin 0 -> 2843 bytes 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 deps/logo-32x32.png create mode 100644 deps/logo-64x64.png diff --git a/.gitignore b/.gitignore index 864fa4bc..b2ce2594 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.pyc +*.un~ /build/ diff --git a/deps/build.jl b/deps/build.jl index f1f994c5..ca9b65fc 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -1,6 +1,7 @@ # TODO: Build IPython 1.0 dependency? (wait for release?) ####################################################################### +import JSON # print to stderr, since that is where Pkg prints its messages eprintln(x...) = println(STDERR, x...) @@ -69,10 +70,15 @@ if VERSION >= v"0.3-" else binary_name = "julia-basic" end + +kernelcmd_array = VERSION >= v"0.3"? + ["$(escape_string(joinpath(JULIA_HOME,(@windows? "julia.exe":"$binary_name"))))", "-i", "-F", "$(escape_string(joinpath(Pkg.dir("IJulia"),"src","kernel.jl")))", "{connection_file}"]: + ["$(escape_string(joinpath(JULIA_HOME,(@windows? "julia.bat":"$binary_name"))))", "-F", "$(escape_string(joinpath(Pkg.dir("IJulia"),"src","kernel.jl")))", "{connection_file}"] + +kernelcmd = JSON.json(kernelcmd_array) + add_config("ipython_config.py", "KernelManager.kernel_cmd", - VERSION >= v"0.3"? - """["$(escape_string(joinpath(JULIA_HOME,(@windows? "julia.exe":"$binary_name"))))", "-i", "-F", "$(escape_string(joinpath(Pkg.dir("IJulia"),"src","kernel.jl")))", "{connection_file}"]""": - """["$(escape_string(joinpath(JULIA_HOME,(@windows? "julia.bat":"$binary_name"))))", "-F", "$(escape_string(joinpath(Pkg.dir("IJulia"),"src","kernel.jl")))", "{connection_file}"]""", + kernelcmd, true) # make qtconsole require shift-enter to complete input @@ -130,6 +136,36 @@ copy_config("custom.js", joinpath(juliaprof, "static", "custom")) # julia.js implements a CodeMirror mode for Julia syntax highlighting in the notebook. # Eventually this will ship with CodeMirror and hence IPython, but for now we manually bundle it. -copy_config("julia.js", joinpath(juliaprof, "static", "components", "codemirror", "mode", "julia")) +if ipyvers <= v"3.0-" + copy_config("julia.js", joinpath(juliaprof, "static", "components", "codemirror", "mode", "julia")) +end ####################################################################### +# Part specific to Jupyter/IPython 3.0 and above +####################################################################### + + +if ipyvers >= v"3.0-" + eprintln("Found IPython version $ipyvers ... installing kernelspec.") + + juliakspec = joinpath(chomp(readall(`$ipython locate`)),"kernels","julia") + ks = [ + "argv" => kernelcmd_array, + "display_name" => "Julia "*string(VERSION), + ] + + destname = "kernel.json" + mkpath(juliakspec) + dest = joinpath(juliakspec, destname) + + + eprintln("Writing IJulia kernelspec to $dest ...") + + open(dest, "w") do f + write(f, JSON.json(ks)) + end + copy_config("logo-32x32.png", juliakspec) + copy_config("logo-64x64.png", juliakspec) +else + eprintln("Found IPython version $ipyvers ... skipping kernelspec.") +end diff --git a/deps/logo-32x32.png b/deps/logo-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..7a6509678235c7c067fe378aab785c4b5b2967d8 GIT binary patch literal 1310 zcmV+(1>yRMP)&u)`X7|0o!5T ze7t-AE}#>N!^|K4tLUi<8+3wO<~znK_vqmQ8R zt$V7C;!Y8HjNlz02$3YnZc*6Kzj^S_TL!RT=d5N>b!x5P`~G>QbRYs6W1^W%rpB0X zlC@la_~oIFvI8{kzPrw3^|6TWU2r|`Ts}=0hLeIIsE1W8KfiL~P$_Xseg|x*IvhtO zua_JE9LE{;Ja0sl{j{ZRR-|kIbKB-tl2{(`qa($%zVDAfaOcH{URX8&U6EWMKp;vo zCCI6iPKdIL$_60dbSO!cq6GjYLJLkW8-SxQK#M8>Qi|RftCe7&Yyf?UlfMHD!!WEW zrlqB4$!ZDpPh|sOoEGHPbSgEi*qR^})B)Vr_v(ogWdi_!!@;DIm zbb=r`(^zBSazm+cZ>SPBw#}%pG5-w$>l~#oXh(+vv7s@pG2tWB3KL}0bvipFJ3$F+_wb*_P4g`+P{9=Ovvk6MUb^XBqV(Rqa@Zg z_YU;t%e{T|`?D0CPn5!aj`EU9J1LObn5>sI*~t)moQ(vVe*_1>X&cDI^Q_ zhb&o5Fc!Mz^KoBhOuh$rE}aQ#iva}bWUUbUp_G>MFyNk z$cqnub98vzAMbi5MPh9xOij&%nd$<`>kN$u{Pp9$35DpZruj28`I$iOcLnFQ;1YnW zB_al>%7Rk}X>aKn*oHhce8=jJCk5E!DmUS}kuj}w5`Z!$Tan79CR^Hz09&^nc(y+; zz-5m}_mYNn0M`pJhky&>B7{F0@}*_HM}8@Ei`!T1sT0rL1xgFSX#lK<8YJw#sxYx_ z>hWdHyG literal 0 HcmV?d00001 diff --git a/deps/logo-64x64.png b/deps/logo-64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..67f45ead9e28470a90dfa16e4d112a1a235fc0e6 GIT binary patch literal 2843 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 literal 0 HcmV?d00001 From 36043fd5ee07dce93110fcae092f696975019dd3 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Fri, 26 Dec 2014 19:46:10 +0100 Subject: [PATCH 2/7] overrite resources, compat and simplify logic --- deps/build.jl | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index ca9b65fc..e664a5f6 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -2,6 +2,7 @@ ####################################################################### import JSON +using Compat # print to stderr, since that is where Pkg prints its messages eprintln(x...) = println(STDERR, x...) @@ -66,14 +67,20 @@ end # add Julia kernel manager if we don't have one yet if VERSION >= v"0.3-" - binary_name = "julia" + binary_name = @windows? "julia.exe":"julia" else - binary_name = "julia-basic" + binary_name = @windows? "julia.bat":"julia-basic" end -kernelcmd_array = VERSION >= v"0.3"? - ["$(escape_string(joinpath(JULIA_HOME,(@windows? "julia.exe":"$binary_name"))))", "-i", "-F", "$(escape_string(joinpath(Pkg.dir("IJulia"),"src","kernel.jl")))", "{connection_file}"]: - ["$(escape_string(joinpath(JULIA_HOME,(@windows? "julia.bat":"$binary_name"))))", "-F", "$(escape_string(joinpath(Pkg.dir("IJulia"),"src","kernel.jl")))", "{connection_file}"] +kernelcmd_array = [escape_string(joinpath(JULIA_HOME,("$binary_name")))] + +if VERSION >= v"0.3" + push!(kernelcmd_array,"-i") +end + +push!(kernelcmd_array, ["-F", escape_string(joinpath(Pkg.dir("IJulia"),"src","kernel.jl")), "{connection_file}"]...) + + kernelcmd = JSON.json(kernelcmd_array) @@ -102,7 +109,7 @@ eqb(a::Vector{Uint8}, b::Vector{Uint8}) = # copy IJulia/deps/src to destpath/destname if it doesn't # already exist at the destination, or if it has changed (if overwrite=true). function copy_config(src::String, destpath::String, - destname::String=src, overwrite=true) + destname::String=src; overwrite=true) mkpath(destpath) dest = joinpath(destpath, destname) srcbytes = rb(joinpath(Pkg.dir("IJulia"), "deps", src)) @@ -149,10 +156,10 @@ if ipyvers >= v"3.0-" eprintln("Found IPython version $ipyvers ... installing kernelspec.") juliakspec = joinpath(chomp(readall(`$ipython locate`)),"kernels","julia") - ks = [ + ks = @compat Dict( "argv" => kernelcmd_array, "display_name" => "Julia "*string(VERSION), - ] + ) destname = "kernel.json" mkpath(juliakspec) @@ -164,8 +171,8 @@ if ipyvers >= v"3.0-" open(dest, "w") do f write(f, JSON.json(ks)) end - copy_config("logo-32x32.png", juliakspec) - copy_config("logo-64x64.png", juliakspec) + copy_config("logo-32x32.png", juliakspec; overwrite=true) + copy_config("logo-64x64.png", juliakspec; overwrite=true) else eprintln("Found IPython version $ipyvers ... skipping kernelspec.") end From fe1b1386c76ee591127ef3d36e63985582aff054 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Fri, 26 Dec 2014 20:09:00 +0100 Subject: [PATCH 3/7] fix more kyle comments --- deps/build.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index e664a5f6..676b1e3a 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -78,7 +78,7 @@ if VERSION >= v"0.3" push!(kernelcmd_array,"-i") end -push!(kernelcmd_array, ["-F", escape_string(joinpath(Pkg.dir("IJulia"),"src","kernel.jl")), "{connection_file}"]...) +append!(kernelcmd_array, ["-F", escape_string(joinpath(Pkg.dir("IJulia"),"src","kernel.jl")), "{connection_file}"]) @@ -171,8 +171,8 @@ if ipyvers >= v"3.0-" open(dest, "w") do f write(f, JSON.json(ks)) end - copy_config("logo-32x32.png", juliakspec; overwrite=true) - copy_config("logo-64x64.png", juliakspec; overwrite=true) + copy_config("logo-32x32.png", juliakspec) + copy_config("logo-64x64.png", juliakspec) else eprintln("Found IPython version $ipyvers ... skipping kernelspec.") end From 4dd13cf2fbb4c0a141b11acfc66d385778ea6e91 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Fri, 26 Dec 2014 20:13:18 +0100 Subject: [PATCH 4/7] specify type for kwarg --- deps/build.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index 676b1e3a..60782d19 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -27,7 +27,7 @@ juliaprof = chomp(readall(`$ipython locate profile julia`)) # set c.$s in prof file to val, or nothing if it is already set # unless overwrite is true -function add_config(prof::String, s::String, val, overwrite=false) +function add_config(prof::String, s::String, val; overwrite::Bool=false) p = joinpath(juliaprof, prof) r = Regex(string("^[ \\t]*c\\.", replace(s, r"\.", "\\."), "\\s*=.*\$"), "m") if isfile(p) @@ -109,7 +109,7 @@ eqb(a::Vector{Uint8}, b::Vector{Uint8}) = # copy IJulia/deps/src to destpath/destname if it doesn't # already exist at the destination, or if it has changed (if overwrite=true). function copy_config(src::String, destpath::String, - destname::String=src; overwrite=true) + destname::String=src; overwrite::Bool=true) mkpath(destpath) dest = joinpath(destpath, destname) srcbytes = rb(joinpath(Pkg.dir("IJulia"), "deps", src)) From af221dab1d39f4a39ecf05033cd2038213a105c6 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Tue, 17 Feb 2015 14:47:18 -0800 Subject: [PATCH 5/7] polish for IPython 3.0.0-rc --- deps/build.jl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index 60782d19..cc7334c6 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -138,7 +138,17 @@ copy_config("ijuliafavicon.ico", # custom.js can contain custom js login that will be loaded # with the notebook to add info and/or monkey-patch some javascript # -- e.g. we use it to add .ipynb metadata that this is a Julia notebook -copy_config("custom.js", joinpath(juliaprof, "static", "custom")) +if ipyvers <= v"3.0-" + copy_config("custom.js", joinpath(juliaprof, "static", "custom")) +else + # TODO + ## upgrade custom.js because old version can prevent notebook + ## from loading. + ## todo: maybe do not copy if don't exist. + ## todo: maybe remove if user custom.js is identical to the one + ## shiped with IJulia ? + copy_config("custom.js", joinpath(juliaprof, "static", "custom")) +end # julia.js implements a CodeMirror mode for Julia syntax highlighting in the notebook. # Eventually this will ship with CodeMirror and hence IPython, but for now we manually bundle it. @@ -155,10 +165,13 @@ end if ipyvers >= v"3.0-" eprintln("Found IPython version $ipyvers ... installing kernelspec.") + # can (should?) install to `/usr/local/share/jupyter/kernels/julia` + # or make tmpdir and shell out to `ipython kernelspec install ` juliakspec = joinpath(chomp(readall(`$ipython locate`)),"kernels","julia") ks = @compat Dict( "argv" => kernelcmd_array, "display_name" => "Julia "*string(VERSION), + "language" => "julia", ) destname = "kernel.json" @@ -169,7 +182,8 @@ if ipyvers >= v"3.0-" eprintln("Writing IJulia kernelspec to $dest ...") open(dest, "w") do f - write(f, JSON.json(ks)) + # indent by 2 for readability of file + write(f, JSON.json(ks, 2)) end copy_config("logo-32x32.png", juliakspec) copy_config("logo-64x64.png", juliakspec) From 1adf21e06fb3a59ec328a4388c9b64bb915d8451 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Tue, 17 Feb 2015 15:13:18 -0800 Subject: [PATCH 6/7] use kwarg --- deps/build.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index cc7334c6..93d644a5 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -1,4 +1,4 @@ -# TODO: Build IPython 1.0 dependency? (wait for release?) +# TODO: Buld IPython 1.0 dependency? (wait for release?) ####################################################################### import JSON @@ -86,7 +86,7 @@ kernelcmd = JSON.json(kernelcmd_array) add_config("ipython_config.py", "KernelManager.kernel_cmd", kernelcmd, - true) + overwrite=true) # make qtconsole require shift-enter to complete input add_config("ipython_qtconsole_config.py", From 8442a03ef8e043ab68e43b2d2ee6b662541e3aaf Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Thu, 19 Feb 2015 14:35:54 -0800 Subject: [PATCH 7/7] install all files on all versions of IPython --- deps/build.jl | 61 ++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index 93d644a5..f8f76345 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -135,58 +135,45 @@ copy_config("ijuliafavicon.ico", joinpath(juliaprof, "static", "base", "images"), "favicon.ico") +# On IPython < 3. # custom.js can contain custom js login that will be loaded # with the notebook to add info and/or monkey-patch some javascript # -- e.g. we use it to add .ipynb metadata that this is a Julia notebook -if ipyvers <= v"3.0-" - copy_config("custom.js", joinpath(juliaprof, "static", "custom")) -else - # TODO - ## upgrade custom.js because old version can prevent notebook - ## from loading. - ## todo: maybe do not copy if don't exist. - ## todo: maybe remove if user custom.js is identical to the one - ## shiped with IJulia ? - copy_config("custom.js", joinpath(juliaprof, "static", "custom")) -end + +# on IPython 3+, still upgrade custom.js because old version can prevent +# notebook from loading. +# todo: maybe do not copy if don't exist. +# todo: maybe remove if user custom.js is identical to the one +# shiped with IJulia ? +copy_config("custom.js", joinpath(juliaprof, "static", "custom")) # julia.js implements a CodeMirror mode for Julia syntax highlighting in the notebook. # Eventually this will ship with CodeMirror and hence IPython, but for now we manually bundle it. -if ipyvers <= v"3.0-" - copy_config("julia.js", joinpath(juliaprof, "static", "components", "codemirror", "mode", "julia")) -end +copy_config("julia.js", joinpath(juliaprof, "static", "components", "codemirror", "mode", "julia")) ####################################################################### # Part specific to Jupyter/IPython 3.0 and above ####################################################################### -if ipyvers >= v"3.0-" - eprintln("Found IPython version $ipyvers ... installing kernelspec.") +juliakspec = joinpath(chomp(readall(`$ipython locate`)),"kernels","julia") +ks = @compat Dict( + "argv" => kernelcmd_array, + "display_name" => "Julia "*string(VERSION), + "language" => "julia", +) - # can (should?) install to `/usr/local/share/jupyter/kernels/julia` - # or make tmpdir and shell out to `ipython kernelspec install ` - juliakspec = joinpath(chomp(readall(`$ipython locate`)),"kernels","julia") - ks = @compat Dict( - "argv" => kernelcmd_array, - "display_name" => "Julia "*string(VERSION), - "language" => "julia", - ) +destname = "kernel.json" +mkpath(juliakspec) +dest = joinpath(juliakspec, destname) - destname = "kernel.json" - mkpath(juliakspec) - dest = joinpath(juliakspec, destname) +eprintln("Writing IJulia kernelspec to $dest ...") - eprintln("Writing IJulia kernelspec to $dest ...") - - open(dest, "w") do f - # indent by 2 for readability of file - write(f, JSON.json(ks, 2)) - end - copy_config("logo-32x32.png", juliakspec) - copy_config("logo-64x64.png", juliakspec) -else - eprintln("Found IPython version $ipyvers ... skipping kernelspec.") +open(dest, "w") do f + # indent by 2 for readability of file + write(f, JSON.json(ks, 2)) end +copy_config("logo-32x32.png", juliakspec) +copy_config("logo-64x64.png", juliakspec)