diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..073dd15 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,75 @@ +name: CI +on: + pull_request: + branches: + - main + push: + branches: + - main + tags: '*' +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + version: + - '1.9' + - '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia. + os: + - ubuntu-latest + arch: + - x64 + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: actions/cache@v1 + env: + cache-name: cache-artifacts + with: + path: ~/.julia/artifacts + key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + restore-keys: | + ${{ runner.os }}-test-${{ env.cache-name }}- + ${{ runner.os }}-test- + ${{ runner.os }}- + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + env: + JULIA_NUM_THREADS: "3" + with: + prefix: xvfb-run + - uses: julia-actions/julia-processcoverage@v1 + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + file: lcov.info + docs: + name: Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: '1' + - run: | + julia --project=docs -e ' + using Pkg + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate()' + - run: | + julia --project=docs -e ' + using Documenter: DocMeta, doctest + using XRootD + DocMeta.setdocmeta!(XRootD, :DocTestSetup, :(using XRootD); recursive=true) + doctest(XRootD)' + - run: julia --project=docs docs/make.jl + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} diff --git a/README.md b/README.md index cd6479f..79df859 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ [![XRootD](docs/src/assets/xrootd-logo.png)](https://xrootd.slac.stanford.edu) -[![License](https://img.shields.io/badge/license-LGPL-blue.svg)](LICENSE) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https:///JuliaHEP.github.io/XRootD.jl/dev/) +[![Build Status](https://github.com/JuliaHEP/XRootD.jl/workflows/CI/badge.svg)](https://github.com/JuliaHEP/XRootD.jl/actions) +[![codecov](https://codecov.io/gh/JuliaHEP/XRootD.jl/graph/badge.svg?token=AS74WXOYT6)](https://codecov.io/gh/JuliaHEP/XRootD.jl)[![License](https://img.shields.io/badge/license-LGPL-blue.svg)](LICENSE) ## Description diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..5e2511d --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,3 @@ +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" + diff --git a/docs/make.jl b/docs/make.jl new file mode 100644 index 0000000..a3f27e6 --- /dev/null +++ b/docs/make.jl @@ -0,0 +1,25 @@ +using Documenter +using XRootD +using XRootD.XrdCl + +makedocs(; + modules=[XRootD, XRootD.XrdCl], + format = Documenter.HTML( + prettyurls = Base.get(ENV, "CI", nothing) == "true", + repolink="https://github.com/JuliaHEP/XRootD.jl", + ), + pages=[ + "Introduction" => "index.md", + "Public APIs" => "api.md", + "Release Notes" => "release_notes.md", + ], + checkdocs=:exports, + repo="https://github.com/JuliaHEP/XRootD.jl/blob/{commit}{path}#L{line}", + sitename="XRootD.jl", + authors="Pere Mato", +) + +deploydocs(; + repo="github.com/JuliaHEP/XRootD.jl", + push_preview = true +) diff --git a/docs/src/api.md b/docs/src/api.md new file mode 100644 index 0000000..5d0baa0 --- /dev/null +++ b/docs/src/api.md @@ -0,0 +1,36 @@ +# Public Documentation + +Documentation for `XRootD.jl` public interface. + +## Index - Types +```@index +Pages = ["api.md"] +Modules = [XRootD, XRootD.XrdCl] +Order = [:type] +``` +## Index - Functions +```@index +Pages = ["api.md"] +Modules = [XRootD, XRootD.XrdCl] +Order = [:function] +``` + +## Modules +```@autodocs +Modules = [XRootD, XRootD.XrdCl] +Order = [:module] +``` +## Types +This is the list of all types and functions defined for XRootD + +```@autodocs +Modules = [XRootD, XRootD.XrdCl] +Order = [:type] +``` +## Functions +```@autodocs +Modules = [XRootD, XRootD.XrdCl] +Order = [:function] +``` + + diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 0000000..e68cbf5 --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,73 @@ +# Julia binding for XRootD + +## Description + +Julia bindings for the [XRootD](https://xrootd.slac.stanford.edu) high performance, scalable, and fault tolerant access to data repositories. It facilitates the interface with the XRootD client, by writing Julia code instead of having to write C++ code. +This package is developed using the [CxxWrap.jl](https://github.com/JuliaInterop/CxxWrap.jl) package to wrap C++ types and functions to Julia. Wrapper C++ code is generated with the help of [WrapIt](https://github.com/grasph/wrapit) tool that uses of the clang library. + +The Julia interface has been inspired by the functionality provided by [pyxrootd](https://xrootd.slac.stanford.edu/doc/doxygen/5.6.4/python/), which provide a set of simple but pythonic bindings for XRootD. + +## Installation +The XRootD.jl package does no require any special installation. Stable releases are registered into the Julia general registry, and therefore can be deployed with the standard `Pkg` Julia package manager. +```julia +julia> using Pkg +julia> Pkg.add("XRootD") +``` +## API Guidelines +Besides de constructors for `XrdCl.File` and `XrdCl.FileSystem` all the other functions returns a Tuple `(status, response)`, where `status` is an instance of `XRootDStatus` and response is the returned object or `nothing` if the function does not return a value. + +The returned `status` can be directly printed with `println(status)` or similar functions. It can also be checked with `isOK(status)` or `isError(status)` helper functions returning a `Bool`value. + +## Getting Started + +```Julia +using XRootD.XrdCl + +#---FileSystem interface--------------------------------------- +fs = FileSystem("root://localhost:1094") # create a FileSystem + +st, _ = ping(fs) # is server alive? +isError(st) && error(st) + +st, statinfo = stat(fs, "/tmp") # get statinfo + +if isOK(st) && isdir(statinfo) + st, entries = readdir(fs, "/tmp") # ls the directory + isError(st) && error(st) + for f in entries + println(f) + end +end + +#---File interface-------------------------------------------- +f = File() + +# create file and write +st, _ = open(f, "root://localhost:1094//tmp/testfile.txt", OpenFlags.New|OpenFlags.Write) +isError(st) && error(st) +write(f, "Hello\nWorld\nFolks!") +close(f) + +# re-open file and read +st, _ = open(f, "root://localhost:1094//tmp/testfile.txt", OpenFlags.Read) +isError(st) && error(st) +st, lines = readlines(f) +isError(st) && error(st) +for line in lines + print(line) +end +close(f) + +# delete file (using FileSystem) +st, _ = rm(fs, "/tmp/testfile.txt") +``` + +## Roadmap +There are a number of issues and problems still to be resolved. We keep track of them in this list: +- Is is necessary to have the async interface? + + +## Tests +Unit tests can be run with `julia --project=. test/runtests.jl` + +## Examples diff --git a/docs/src/release_notes.md b/docs/src/release_notes.md new file mode 100644 index 0000000..8308bcf --- /dev/null +++ b/docs/src/release_notes.md @@ -0,0 +1,5 @@ + +# Release Notes + +## 0.1.0 +- First release. It provide similar functionality as for the python bindings of the client library of XRootD diff --git a/gen/build.jl b/gen/build.jl index 44d4918..ce94e3c 100644 --- a/gen/build.jl +++ b/gen/build.jl @@ -17,5 +17,6 @@ xrootd_prefix = XRootD_jll.artifact_dir run(`cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17 - -DCMAKE_PREFIX_PATH=$cxxwrap_prefix\;$xrootd_prefix $sourcedir`) + -DCMAKE_PREFIX_PATH=$cxxwrap_prefix\;$xrootd_prefix $sourcedir + -DCxxWrap_VERSION=$(pkgversion(CxxWrap))`) run(`cmake --build . --config Release --parallel 8`) diff --git a/src/File.jl b/src/File.jl index 0f3d25f..0b2df01 100644 --- a/src/File.jl +++ b/src/File.jl @@ -9,11 +9,11 @@ end File() = File(XRootD.XrdCl!File(), 0, 0) """ - File(url::String, flags::UInt16=0x0000, mode::UInt16=0x0000) + File(url::String, flags=0x0000, mode=0x0000) File crates a File object and opens it. """ -function File(url::String, flags::UInt16=0x0000, mode::UInt16=0x0000) +function File(url::String, flags=0x0000, mode=0x0000) file = XRootD.XrdCl!File() st = XRootD.Open(file, url, flags, mode) if isOK(st) @@ -172,7 +172,7 @@ end readlines reads lines from the file. """ function Base.readlines(f::File, size=0, offset=0, chunk=0) - lines = [] + lines = String[] st = XRootDStatus() offset != 0 && (f.currentOffset = offset) while !eof(f)