Skip to content

Commit 69b8205

Browse files
authored
Merge pull request #5 from LIM-AeroCloud/rel/0.1.0
Rel/0.1.0
2 parents 434dabd + c52d2de commit 69b8205

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2899
-0
lines changed

.github/dependabot.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
2+
version: 2
3+
updates:
4+
- package-ecosystem: "github-actions"
5+
directory: "/" # Location of package manifests
6+
schedule:
7+
interval: "weekly"

.github/workflows/CI.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: CI
2+
on:
3+
push:
4+
branches:
5+
- dev
6+
tags: ['*']
7+
pull_request:
8+
workflow_dispatch:
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
12+
jobs:
13+
test:
14+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
15+
runs-on: ${{ matrix.os }}
16+
timeout-minutes: 60
17+
permissions:
18+
actions: write
19+
contents: read
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
version:
24+
- '1.10'
25+
- '1'
26+
- 'nightly'
27+
os:
28+
- ubuntu-latest
29+
- macOS-latest
30+
- windows-latest
31+
arch:
32+
- x64
33+
steps:
34+
- uses: actions/checkout@v4
35+
- uses: julia-actions/setup-julia@v2
36+
with:
37+
version: ${{ matrix.version }}
38+
arch: ${{ matrix.arch }}
39+
- uses: julia-actions/cache@v2
40+
- uses: julia-actions/julia-buildpkg@v1
41+
- uses: julia-actions/julia-runtest@v1
42+
- uses: julia-actions/julia-processcoverage@v1
43+
- uses: codecov/codecov-action@v5
44+
with:
45+
files: lcov.info
46+
token: ${{ secrets.CODECOV_TOKEN }}
47+
fail_ci_if_error: false
48+
docs:
49+
name: Documentation
50+
runs-on: ubuntu-latest
51+
permissions:
52+
actions: write # needed to allow julia-actions/cache to proactively delete old caches that it has created
53+
contents: write
54+
statuses: write
55+
steps:
56+
- uses: actions/checkout@v4
57+
- uses: julia-actions/setup-julia@v2
58+
with:
59+
version: '1'
60+
- uses: julia-actions/cache@v2
61+
- name: Configure doc environment
62+
shell: julia --project=docs --color=yes {0}
63+
run: |
64+
using Pkg
65+
Pkg.develop(PackageSpec(path=pwd()))
66+
Pkg.instantiate()
67+
- uses: julia-actions/julia-buildpkg@v1
68+
- uses: julia-actions/julia-docdeploy@v1
69+
env:
70+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
71+
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
72+
- name: Run doctests
73+
shell: julia --project=docs --color=yes {0}
74+
run: |
75+
using Documenter: DocMeta, doctest
76+
using SFTP
77+
DocMeta.setdocmeta!(SFTP, :DocTestSetup, :(using SFTP); recursive=true)
78+
doctest(SFTP)

.github/workflows/CompatHelper.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: CompatHelper
2+
on:
3+
schedule:
4+
- cron: 0 0 1 * *
5+
- cron: 0 0 16 * *
6+
workflow_dispatch:
7+
jobs:
8+
CompatHelper:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Pkg.add("CompatHelper")
12+
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
13+
- name: CompatHelper.main()
14+
env:
15+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16+
COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }}
17+
run: julia -e 'using CompatHelper; CompatHelper.main()'

.github/workflows/TagBot.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: TagBot
2+
on:
3+
issue_comment:
4+
types:
5+
- created
6+
workflow_dispatch:
7+
inputs:
8+
lookback:
9+
default: "3"
10+
permissions:
11+
actions: read
12+
checks: read
13+
contents: write
14+
deployments: read
15+
issues: read
16+
discussions: read
17+
packages: read
18+
pages: read
19+
pull-requests: read
20+
repository-projects: read
21+
security-events: read
22+
statuses: read
23+
jobs:
24+
TagBot:
25+
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: JuliaRegistries/TagBot@v1
29+
with:
30+
token: ${{ secrets.GITHUB_TOKEN }}
31+
ssh: ${{ secrets.DOCUMENTER_KEY }}

.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Files generated by invoking Julia with --code-coverage
2+
*.jl.cov
3+
*.jl.*.cov
4+
5+
# Files generated by invoking Julia with --track-allocation
6+
*.jl.mem
7+
8+
# System-specific files and directories generated by the BinaryProvider and BinDeps packages
9+
# They contain absolute paths specific to the host computer, and so should not be committed
10+
deps/deps.jl
11+
deps/build.log
12+
deps/downloads/
13+
deps/usr/
14+
deps/src/
15+
16+
# Build artifacts for creating documentation generated by the Documenter package
17+
docs/build/
18+
docs/site/
19+
20+
# File generated by Pkg, the package manager, based on a corresponding Project.toml
21+
# It records a fixed state of all packages used by the project. As such, it should not be
22+
# committed for packages, but should be committed for applications that require a static
23+
# environment.
24+
Manifest.toml

CHANGELOG.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Release Notes
2+
3+
This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4+
The format of the release notes follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5+
6+
## [v0.1.0] - 2025-04-23
7+
8+
The initial release is based on [SFTPClient (v0.4.4)](https://github.com/stensmo/SFTPClient.jl/releases/tag/0.4.4).
9+
All changes for this released are documented in respect to this version.
10+
11+
### Added
12+
13+
- Initial release with new project name SFTP.jl and new initial version v0.1.0
14+
- Prefer `Logging` over simple print commands
15+
- Overload `stat` with simplified `stat` method for a single path object
16+
(in contrast to `statscan` that scans the whole folder) and return an `SFTP.StatStruct`
17+
- Overlaod Base functions for the file system; new methods added for:
18+
- `ispath`
19+
- `pwd`
20+
- `mkdir` (previous `mkdir` was renamed to `mkpath`)
21+
- `joinpath`
22+
- `splitdir`
23+
- `basename`
24+
- Add labels for docs, CI status and Codecov in Readme
25+
- Add workflow for compat helper
26+
- Add changelog and automate with Changelog.jl
27+
28+
### Changed
29+
30+
- Update API
31+
- exported: `upload`, `statscan`,`URI`
32+
- public: `Client`, `StatStruct`, `download`, `stat`, `filemode`, `ispath`,
33+
`isdir`, `isfile`, `islink`, `pwd`, `cd`, `mv`,`rm`, `mkdir`, `mkpath`,
34+
`readdir`, `walkdir`, `joinpath`, `splitdir`, `basename`
35+
- Completely refactor code base, use concise variable names, format source code
36+
- Rename `SFTPStatStruct` to `StatStruct` (unexported) and refactor constructors
37+
- Rename `SFTP` to `Client` (unexported) and refactor constructors
38+
- Rename `sftpstat` to `statscan`
39+
- Rename `mkdir` to `mkpath` (as it has the functionality of `mkpath`, add new method for `mkdir`)
40+
- Update functionality of file system functions to more close resemble Julia's Base functions
41+
- Combine `rm`/`rmdir` in `rm` with a `force` flag
42+
- Sort results in `readdir`, `stat`, `statscan`, and `walkdir` (can be switched off with `sort`
43+
flag)
44+
- Introduce more checks and restrictions based on Julia's file system function/Unix functions
45+
- Check validity of a path
46+
- Add methods to pass a path as `String` to `filemode` and related functions instead of
47+
a `StatStruct` object
48+
- Allow recursive methods, where appropriate
49+
- Allow upload/download of directories
50+
- Add `force`/`merge` flag
51+
- Allow filtering of hidden files
52+
- Update and unify how paths are defined on the remote and local system
53+
- Refactor and extent tests
54+
- Update documentation
55+
56+
### Removed
57+
58+
- Remove `CSV` as dependecy and use `readlines` instead
59+
- Remove `FileWatching`, `ArgTools`, and `NetworkOptions` as dependency
60+
61+
### Fixed
62+
63+
- Overload `walkdir` and `download` instead of defining new functions
64+
- Ensure Windows paths are processed correctly
65+
- Several fixes concerning the representation of paths (especially under Windows)
66+
- Symlinks are now recognised by `stat`/`statscan`
67+
- `walkdir` correctly follows symlinks
68+
69+
70+
<!-- Links generated by Changelog.jl -->
71+
72+
[v0.1.0]: https://github.com/LIM-AeroCloud/SFTP.jl/releases/tag/v0.1.0

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Peter Bräuer <pb866.git@gmail.com>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
EXEC:=julia
2+
3+
default: help
4+
5+
docs/Manifest.toml: docs/Project.toml
6+
${EXEC} --project=docs -e 'using Pkg; Pkg.instantiate()'
7+
8+
docs-instantiate:
9+
${EXEC} --project=docs -e 'using Pkg; Pkg.instantiate()'
10+
11+
docs: changelog
12+
${EXEC} --project=docs docs/make.jl
13+
14+
changelog: docs/Manifest.toml
15+
${EXEC} --project=docs release-scripts/changelog.jl
16+
17+
bump-version:
18+
${EXEC} --project=docs release-scripts/pre-release.jl
19+
20+
test:
21+
${EXEC} --project -e 'using Pkg; Pkg.test()'
22+
23+
pre-release: test bump-version docs
24+
25+
post-release:
26+
${EXEC} --project=docs release-scripts/post-release.jl
27+
28+
help:
29+
@echo "The following make commands are available:"
30+
@echo " - make changelog: update all links in CHANGELOG.md's footer"
31+
@echo " - make docs: build the documentation and update changelog links"
32+
@echo " - make test: run the tests"
33+
@echo " - make bump-version: set version to stable"
34+
@echo " - make pre-release: run tests, build docs, update changelog links, and bump version"
35+
@echo " - make post-release: increment minor version"
36+
37+
.PHONY: default docs-instantiate help changelog docs test bump-version pre-release post-release

Project.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name = "SFTP"
2+
uuid = "f44f501d-421f-4286-bfa3-132bd4e9b35e"
3+
authors = ["Peter Bräuer <pb866.git@gmail.com>"]
4+
version = "0.1.0"
5+
6+
[deps]
7+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
8+
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
9+
LibCURL = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
10+
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
11+
URIs = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
12+
13+
[compat]
14+
Downloads = "1.4.3"
15+
LibCURL = "0.6"
16+
Logging = "1.10"
17+
URIs = "1.5"
18+
julia = "1.10"
19+
20+
[extras]
21+
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
22+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
23+
24+
[targets]
25+
test = ["Test"]

README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Julia SFTP Client
2+
3+
A Julia SFTP Client for exploring the structure and contents of SFTP servers and
4+
exchanging files.
5+
6+
## Overview
7+
8+
This package is based on [SFTPClient.jl](https://github.com/stensmo/SFTPClient.jl.git)
9+
and builds on [Downloads.jl](https://github.com/JuliaLang/Downloads.jl.git) and
10+
[LibCurl.jl](https://github.com/JuliaWeb/LibCURL.jl.git).
11+
12+
_SFTP.jl_ supports username/password as well as certificates for authentication.
13+
It provides methods to exchange files with the SFTP server as well as investigate the
14+
folder structure and files with methods based on
15+
[Julia's Filesystem functions](https://docs.julialang.org/en/v1/base/file/).
16+
Details can be found in the [documentation](docs-dev-url).
17+
18+
| **Documentation** | **Build Status** |
19+
|:----------------------------------------------------------------------------------:|:---------------------------------------------------------------------------:|
20+
| [![Stable][docs-stable-img]][docs-stable-url] [![Dev][docs-dev-img]][docs-dev-url] | [![Build Status][CI-img]][CI-url] [![Coverage][codecov-img]][codecov-url] |
21+
22+
## Showcase
23+
24+
```julia
25+
using SFTP
26+
# Set up client for connection to server
27+
sftp = SFTP.Client("sftp://test.rebex.net/pub/example/", "demo", "password")
28+
# Analyse contents of current path
29+
files=readdir(sftp)
30+
statStructs = statscan(sftp)
31+
# Download contents
32+
download.(sftp, files)
33+
```
34+
35+
```julia
36+
using SFTP
37+
# You can also load file contents to a variable by passing a function to download as first argument
38+
# Note: the function must an AbstractString as parameter for a temporary path of the downloaded file
39+
# Note: the path will be deleted immediately after the contents are saved to the variable
40+
fread(path::AbstractString)::Vector{String} = readlines(path)
41+
array = download(fread, sftp, "data/matrix.csv")
42+
43+
# Certificate authentication works as well
44+
sftp = SFTP.Client("sftp://mysitewhereIhaveACertificate.com", "myuser")
45+
sftp = SFTP.Client("sftp://mysitewhereIhaveACertificate.com", "myuser", "cert.pub", "cert.pem") # Assumes cert.pub and cert.pem is in your current path
46+
# The cert.pem is your certificate (private key), and the cert.pub can be obtained from the private key.
47+
# ssh-keygen -y -f ./cert.pem. Save the output into "cert.pub".
48+
```
49+
50+
[docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg
51+
[docs-stable-url]: https://LIM-AeroCloud.github.io/SFTP.jl/stable/
52+
53+
[docs-dev-img]: https://img.shields.io/badge/docs-dev-blue.svg
54+
[docs-dev-url]: https://LIM-AeroCloud.github.io/SFTP.jl/dev/
55+
56+
[CI-img]: https://github.com/LIM-AeroCloud/SFTP.jl/actions/workflows/CI.yml/badge.svg?branch=dev
57+
[CI-url]: https://github.com/LIM-AeroCloud/SFTP.jl/actions/workflows/CI.yml?query=branch%3Adev
58+
59+
[codecov-img]: https://codecov.io/gh/LIM-AeroCloud/SFTP.jl/graph/badge.svg?token=kYZK3bRvCZ
60+
[codecov-url]: https://codecov.io/gh/LIM-AeroCloud/SFTP.jl

0 commit comments

Comments
 (0)