From 32460d430a282c0b5e411a5ce17661b53e7cab96 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Fri, 22 Dec 2023 17:28:10 +0100 Subject: [PATCH 1/2] Delete old documentation Source docs can be found in hummingbird-docs Docs can be found https://hummingbird-project.github.io/hummingbird-docs/documentation/hummingbird/ --- documentation/Encoding and Decoding.md | 95 ------------------ documentation/Error Handling.md | 50 ---------- documentation/Extending Hummingbird.md | 56 ----------- documentation/Jobs.md | 69 ------------- documentation/Middleware.md | 66 ------------ documentation/Persistent Data.md | 59 ----------- documentation/Router.md | 133 ------------------------- documentation/readme.md | 12 --- 8 files changed, 540 deletions(-) delete mode 100644 documentation/Encoding and Decoding.md delete mode 100644 documentation/Error Handling.md delete mode 100644 documentation/Extending Hummingbird.md delete mode 100644 documentation/Jobs.md delete mode 100644 documentation/Middleware.md delete mode 100644 documentation/Persistent Data.md delete mode 100644 documentation/Router.md delete mode 100644 documentation/readme.md diff --git a/documentation/Encoding and Decoding.md b/documentation/Encoding and Decoding.md deleted file mode 100644 index ce908b568..000000000 --- a/documentation/Encoding and Decoding.md +++ /dev/null @@ -1,95 +0,0 @@ -# Encoding and Decoding - -Hummingbird can make use of `Codable` to decode requests and encode responses. `HBApplication` has two member variables `decoder` and `encoder` which define how requests/responses are decoded/encoded. The `decoder` must conform to `HBRequestDecoder` which requires a `decode(_:from)` function that decodes a `HBRequest`. - -```swift -public protocol HBRequestDecoder { - func decode(_ type: T.Type, from request: HBRequest) throws -> T -} -``` - -The `encoder` must conform to `HBResponseEncoder` which requires a `encode(_:from)` function that creates a `HBResponse` from a `Codable` value and the original request that generated it. - -```swift -public protocol HBResponseEncoder { - func encode(_ value: T, from request: HBRequest) throws -> HBResponse -} -``` - -Both of these look very similar to the `Encodable` and `Decodable` protocol that come with the `Codable` system except you have additional information from the `HBRequest` class on how you might want to decode/encode your data. - -## Setting up HBApplication - -The default implementations of `decoder` and `encoder` are `Null` implementations that will assert if used. So you have to setup your `decoder` and `encoder` before you can use `Codable` in Hummingbird. `HummingbirdFoundation` includes two such implementations. `JSONEncoder` and `JSONDecoder` have been extended to conform to the relevant protocols so you can have JSON decoding/encoding by adding the following when creating your application - -```swift -let app = HBApplication() -app.decoder = JSONDecoder() -app.encoder = JSONEncoder() -``` - -`HummingbirdFoundation` also includes a decoder and encoder for url encoded form data. To use this you setup the application as follows - -```swift -let app = HBApplication() -app.decoder = URLEncodedFormDecoder() -app.encoder = URLEncodedFormEncoder() -``` - -## Decoding Requests - -Once you have a decoder you can implement decoding in your routes using the `HBRequest.decode` method in the following manner - -```swift -struct User: Decodable { - let email: String - let firstName: String - let surname: String -} -app.router.post("user") { request -> EventLoopFuture in - // decode user from request - guard let user = try? request.decode(as: User.self) else { - return request.failure(.badRequest) - } - // create user and if ok return `.ok` status - return createUser(user, on: request.eventLoop) - .map { _ in .ok } -} -``` -Like the standard `Decoder.decode` functions `HBRequest.decode` can throw an error if decoding fails. In this situation when I received a decode error I return a failed `EventLoopFuture`. I use the function `HBRequest.failure` to generate the failed `EventLoopFuture`. - -## Encoding Responses - -To have an object encoded in the response we have to conform it to `HBResponseEncodable`. This then allows you to create a route handler that returns this object and it will automatically get encoded. If we extend the `User` object from the above example we can do this - -```swift -extension User: HBResponseEncodable {} - -app.router.get("user") { request -> User in - let user = User(email: "js@email.com", name: "John Smith") - return user -} -``` - -## Decoding/Encoding based on Request headers - -Because the full request is supplied to the `HBRequestDecoder`. You can make decoding decisions based on headers in the request. In the example below we are decoding using either the `JSONDecoder` or `URLEncodedFormDecoder` based on the "content-type" header. - -```swift -struct MyRequestDecoder: HBRequestDecoder { - func decode(_ type: T.Type, from request: HBRequest) throws -> T where T : Decodable { - guard let header = request.headers["content-type"].first else { throw HBHTTPError(.badRequest) } - guard let mediaType = HBMediaType(from: header) else { throw HBHTTPError(.badRequest) } - switch mediaType { - case .applicationJson: - return try JSONDecoder().decode(type, from: request) - case .applicationUrlEncoded: - return try URLEncodedFormDecoder().decode(type, from: request) - default: - throw HBHTTPError(.badRequest) - } - } -} -``` - -Using a similar manner you could also create a `HBResponseEncoder` based on the "accepts" header in the request. diff --git a/documentation/Error Handling.md b/documentation/Error Handling.md deleted file mode 100644 index 524def857..000000000 --- a/documentation/Error Handling.md +++ /dev/null @@ -1,50 +0,0 @@ -# Error Handling - -If a middleware or route handler throws an error the server needs to know how to handle this. If the server does not know how to handle the error then the only thing it can return to the client is a status code of 500 (Internal Server Error). This is not overly informative. - -## HBHTTPError - -Hummingbird uses the Error object `HBHTTPError` throughout its codebase. The server recognises this and can generate a more informative response for the client from it. The error includes the status code that should be returned and a response message if needed. For example - -```swift -app.get("user") { request -> User in - guard let userId = request.uri.queryParameters.get("id", as: Int.self) else { - throw HBHTTPError(.badRequest, message: "Invalid user id") - } - ... -} -``` -The `HBHTTPError` generated here will be recognised by the server and it will generate a status code 400 (Bad Request) with the body "Invalid user id". - -In the situation where you have a route that returns an `EventLoopFuture` you are not allowed to throw an error so you have to return a failed `EventLoopFuture`. Hummingbird provides a shortcut here for you `request.failure`. It can be used as follows - -```swift -app.get("user") { request -> EventLoopFuture in - guard let userId = request.uri.queryParameters.get("id", as: Int.self) else { - return request.failure(.badRequest, message: "Invalid user id") - } - ... -} -``` - -## HBHTTPResponseError - -The server knows how to respond to a `HBHTTPError` because it conforms to protocol `HBHTTPResponseError`. You can create your own `Error` object and conform it to `HBHTTPResponseError` and the server will know how to generate a sensible error from it. The example below is a error class that outputs an error code in the response headers. - -```swift -struct MyError: HBHTTPResponseError { - init(_ status: HTTPResponseStatus, errorCode: String) { - self.status = status - self.errorCode = errorCode - } - - let errorCode: String - - // required by HBHTTPResponseError protocol - let status: HTTPResponseStatus - var headers: HTTPHeaders { ["error-code": self.errorCode] } - func body(allocator: ByteBufferAllocator) -> ByteBuffer? { - return nil - } -} -``` diff --git a/documentation/Extending Hummingbird.md b/documentation/Extending Hummingbird.md deleted file mode 100644 index 02b8b7918..000000000 --- a/documentation/Extending Hummingbird.md +++ /dev/null @@ -1,56 +0,0 @@ -# Extending Hummingbird - -The `HBApplication`, `HBRequest` and `HBResponse` classes all contain an `HBExtensions` object that allows you to extend these classes with your own objects. The extension objects are stored in a dictionary with a KeyPath as their key. - -```swift -extension HBApplication { - public var myExt: String? { - get { self.extensions.get(\.myExt) } - set { self.extensions.set(\.myExt, value: newValue) } - } -} -``` -The code above adds the member variable `myExt` to the `HBApplication` class. I use the `KeyPath` to the variable as the key. While it would be possible to use another `KeyPath` as the key it doesn't really make sense. - -In the example above the member variable is an optional, to ensure you will always get a valid value when referencing `HBApplication.myExt`. You can set the variable to be non-optional but you will have to ensure you set the variable before ever accessing it, otherwise your application will crash. - -For extensions to `HBApplication` you also get the added bonus of being able to add a shutdown call for when the application is shutdown. In the example below we have extended `HBApplication` to include a `AWSClient` from the package [`Soto`](https://github.com/soto-project/soto). It is required you shutdown the client before it is deleted. The extension shutdown can be used to do this for you. - -```swift -extension HBApplication { - public struct AWS { - public var client: AWSClient { - get { application.extensions.get(\.aws.client) } - nonmutating set { - application.extensions.set(\.aws.client, value: newValue) { client in - // shutdown AWSClient - try client.syncShutdown() - } - } - } - let application: HBApplication - } - - public var aws: AWS { return .init(application: self) } -} -``` - -Note, I have placed everything inside a containing struct `AWS`, so the KeyPath `\.aws.client` needs to include the name of containing member variable in it as well. - -## Extending EventLoop - -In certain situations it can be useful to hold data on a per `EventLoop` basis. You can do this by extending the class `HBApplication.EventLoopStorage`. The class can be extended in the same way as above. You then access the storage either via `HBApplication.eventLoopStorage(for:)` or `HBRequest.eventLoopStorage`. -```swift -extension HBApplication.EventLoopStorage { - public var index: Int? { - get { self.extensions.get(\.index) } - set { self.extensions.set(\.index, value: newValue) } - } -} -func getIndex(_ request: HBRequest) { - let index = request.eventLoopStorage.index - ... -} -``` - -This is used by the `DateCache` in `HummingbirdFoundation` and also by the `Redis` interface that can be found [here](https://github.com/hummingbird-project/hummingbird-redis). diff --git a/documentation/Jobs.md b/documentation/Jobs.md deleted file mode 100644 index 02dc4ee40..000000000 --- a/documentation/Jobs.md +++ /dev/null @@ -1,69 +0,0 @@ -# Jobs - -HummingbirdJobs allows you to offload work your server would be doing to another server. You can setup jobs to use different drivers for storing job metadata. The module comes with a driver that stores jobs in local memory and uses your current server to process the jobs, but there is also an implementation that comes with the HummingbirdRedis package that stores jobs in a Redis database. - -## Setting up Jobs - -Before you can start adding or processing jobs you need to add a jobs driver to the `HBApplication`. The code below adds a redis driver for jobs. To use a Redis driver you will need to setup Redis first. -```swift - let app = HBApplication() - try app.addRedis( - configuration: .init( - hostname: Self.redisHostname, - port: 6379 - ) - ) - app.addJobs( - using: .redis(configuration: .init(queueKey: "_myJobsQueue")), - numWorkers: 0 - ) -``` -In this example I called `addJob` with `numWorkers` set to `0`. This means I can add jobs but they will not be processed. To get another server to process these jobs, I should run a separate version of the app which connects to the same Redis queue but with the `numWorkers` set to the number of threads you want to process the jobs on the queue. - -## Creating a Job - -First you must define your job. Create an object that inherits from `HBJob`. This protocol requires you to implement a static variable `name` and a function `func execute(on:logger)`. The `name` variable should be unique to this job definition. It is used in the serialisation of the job. The `execute` function does the work of the job and returns an `EventLoopFuture` that should be fulfilled when the job is complete. Below is an example of a job that calls a `sendEmail()` function. -```swift -struct SendEmailJob: HBJob { - static let name = "SendEmail" - let to: String - let subject: String - let message: String - - /// do the work - func execute(on eventLoop: EventLoop, logger: Logger) -> EventLoopFuture { - return sendEmail(to: self.to, subject: self.subject, message: self.message) - } -} -``` -Before you use this job you have to register it. -```swift -SendEmailJob.register() -``` -Now you job is ready to create. Jobs can be queued up using the function `enqueue` on `HBJobQueue`. You can access the job queue via `HBApplication.jobs.queue`. There is a helper object attached to `HBRequest` that reduces this to `HBRequest.jobs.enqueue`. -```swift -let job = SendEmailJob( - to: "joe@email.com", - subject: "Testing Jobs", - message: "..." -) -request.jobs.enqueue(job: job) -``` -`enqueue` returns an `EventLoopFuture` that will be fulfilled once the job has been added to the queue. - -## Multiple Queues - -HummingbirdJobs allows for the creation of multiple job queues. To create a new queue you need a new queue id. -```swift -extension HBJobQueueId { - static var newQueue: HBJobQueueId { "newQueue" } -} -``` -Once you have the new queue id you can register your new queue with this id -```swift -app.jobs.registerQueue(.newQueue, queue: .redis(configuration: .init(queueKey: "_myNewJobsQueue"))) -``` -Then when adding jobs you add the queue id to the `enqueue` function -```swift -request.jobs.enqueue(job: job, queue: .newQueue) -``` diff --git a/documentation/Middleware.md b/documentation/Middleware.md deleted file mode 100644 index 7e1b917a8..000000000 --- a/documentation/Middleware.md +++ /dev/null @@ -1,66 +0,0 @@ -# Middleware - -Middleware can be used to edit requests before they are forwared to the router, edit the responses returned by the route handlers or even shortcut the router and return their own responses. Middleware is added to the application as follows. - -```swift -let app = HBApplication() -app.middleware.add(MyMiddlware()) -``` - -## Groups - -Middleware can also be applied to a specific set of routes using groups. Below is a example of applying an authentication middleware `BasicAuthenticatorMiddleware` to routes that need protected. - -```swift -let app = HBApplication() -app.router.put("/user", createUser) -app.router.group() - .add(middleware: BasicAuthenticatorMiddleware()) - .post("/user", loginUser) -``` -The first route that calls `createUser` does not have the `BasicAuthenticatorMiddleware` applied to it. But the route calling `loginUser` which is inside the group does have the middleware applied. - -## Writing Middleware - -All middleware has to conform to the protocol `HBMiddleware`. This requires one function `apply(to:next)` to be implemented. At some point in this function unless you want to shortcut the router and return your own response you are required to call `next.respond(to: request)` and return the result, or a result processed by your middleware. The following is a simple logging middleware that outputs every URI being sent to the server - -```swift -public struct LogRequestsMiddleware: HBMiddleware { - public func apply(to request: HBRequest, next: HBResponder) -> EventLoopFuture { - // log request URI - request.logger.log(level: .debug, String(describing:request.uri.path)) - // pass request onto next middleware or the router - return next.respond(to: request) - } -} -``` - -If you want to process the response after it has been returned by the route handler you will need to use run a function on the `EventLoopFuture` returned by `next.respond`. Swift NIO provide documentation `EventLoopFuture` [here](https://apple.github.io/swift-nio/docs/current/NIO/Classes/EventLoopFuture.html). -```swift -public struct ResponseProcessingMiddleware: HBMiddleware { - public func apply(to request: HBRequest, next: HBResponder) -> EventLoopFuture { - return next.respond(to: request).map { response in - // process responses from handler and middleware further down the chain - return processResponse(response) - } - .flatMapError { error in - // if an error is thrown by handler or middleware further down the - // chain process that - return processError(error) - } - } -} -``` - -## Already available - -Hummingbird comes with a number of middleware already implemented. - -- `HBCORSMiddleware`: Sets CORS headers -- `HBLogRequestsMiddleware`: Outputs request details to the log -- `HBMetricsMiddleware`: Outputs request details to a metrics server - -HummingbirdFoundation also provides some middleware - -- `HBFileMiddleware`: Serves static files -- `HBDateResponseMiddleware`: Sets the date header in the response in an optimal manner. diff --git a/documentation/Persistent Data.md b/documentation/Persistent Data.md deleted file mode 100644 index 9f821690e..000000000 --- a/documentation/Persistent Data.md +++ /dev/null @@ -1,59 +0,0 @@ -# Persistent data - -If you are looking to store data between requests to your server then the Hummingbird `persist` framework provides a key/value store. Each key is a string and the value can be any object that conforms to `Codable`. - -To create a new entry you can call `create` -```swift -let future = request.persist.create(key: "mykey", value: MyValue) -``` -This returns an `EventLoopFuture` which will succeed once the value has been saved. If there is an entry for the key already then the `EventLoopFuture` will fail with the error `HBPersistError.duplicate`. - -If you are not concerned about overwriting a previous key/value pair you can use -```swift -let future = request.persist.set(key: "mykey", value: MyValue) -``` - -Both `create` and `set` have an `expires` parameter. With this parameter you can make a key/value pair expire after a certain time period. eg -```swift -let future = request.persist.set(key: "sessionID", value: MyValue, expires: .hours(1)) -``` - -To access values in the `persist` key/value store you use -```swift -let future = request.persist.get(key: "mykey", as: MyValueType.self) -``` -This returns an `EventLoopFuture` which will succeed with the value associated with key or `nil` if that value doesn't exist or is not of the type requested. - -And finally if you want to delete a key you can use -```swift -let future request.persist.remove(key: "mykey") -``` - -## Drivers - -The `persist` framework defines an API for storing key/value pairs. You also need a driver for the framework. When configuring your application if you want to use `persist` you have to add it to the application and indicate what driver you are going to use. `Hummingbird` comes with a memory based driver which will store these values in the memory of your server. -```swift -app.addPersist(using: .memory) -``` -If you use the memory based driver the key/value pairs you store will be lost if your server goes down. - -## Redis - -You can use Redis to store the `persists` key/value pairs with the `HummingbirdRedis` library. You would setup `persist` to use Redis as follows. To use the Redis driver you need to have setup Redis with Hummingbird as well. -```swift -app.addRedis(configuration: .init(hostname: redisHostname, port: 6379)) -app.addPersist(using: .redis) -``` - -## Fluent - -`HummingbirdFluent` also contains a `persist` driver for the storing the key/value pairs in a database. To setup the Fluent driver you need to have setup Fluent first. The first time you run with the fluent driver you should ensure you call `fluent.migrate()` after the `addPersist` call has been made. -```swift -app.addFluent() -app.fluent.databases.use(...) -app.addPersist(using: .fluent(databaseID)) -if Self.migrate { - app.fluent.migrate() -} -``` - diff --git a/documentation/Router.md b/documentation/Router.md deleted file mode 100644 index f8381ad97..000000000 --- a/documentation/Router.md +++ /dev/null @@ -1,133 +0,0 @@ -# Router - -The router: `HBApplication.router` directs requests to their handlers based on the contents of their path. The router that comes with Hummingbird uses a Trie based lookup. Routes are added using the function `on`. You provide the URI path, the method and the handler function. Below is a simple route which returns "Hello" in the body of the response. - -```swift -let app = HBApplication() -app.router.on("/hello", method: .GET) { request in - return "Hello" -} -``` -If you don't provide a path then the default is for it to be "/". - -## Methods - -There are shortcut functions for common HTTP methods. The above can be written as - -```swift -let app = HBApplication() -app.router.get("/hello") { request in - return "Hello" -} -``` - -There are shortcuts for `put`, `post`, `head`, `patch` and `delete` as well. - -## Response generators - -Route handlers are required to return either a type conforming to the `HBResponseGenerator` protocol or an `EventLoopFuture` of a type conforming to `HBResponseGenerator`. An `EventLoopFuture` is an object that will fulfilled with their value at a later date in an asynchronous manner. The `HBResponseGenerator` protocol requires an object to be able to generate an `HBResponse`. For example `String` has been extended to conform to `HBResponseGenerator` by returning an `HBResponse` with status `.ok`, a content-type header of `text-plain` and a body holding the contents of the `String`. -```swift -/// Extend String to conform to ResponseGenerator -extension String: HBResponseGenerator { - /// Generate response holding string - public func response(from request: HBRequest) -> HBResponse { - let buffer = request.allocator.buffer(string: self) - return HBResponse(status: .ok, headers: ["content-type": "text/plain; charset=utf-8"], body: .byteBuffer(buffer)) - } -} -``` - -In addition to `String` `ByteBuffer`, `HTTPResponseStatus` and `Optional` have also been extended to conform to `HBResponseGenerator`. - -It is also possible to extend `Codable` objects to generate `HBResponses` by conforming these objects to `HBResponseEncodable`. The object will use `HBApplication.encoder` to encode these objects. If an object conforms to `HBResponseEncodable` then also so do arrays of these objects and dictionaries. - -## Parameters - -You can extract parameters out of the URI by prefixing the path with a colon. This indicates that this path section is a parameter. The parameter name is the string following the colon. You can get access to the parameters extracted from the URI with `HBRequest.parameters`. If there are no URI parameters in the path, accessing `HBRequest.parameters` will cause a crash, so don't use it if you haven't specified a parameter in the route path. This example extracts an id from the URI and uses it to return a specific user. so "/user/56" will return user with id 56. - -```swift -let app = HBApplication() -app.router.get("/user/:id") { request in - guard let id = request.parameters.get("id", as: Int.self) else { throw HBHTTPError(.badRequest) } - return getUser(id: id) -} -``` -In the example above if I fail to access the parameter as an `Int` then I throw an error. If you throw an `HBHTTPError` it will get converted to a valid HTTP response. - -## Groups - -Routes can be grouped together in a `HBRouterGroup`. These allow for you to prefix a series of routes with the same path and more importantly apply middleware to only those routes. The example below is a group that includes five handlers all prefixed with the path "/todos". - -```swift -let app = HBApplication() -app.router.group("/todos") - .put(use: createTodo) - .get(use: listTodos) - .get(":id", getTodo) - .patch(":id", editTodo) - .delete(":id", deleteTodo) -``` - -## Route handlers - -A route handler `HBRouteHandler` allows you to encapsulate all the components required for a route, and provide separation of the extraction of input parameters from the request and the processing of those parameters. An example could be structrured as follows - -```swift -struct AddOrder: HBRouteHandler { - struct Input: Decodable { - let name: String - let amount: Double - } - struct Output: HBResponseEncodable { - let id: String - } - let input: Input - let user: User - - init(from request: HBRequest) throws { - self.input = try request.decode(as: Input.self) - self.user = try request.auth.require(User.self) - } - func handle(request: HBRequest) -> EventLoopFuture { - let order = Order(user: self.user.id, details: self.input) - return order.save(on: request.db) - .map { .init(id: order.id) } - } -} -``` -Here you can see the `AddOrder` route handler encapsulates everything you need to know about the add order route. The `Input` and `Output` structs are defined and any additional input parameters that need extracted from the `HBRequest`. The input parameters are extracted in the `init` and then the request is processed in the `handle` function. In this example we need to decode the `Input` from the `HBRequest` and using the authentication framework from `HummingbirdAuth` we get the authenticated user. - -The following will add the handler to the application -```swift -application.router.put("order", use: AddOrder.self) -``` - -## Streaming request body - -By default Hummingbird will collate the contents of your request body into one ByteBuffer. You can access this via `HBRequest.body.buffer`. If you'd prefer to stream the content of the request body, you can add a `.streamBody` option to the route handler to receive a streaming body instead of a single `ByteBuffer`. Inside the route handler you access this stream via `HBRequest.body.stream`. The request body parts are then accessed either via `consume` function which will return everything that has been streamed so far or a `consumeAll` function which takes a closure processing each part. Here is an example which reads the request buffer and returns it size -```swift -application.router.post("size", options: .streamBody) { request -> EventLoopFuture in - guard let stream = request.body.stream else { - return request.failure(.badRequest) - } - var size = 0 - return stream.consumeAll(on: request.eventLoop) { buffer in - size += buffer.readableBytes - return request.eventLoop.makeSucceededFuture(()) - } - .map { size.description } -} -``` - -## Editing response in handler - -The standard way to provide a custom response from a route handler is to return a `HBResponse` from that handler. This method loses a lot of the automation of encoding responses, generating the correct status code etc. - -There is another method though that allows you to edit a response even when returning something other than a `HBResponse`. First you need to flag your route to say it is editing the response using the option `.editResponse`. Once you have set this option you can edit your response via `HBRequest.response`. This allows you to add new headers, replace generated headers or set the status code. Below is a route replacing the generated `content-type` header and setting the status code. -```swift -application.router.post("test", options: .editResponse) { request -> String in - request.response.headers.replaceOrAdd(name: "content-type", value: "application/json") - request.response.status = .accepted - return #"{"test": "value"}"# -} -``` diff --git a/documentation/readme.md b/documentation/readme.md deleted file mode 100644 index 5ecb1f8a5..000000000 --- a/documentation/readme.md +++ /dev/null @@ -1,12 +0,0 @@ -# Hummingbird Documentation - -Hummingbird is split into multiple modules. Below are links to the documentation for each of these modules - -- [Hummingbird](https://hummingbird-project.github.io/hummingbird/current/hummingbird/index.html) -- [HummingbirdAuth](https://hummingbird-project.github.io/hummingbird/current/hummingbird-auth/index.html) -- [HummingbirdCore](https://hummingbird-project.github.io/hummingbird/current/hummingbird-core/index.html) -- [HummingbirdFoundation](https://hummingbird-project.github.io/hummingbird/current/hummingbird-foundation/index.html) -- [HummingbirdJobs](https://hummingbird-project.github.io/hummingbird/current/hummingbird-jobs/index.html) -- [HummingbirdMustache](https://hummingbird-project.github.io/hummingbird/current/hummingbird-mustache/index.html) -- [HummingbirdWebSocket](https://hummingbird-project.github.io/hummingbird/current/hummingbird-websocket/index.html) -- [HummingbirdXCT](https://hummingbird-project.github.io/hummingbird/current/hummingbird-xct/index.html) From 8eed410f48de90be40e2d42134ec54db104a9a6f Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 23 Dec 2023 07:49:21 +0100 Subject: [PATCH 2/2] Remove scripts --- scripts/build-docs.sh | 76 ------------------------------------------ scripts/commit-docs.sh | 38 --------------------- 2 files changed, 114 deletions(-) delete mode 100755 scripts/build-docs.sh delete mode 100755 scripts/commit-docs.sh diff --git a/scripts/build-docs.sh b/scripts/build-docs.sh deleted file mode 100755 index f1471ce88..000000000 --- a/scripts/build-docs.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -PROJECT=${1:-} -CWD=$(pwd) -TEMP_DIR=$(mktemp -d) - -get_latest_version() { - RELEASE_REVISION=$(git rev-list --tags --max-count=1) - echo $(git describe --tags "$RELEASE_REVISION") -} - -build_docs() { - GITHUB_FOLDER=$1 - DOCS_FOLDER=$2 - shift 2 - MODULES=$* - - if [[ -n "$PROJECT" ]]; then - if [[ "$DOCS_FOLDER" != "$PROJECT" ]]; then - return - fi - fi - SOURCEKITTEN_FOLDER="$TEMP_DIR/sourcekitten/$DOCS_FOLDER" - - mkdir -p $SOURCEKITTEN_FOLDER - - SOURCEKITTEN_FILES="" - for MODULE in $MODULES; - do - echo "$MODULE" - sourcekitten doc --spm --module-name "$MODULE" > $SOURCEKITTEN_FOLDER/"$MODULE".json - if [ -z "$SOURCEKITTEN_FILES" ]; then - SOURCEKITTEN_FILES=$SOURCEKITTEN_FOLDER/"$MODULE".json - else - SOURCEKITTEN_FILES="$SOURCEKITTEN_FILES,$SOURCEKITTEN_FOLDER/"$MODULE".json" - fi - done - - VERSION=$(get_latest_version) - jazzy \ - --clean \ - --author "Adam Fowler" \ - --author_url https://github.com/adam-fowler \ - --github_url https://github.com/hummingbird-project/"$GITHUB_FOLDER" \ - --module-version "$VERSION" \ - --sourcekitten-sourcefile "$SOURCEKITTEN_FILES" \ - --readme "$CWD"/documentation/readme.md \ - --documentation "documentation/[^r]*.md" \ - --output "$CWD"/docs/"$DOCS_FOLDER" -} - -build_docs_from_other_repo() { - GITHUB_FOLDER=$1 - - pushd "$TEMP_DIR" - git clone https://github.com/hummingbird-project/"$GITHUB_FOLDER" - cd "$GITHUB_FOLDER" - build_docs $* - - popd -} - -build_docs hummingbird hummingbird Hummingbird -build_docs hummingbird hummingbird-foundation HummingbirdFoundation -build_docs hummingbird hummingbird-jobs HummingbirdJobs -build_docs hummingbird hummingbird-xct HummingbirdXCT - -build_docs_from_other_repo hummingbird-core hummingbird-core HummingbirdCore -build_docs_from_other_repo hummingbird-auth hummingbird-auth HummingbirdAuth -build_docs_from_other_repo hummingbird-mustache hummingbird-mustache HummingbirdMustache -build_docs_from_other_repo hummingbird-websocket hummingbird-websocket HummingbirdWebSocket HummingbirdWSClient HummingbirdWSCore - - -rm -rf "$TEMP_DIR" diff --git a/scripts/commit-docs.sh b/scripts/commit-docs.sh deleted file mode 100755 index 73426b3fe..000000000 --- a/scripts/commit-docs.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -set -eux - -FOLDER=current -SUBFOLDER=${1:-} - -# stash everything that isn't in docs, store result in STASH_RESULT -STASH_RESULT=$(git stash push -- ":(exclude)docs") -# get branch name -CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) -REVISION_HASH=$(git rev-parse HEAD) - -git checkout gh-pages -if [[ -z "$SUBFOLDER" ]]; then - # copy contents of docs to docs/current replacing the ones that are already there - rm -rf "$FOLDER" - mv docs/ "$FOLDER"/ - # commit - git add --all "$FOLDER" -else - # copy contents of subfolder of docs to docs/current replacing the ones that are already there - rm -rf "$FOLDER"/"$SUBFOLDER" - mv docs/"$SUBFOLDER"/ "$FOLDER"/"$SUBFOLDER" - # commit - git add --all "$FOLDER"/"$SUBFOLDER" -fi - -git status -git commit -m "Documentation for https://github.com/hummingbird-project/hummingbird/tree/$REVISION_HASH" -git push -# return to branch -git checkout $CURRENT_BRANCH - -if [ "$STASH_RESULT" != "No local changes to save" ]; then - git stash pop -fi -