diff --git a/Changelog.md b/Changelog.md index 975a1b2b..7903b0f7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added end-to-end tests for command-line interface. #199 by @MaxDesiatov and @mattt. +- Added `--minimum-access-level` option to `generate` and `coverage` commands. + #219 by @Lukas-Stuehrk. ### Fixed diff --git a/README.md b/README.md index c4fc08cc..3cff9d4a 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,9 @@ $ apt-get install -y libxml2-dev graphviz -f, --format The output format (default: commonmark) --base-url The base URL used for all relative URLs in generated documents. (default: /) + --minimum-access-level + The minimum access level of the symbols which should + be included. (default: public) -h, --help Show help information. The `generate` subcommand @@ -131,6 +134,12 @@ $ Documentation/ └── index.html ``` +By default, +`swift-doc` includes only symbols declared as `public` or `open` +in the generated documentation. +To include `internal` or `private` declarations, +pass the `--minimum-access-level` flag with the specified access level. + #### swift-doc coverage OVERVIEW: Generates documentation coverage statistics for Swift files @@ -142,6 +151,9 @@ $ Documentation/ OPTIONS: -o, --output The path for generated report + --minimum-access-level + The minimum access level of the symbols which should + be included. (default: public) -h, --help Show help information. The `coverage` subcommand @@ -190,6 +202,9 @@ please reach out by [opening an Issue][open an issue]! One or more paths to Swift files OPTIONS: + --minimum-access-level + The minimum access level of the symbols which should + be included. (default: public) -h, --help Show help information. The `diagram` subcommand diff --git a/Sources/SwiftDoc/Interface.swift b/Sources/SwiftDoc/Interface.swift index d5adac70..65e37993 100644 --- a/Sources/SwiftDoc/Interface.swift +++ b/Sources/SwiftDoc/Interface.swift @@ -8,14 +8,13 @@ public final class Interface { public required init(imports: [Import], symbols: [Symbol]) { self.imports = imports - self.symbols = symbols.filter { $0.isPublic } + self.symbols = symbols self.symbolsGroupedByIdentifier = Dictionary(grouping: symbols, by: { $0.id }) self.symbolsGroupedByQualifiedName = Dictionary(grouping: symbols, by: { $0.id.description }) self.topLevelSymbols = symbols.filter { $0.api is Type || $0.id.pathComponents.isEmpty } self.relationships = { - let symbols = symbols.filter { $0.isPublic } let extensionsByExtendedType: [String: [Extension]] = Dictionary(grouping: symbols.flatMap { $0.context.compactMap { $0 as? Extension } }, by: { $0.extendedType }) var relationships: Set = [] diff --git a/Sources/SwiftDoc/Symbol.swift b/Sources/SwiftDoc/Symbol.swift index 1174b6a2..fe2fa345 100644 --- a/Sources/SwiftDoc/Symbol.swift +++ b/Sources/SwiftDoc/Symbol.swift @@ -66,6 +66,44 @@ public final class Symbol { return false } + public var isPrivate: Bool { + // We always assume that `Unknown` is public. + guard api is Unknown == false else { + return false + } + + if api.modifiers.contains(where: { $0.detail == nil && ($0.name == "private" || $0.name == "fileprivate") }) { + return true + } + + if let `extension` = `extension`, + `extension`.modifiers.contains(where: { $0.name == "private" || $0.name == "fileprivate" }) { + + return api.modifiers.allSatisfy { modifier in + modifier.detail != nil || (modifier.name != "internal" && modifier.name != "public" && modifier.name != "open") + } + } + + if let symbol = context.compactMap({ $0 as? Symbol }).last, + symbol.api.modifiers.contains(where: { $0.name == "private" || $0.name == "fileprivate" }) + { + switch symbol.api { + case is Enumeration: + return api is Enumeration.Case + case is Protocol: + return api is Function || api is Variable + default: + break + } + } + + return false + } + + public var isInternal: Bool { + !isPublic && !isPrivate + } + public var isDocumented: Bool { return documentation?.isEmpty == false } diff --git a/Sources/swift-doc/Extensions/DCOV+Extensions.swift b/Sources/swift-doc/Extensions/DCOV+Extensions.swift index fbd423cd..20d375f4 100644 --- a/Sources/swift-doc/Extensions/DCOV+Extensions.swift +++ b/Sources/swift-doc/Extensions/DCOV+Extensions.swift @@ -18,10 +18,10 @@ extension Entry { // MARK: - extension Report { - public init(module: Module) { + public init(module: Module, symbolFilter: (Symbol) -> Bool) { let entries = module.sourceFiles .flatMap { $0.symbols } - .filter { $0.isPublic } + .filter(symbolFilter) .map { Entry($0) } self.init(entries: entries) diff --git a/Sources/swift-doc/Subcommands/Coverage.swift b/Sources/swift-doc/Subcommands/Coverage.swift index b26d5a40..63a845ae 100644 --- a/Sources/swift-doc/Subcommands/Coverage.swift +++ b/Sources/swift-doc/Subcommands/Coverage.swift @@ -12,6 +12,10 @@ extension SwiftDoc { @Option(name: .shortAndLong, help: "The path for generated report") var output: String? + + @Option(name: .long, + help: "The minimum access level of the symbols considered for coverage statistics.") + var minimumAccessLevel: AccessLevel = .public } static var configuration = CommandConfiguration(abstract: "Generates documentation coverage statistics for Swift files") @@ -21,7 +25,7 @@ extension SwiftDoc { func run() throws { let module = try Module(paths: options.inputs) - let report = Report(module: module) + let report = Report(module: module, symbolFilter: options.minimumAccessLevel.includes(symbol:)) if let output = options.output { let encoder = JSONEncoder() diff --git a/Sources/swift-doc/Subcommands/Diagram.swift b/Sources/swift-doc/Subcommands/Diagram.swift index 4986df23..280bc596 100644 --- a/Sources/swift-doc/Subcommands/Diagram.swift +++ b/Sources/swift-doc/Subcommands/Diagram.swift @@ -11,23 +11,27 @@ extension SwiftDoc { struct Options: ParsableArguments { @Argument(help: "One or more paths to Swift files") var inputs: [String] + + @Option(name: .long, + help: "The minimum access level of the symbols included in the generated diagram.") + var minimumAccessLevel: AccessLevel = .public } static var configuration = CommandConfiguration(abstract: "Generates diagram of Swift symbol relationships") @OptionGroup() var options: Options - + func run() throws { let module = try Module(paths: options.inputs) - print(diagram(of: module), to: &standardOutput) + print(diagram(of: module, including: options.minimumAccessLevel.includes(symbol:)), to: &standardOutput) } } } // MARK: - -fileprivate func diagram(of module: Module) -> String { +fileprivate func diagram(of module: Module, including symbolFilter: (Symbol) -> Bool) -> String { var graph = Graph(directed: true) for (baseClass, subclasses) in module.interface.classHierarchies { @@ -61,7 +65,7 @@ fileprivate func diagram(of module: Module) -> String { } - for symbol in (module.interface.symbols.filter { $0.isPublic && $0.api is Type }) { + for symbol in (module.interface.symbols.filter { $0.api is Type }).filter(symbolFilter) { let symbolNode = Node("\(symbol.id)") graph.append(symbolNode) diff --git a/Sources/swift-doc/Subcommands/Generate.swift b/Sources/swift-doc/Subcommands/Generate.swift index 616b6658..cca17a59 100644 --- a/Sources/swift-doc/Subcommands/Generate.swift +++ b/Sources/swift-doc/Subcommands/Generate.swift @@ -35,6 +35,10 @@ extension SwiftDoc { @Option(name: .customLong("base-url"), help: "The base URL used for all relative URLs in generated documents.") var baseURL: String = "/" + + @Option(name: .long, + help: "The minimum access level of the symbols included in generated documentation.") + var minimumAccessLevel: AccessLevel = .public } static var configuration = CommandConfiguration(abstract: "Generates Swift documentation") @@ -55,10 +59,11 @@ extension SwiftDoc { var pages: [String: Page] = [:] var globals: [String: [Symbol]] = [:] - for symbol in module.interface.topLevelSymbols.filter({ $0.isPublic }) { + let symbolFilter = options.minimumAccessLevel.includes(symbol:) + for symbol in module.interface.topLevelSymbols.filter(symbolFilter) { switch symbol.api { case is Class, is Enumeration, is Structure, is Protocol: - pages[route(for: symbol)] = TypePage(module: module, symbol: symbol, baseURL: baseURL) + pages[route(for: symbol)] = TypePage(module: module, symbol: symbol, baseURL: baseURL, includingChildren: symbolFilter) case let `typealias` as Typealias: pages[route(for: `typealias`.name)] = TypealiasPage(module: module, symbol: symbol, baseURL: baseURL) case let function as Function where !function.isOperator: @@ -76,6 +81,9 @@ extension SwiftDoc { guard !pages.isEmpty else { logger.warning("No public API symbols were found at the specified path. No output was written.") + if options.minimumAccessLevel == .public { + logger.warning("By default, swift-doc only includes public declarations. Maybe you want to use --minimum-access-level to include non-public declarations?") + } return } @@ -93,11 +101,11 @@ extension SwiftDoc { } else { switch format { case .commonmark: - pages["Home"] = HomePage(module: module, baseURL: baseURL) - pages["_Sidebar"] = SidebarPage(module: module, baseURL: baseURL) + pages["Home"] = HomePage(module: module, baseURL: baseURL, symbolFilter: symbolFilter) + pages["_Sidebar"] = SidebarPage(module: module, baseURL: baseURL, symbolFilter: symbolFilter) pages["_Footer"] = FooterPage(baseURL: baseURL) case .html: - pages["Home"] = HomePage(module: module, baseURL: baseURL) + pages["Home"] = HomePage(module: module, baseURL: baseURL, symbolFilter: symbolFilter) } try pages.map { $0 }.parallelForEach { diff --git a/Sources/swift-doc/Supporting Types/AccessLevel.swift b/Sources/swift-doc/Supporting Types/AccessLevel.swift new file mode 100644 index 00000000..30de853f --- /dev/null +++ b/Sources/swift-doc/Supporting Types/AccessLevel.swift @@ -0,0 +1,16 @@ +import ArgumentParser +import SwiftDoc + +enum AccessLevel: String, ExpressibleByArgument { + case `public` + case `internal` + + func includes(symbol: Symbol) -> Bool { + switch self { + case .public: + return symbol.isPublic + case .internal: + return symbol.isPublic || symbol.isInternal + } + } +} diff --git a/Sources/swift-doc/Supporting Types/Components/Members.swift b/Sources/swift-doc/Supporting Types/Components/Members.swift index d7d26a32..b653b25d 100644 --- a/Sources/swift-doc/Supporting Types/Components/Members.swift +++ b/Sources/swift-doc/Supporting Types/Components/Members.swift @@ -18,14 +18,14 @@ struct Members: Component { var methods: [Symbol] var genericallyConstrainedMembers: [[GenericRequirement] : [Symbol]] - init(of symbol: Symbol, in module: Module, baseURL: String) { + init(of symbol: Symbol, in module: Module, baseURL: String, symbolFilter: (Symbol) -> Bool) { self.symbol = symbol self.module = module self.baseURL = baseURL self.members = module.interface.members(of: symbol) .filter { $0.extension?.genericRequirements.isEmpty != false } - .filter { $0.isPublic } + .filter(symbolFilter) self.typealiases = members.filter { $0.api is Typealias } self.initializers = members.filter { $0.api is Initializer } diff --git a/Sources/swift-doc/Supporting Types/Pages/HomePage.swift b/Sources/swift-doc/Supporting Types/Pages/HomePage.swift index 425c8d89..27090a08 100644 --- a/Sources/swift-doc/Supporting Types/Pages/HomePage.swift +++ b/Sources/swift-doc/Supporting Types/Pages/HomePage.swift @@ -16,11 +16,11 @@ struct HomePage: Page { var globalFunctions: [Symbol] = [] var globalVariables: [Symbol] = [] - init(module: Module, baseURL: String) { + init(module: Module, baseURL: String, symbolFilter: (Symbol) -> Bool) { self.module = module self.baseURL = baseURL - for symbol in module.interface.topLevelSymbols.filter({ $0.isPublic }) { + for symbol in module.interface.topLevelSymbols.filter(symbolFilter) { switch symbol.api { case is Class: classes.append(symbol) diff --git a/Sources/swift-doc/Supporting Types/Pages/SidebarPage.swift b/Sources/swift-doc/Supporting Types/Pages/SidebarPage.swift index 7b71908b..cbbce3b0 100644 --- a/Sources/swift-doc/Supporting Types/Pages/SidebarPage.swift +++ b/Sources/swift-doc/Supporting Types/Pages/SidebarPage.swift @@ -14,11 +14,11 @@ struct SidebarPage: Page { var globalFunctionNames: Set = [] var globalVariableNames: Set = [] - init(module: Module, baseURL: String) { + init(module: Module, baseURL: String, symbolFilter: (Symbol) -> Bool) { self.module = module self.baseURL = baseURL - for symbol in module.interface.topLevelSymbols.filter({ $0.isPublic }) { + for symbol in module.interface.topLevelSymbols.filter(symbolFilter) { switch symbol.api { case is Class: typeNames.insert(symbol.id.description) diff --git a/Sources/swift-doc/Supporting Types/Pages/TypePage.swift b/Sources/swift-doc/Supporting Types/Pages/TypePage.swift index 244e736a..b3bee3f7 100644 --- a/Sources/swift-doc/Supporting Types/Pages/TypePage.swift +++ b/Sources/swift-doc/Supporting Types/Pages/TypePage.swift @@ -7,12 +7,14 @@ struct TypePage: Page { let module: Module let symbol: Symbol let baseURL: String + let symbolFilter: (Symbol) -> Bool - init(module: Module, symbol: Symbol, baseURL: String) { + init(module: Module, symbol: Symbol, baseURL: String, includingChildren symbolFilter: @escaping (Symbol) -> Bool) { precondition(symbol.api is Type) self.module = module self.symbol = symbol self.baseURL = baseURL + self.symbolFilter = symbolFilter } // MARK: - Page @@ -27,7 +29,7 @@ struct TypePage: Page { Documentation(for: symbol, in: module, baseURL: baseURL) Relationships(of: symbol, in: module, baseURL: baseURL) - Members(of: symbol, in: module, baseURL: baseURL) + Members(of: symbol, in: module, baseURL: baseURL, symbolFilter: symbolFilter) Requirements(of: symbol, in: module, baseURL: baseURL) } } @@ -41,7 +43,7 @@ struct TypePage: Page { \#(Documentation(for: symbol, in: module, baseURL: baseURL).html) \#(Relationships(of: symbol, in: module, baseURL: baseURL).html) - \#(Members(of: symbol, in: module, baseURL: baseURL).html) + \#(Members(of: symbol, in: module, baseURL: baseURL, symbolFilter: symbolFilter).html) \#(Requirements(of: symbol, in: module, baseURL: baseURL).html) """# } diff --git a/Tests/SwiftDocTests/InterfaceTypeTests.swift b/Tests/SwiftDocTests/InterfaceTypeTests.swift index 0c3db153..42ba0ba9 100644 --- a/Tests/SwiftDocTests/InterfaceTypeTests.swift +++ b/Tests/SwiftDocTests/InterfaceTypeTests.swift @@ -31,12 +31,11 @@ final class InterfaceTypeTests: XCTestCase { // `class C` let classC = sourceFile.symbols[2] XCTAssert(classC.api is Class) - - // Class B does not exist in subclasses because it's not public - // Class C exists in subclasses because it's public + let subclasses = module.interface.typesInheriting(from: classA) - XCTAssertEqual(subclasses.count, 1) - XCTAssertEqual(subclasses[0].id, classC.id) + XCTAssertEqual(subclasses.count, 2) + XCTAssertEqual(subclasses[0].id, classB.id) + XCTAssertEqual(subclasses[1].id, classC.id) } func testInternalMembers() throws { @@ -60,7 +59,7 @@ final class InterfaceTypeTests: XCTestCase { let module = Module(name: "Module", sourceFiles: [sourceFile]) XCTAssertEqual(sourceFile.symbols.count, 5) - XCTAssertEqual(module.interface.symbols.count, 1) + XCTAssertEqual(module.interface.symbols.count, 5) // `struct A` do { @@ -87,12 +86,22 @@ final class InterfaceTypeTests: XCTestCase { XCTAssertEqual(sourceFile.symbols.count, 5) XCTAssertTrue(sourceFile.symbols[0].isPublic, "Function `a()` should BE marked as public - its visibility is specified by extension") + XCTAssertFalse(sourceFile.symbols[0].isInternal, "Function `a()` should NOT be marked as internal") + XCTAssertFalse(sourceFile.symbols[0].isPrivate, "Function `a()` should NOT be marked as private") XCTAssertTrue(sourceFile.symbols[1].isPublic, "Function `b()` should BE marked as public - its visibility is public") + XCTAssertFalse(sourceFile.symbols[1].isInternal, "Function `b()` should NOT be marked as internal") + XCTAssertFalse(sourceFile.symbols[1].isPrivate, "Function `b()` should NOT be marked as private") XCTAssertFalse(sourceFile.symbols[2].isPublic, "Function `c()` should NOT be marked as public - its visibility is internal") + XCTAssertTrue(sourceFile.symbols[2].isInternal, "Function `c()` should BE marked as internal - its visibility is internal.") + XCTAssertFalse(sourceFile.symbols[2].isPrivate, "Function `c()` should NOT be marked as private") XCTAssertFalse(sourceFile.symbols[3].isPublic, "Function `d()` should NOT be marked as public - its visibility is fileprivate") + XCTAssertFalse(sourceFile.symbols[3].isInternal, "Function `d()` should NOT be marked as internal - its visibility is fileprivate") + XCTAssertTrue(sourceFile.symbols[3].isPrivate, "Function `d()` should BE marked as public - its visibility is fileprivate") XCTAssertFalse(sourceFile.symbols[4].isPublic, "Function `e()` should NOT be marked as public - its visibility is private") + XCTAssertFalse(sourceFile.symbols[4].isInternal, "Function `e()` should NOT be marked as public - its visibility is private") + XCTAssertTrue(sourceFile.symbols[4].isPrivate, "Function `e()` should BE marked as private - its visibility is private") - XCTAssertEqual(module.interface.symbols.count, 2) + XCTAssertEqual(module.interface.symbols.count, 5) XCTAssertEqual(module.interface.symbols[0].name, "a()", "Function `a()` should be in documented interface") XCTAssertEqual(module.interface.symbols[1].name, "b()", "Function `b()` should be in documented interface") } @@ -114,14 +123,27 @@ final class InterfaceTypeTests: XCTestCase { XCTAssertEqual(sourceFile.symbols.count, 5) XCTAssertTrue(sourceFile.symbols[0].isPublic, "Property `a` should BE marked as public - its visibility is specified by extension") + XCTAssertFalse(sourceFile.symbols[0].isInternal, "Property `a` should NOT be marked as internal - its visibility is specified public by extension") + XCTAssertFalse(sourceFile.symbols[0].isPrivate, "Property `a` should NOT be marked as private - its visibility is specified public by extension") XCTAssertTrue(sourceFile.symbols[1].isPublic, "Property `b` should BE marked as public - its visibility is public") + XCTAssertFalse(sourceFile.symbols[1].isInternal, "Property `b` should NOT be marked as internal - its visibility is public") + XCTAssertFalse(sourceFile.symbols[1].isPrivate, "Property `b` should NOT be marked as private - its visibility is public") XCTAssertFalse(sourceFile.symbols[2].isPublic, "Property `c` should NOT be marked as public - its visibility is internal") + XCTAssertTrue(sourceFile.symbols[2].isInternal, "Property `c` should BE marked as internal - its visibility is internal") + XCTAssertFalse(sourceFile.symbols[2].isPrivate, "Property `c` should NOT be marked as private - its visibility is internal") XCTAssertFalse(sourceFile.symbols[3].isPublic, "Property `d` should NOT be marked as public - its visibility is fileprivate") + XCTAssertFalse(sourceFile.symbols[3].isInternal, "Property `d` should NOT be marked as internal - its visibility is fileprivate") + XCTAssertTrue(sourceFile.symbols[3].isPrivate, "Property `d` should BE marked as private - its visibility is fileprivate") XCTAssertFalse(sourceFile.symbols[4].isPublic, "Property `e` should NOT be marked as public - its visibility is private") + XCTAssertFalse(sourceFile.symbols[4].isInternal, "Property `e` should NOT be marked as internal - its visibility is private") + XCTAssertTrue(sourceFile.symbols[4].isPrivate, "Property `e` should BE marked as public - its visibility is private") - XCTAssertEqual(module.interface.symbols.count, 2) + XCTAssertEqual(module.interface.symbols.count, 5) XCTAssertEqual(module.interface.symbols[0].name, "a", "Property `a` should be in documented interface") XCTAssertEqual(module.interface.symbols[1].name, "b", "Property `b` should be in documented interface") + XCTAssertEqual(module.interface.symbols[2].name, "c", "Property `c` should be in documented interface") + XCTAssertEqual(module.interface.symbols[3].name, "d", "Property `d` should be in documented interface") + XCTAssertEqual(module.interface.symbols[4].name, "e", "Property `e` should be in documented interface") } func testComputedPropertiesWithMultipleAccessModifiersInPublicExtension() throws { @@ -156,10 +178,20 @@ final class InterfaceTypeTests: XCTestCase { XCTAssertEqual(sourceFile.symbols.count, 5) XCTAssertTrue(sourceFile.symbols[0].isPublic, "Property `a` should be marked as public - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[0].isInternal, "Property `a` should not be marked as internal - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[0].isPrivate, "Property `a` should not be marked as private - the visibility of its getter is public") XCTAssertTrue(sourceFile.symbols[1].isPublic, "Property `b` should be marked as public - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[1].isInternal, "Property `b` should not be marked as internal - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[1].isPrivate, "Property `b` should not be marked as private - the visibility of its getter is public") XCTAssertTrue(sourceFile.symbols[2].isPublic, "Property `c` should be marked as public - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[2].isInternal, "Property `c` should not be marked as internal - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[2].isPrivate, "Property `c` should not be marked as private - the visibility of its getter is public") XCTAssertTrue(sourceFile.symbols[3].isPublic, "Property `d` should be marked as public - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[3].isInternal, "Property `d` should not be marked as internal - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[3].isPrivate, "Property `d` should not be marked as private - the visibility of its getter is public") XCTAssertTrue(sourceFile.symbols[4].isPublic, "Property `e` should be marked as public - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[4].isInternal, "Property `e` should not be marked as internal - the visibility of its getter is public") + XCTAssertFalse(sourceFile.symbols[4].isPrivate, "Property `e` should not be marked as private - the visibility of its getter is public") XCTAssertEqual(module.interface.symbols.count, 5) XCTAssertEqual(module.interface.symbols[0].name, "a", "Property `a` should be in documented interface") @@ -198,11 +230,14 @@ final class InterfaceTypeTests: XCTestCase { let sourceFile = try SourceFile(file: url, relativeTo: url.deletingLastPathComponent()) let module = Module(name: "Module", sourceFiles: [sourceFile]) - XCTAssertEqual(module.interface.symbols.count, 5) + XCTAssertEqual(module.interface.symbols.count, 8) XCTAssertEqual(module.interface.symbols[0].name, "RootController") XCTAssertEqual(module.interface.symbols[1].name, "ControllerExtension") XCTAssertEqual(module.interface.symbols[2].name, "public_properties") - XCTAssertEqual(module.interface.symbols[3].name, "ExtendedProperties") - XCTAssertEqual(module.interface.symbols[4].name, "public_prop") + XCTAssertEqual(module.interface.symbols[3].name, "internal_properties") + XCTAssertEqual(module.interface.symbols[4].name, "ExtendedProperties") + XCTAssertEqual(module.interface.symbols[5].name, "public_prop") + XCTAssertEqual(module.interface.symbols[6].name, "InternalProperties") + XCTAssertEqual(module.interface.symbols[7].name, "internal_prop") } } diff --git a/action.yml b/action.yml index 46c691e6..9f26e8be 100644 --- a/action.yml +++ b/action.yml @@ -20,6 +20,10 @@ inputs: description: "The path for generated output" required: true default: "./.build/documentation" + minimum-access-level: + description: "The minimum access level of the symbols which should be included (public, internal, or private)" + required: false + default: "public" runs: using: "docker" @@ -36,6 +40,8 @@ runs: "${{ inputs.module-name }}", --output, "${{ inputs.output }}", + --minimum-access-level, + "${{ inputs.minimum-access-level }}" ] branding: