Skip to content

Commit

Permalink
Add yangIgnorePath setting
Browse files Browse the repository at this point in the history
This allows for exclusion of specific subdirs or files under the dirs
specified via `yangPath`.

Also formatted markdown files to fix markdownlint issues.

This addresses #232

Signed-off-by: Siddharth Sharma <[email protected]>
  • Loading branch information
esmasth committed Apr 1, 2024
1 parent 0e0d1c6 commit f88d537
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 150 deletions.
11 changes: 6 additions & 5 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
root = true

[*.json]
[*]
charset = utf-8
trim_trailing_whitespace = true
end_of_line = lf
insert_final_newline = true

[*.json]
indent_style = space
indent_size = 2

[*.md]
charset = utf-8
trim_trailing_whitespace = true
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2

[{*.xtext,*.xtend}]
indent_size = 4
109 changes: 57 additions & 52 deletions docs/Extensions.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# Extensions

The yang-lsp allows to have additional third party extensions, configured through the [`yang.settings` file](Settings.md).
That file must be located in the root of an opened directory must conform to JSON syntax.
The yang-lsp allows to have additional third party extensions, configured
through the [`yang.settings` file](Settings.md). That file must be located in
the root of an opened directory must conform to JSON syntax.

So far two different kinds of extensions are supported :
- Validators (`IValidatorExtension`)
- Commands (`ICommandExtension`)

- Validators (`IValidatorExtension`)
- Commands (`ICommandExtension`)

## Create a Validator

A validator extension is a Java class that implements the interface `io.typefox.yang.validation.IValidatorExtension`.
Here is a small example:
A validator extension is a Java class that implements the interface
`io.typefox.yang.validation.IValidatorExtension`. Here is a small example:

```java
package my.pack;
Expand All @@ -19,72 +21,75 @@ package my.pack;

public class MyExampleValidator implements IValidatorExtension {

public static final String BAD_NAME = "bad_name";
public static final String BAD_NAME = "bad_name";

@Override
public void validate(AbstractModule module, IAcceptor<Issue> issueAcceptor, CancelIndicator cancelIndicator) {
if (module.getName().equals("foo")) {
issueAcceptor.accept(IssueFactory.createIssue(module, YangPackage.Literals.ABSTRACT_MODULE__NAME, "'foo' is a bad name", BAD_NAME));
}
}
@Override
public void validate(AbstractModule module, IAcceptor<Issue> issueAcceptor, CancelIndicator cancelIndicator) {
if (module.getName().equals("foo")) {
issueAcceptor.accept(IssueFactory.createIssue(module, YangPackage.Literals.ABSTRACT_MODULE__NAME, "'foo' is a bad name", BAD_NAME));
}
}

}
```
```

## Create a Command Extension

A command extension contributes actions, that will be shown in the context menu of a supporting client (currently only Yangster supports it).
A command extension contributes actions, that will be shown in the context menu
of a supporting client (currently only Yangster supports it).

Here is an example:

```xtend
```java
class MyCommand implements ICommandExtension {

static val COMMAND = "Create a file name 'foo.txt'."
/**
* return a list of commands. A command string is used as ID internally and as a label in the UI.
*/
override getCommands() {
#[COMMAND]
}
/**
* Called when the user asked to execute a certain command.
*/
override executeCommand(String command, Resource resource, LanguageClient client) {
if (COMMAND == command) {
// get the project directory
val uri = ProjectConfigAdapter.findInEmfObject(resource.resourceSet)?.projectConfig?.path.toFileString
val f = new File(uri, 'foo.txt')
if (f.exists) {
client.showMessage(new MessageParams => [
message = 'Such a file already exists.'
])
} else {
f.createNewFile
}
}
}
static val COMMAND = "Create a file name 'foo.txt'."

/**
* return a list of commands. A command string is used as ID internally and as a label in the UI.
*/
override getCommands() {
#[COMMAND]
}

/**
* Called when the user asked to execute a certain command.
*/
override executeCommand(String command, Resource resource, LanguageClient client) {
if (COMMAND == command) {
// get the project directory
val uri = ProjectConfigAdapter.findInEmfObject(resource.resourceSet)?.projectConfig?.path.toFileString
val f = new File(uri, 'foo.txt')
if (f.exists) {
client.showMessage(new MessageParams => [
message = 'Such a file already exists.'
])
} else {
f.createNewFile
}
}
}

}
```


## Package an extension

The class needs to be packaged in a jar. So simply use the java build tool of your preference to create a jar from it. Put the jar somewhere relative to the project's root directory.
The class needs to be packaged in a jar. So simply use the java build tool of
your preference to create a jar from it. Put the jar somewhere relative to the
project's root directory.

## Add the plugin

Create (or open) the `yang.settings` file and add the plugin using the following configuration:
Create (or open) the `yang.settings` file and add the plugin using the following
configuration:

```json
"extension" : {
"classpath" : "extension.jar",
"validators" : "my.pack.MyExampleValidator",
"commands" : "my.pack.MyCommand"
}
"extension" : {
"classpath" : "extension.jar",
"validators" : "my.pack.MyExampleValidator",
"commands" : "my.pack.MyCommand"
}
```

The language server will automatically pick up the extension.

116 changes: 62 additions & 54 deletions docs/Processing_Files.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# Processing YANG files
# Processing YANG files

As yang-lsp contains all the tools to parse, link and validate YANG models. If you want to further process the YANG files you authored with yang-lsp it makes sense to make reuse of the existing functionality.
As yang-lsp contains all the tools to parse, link and validate YANG models. If
you want to further process the YANG files you authored with yang-lsp it makes
sense to make reuse of the existing functionality.

Here is some example code in Xtend for an application that reads in all YANG files from a given directory. The files are parsed into our YANG EMF model, all cross-references are resolved and all files are validated. If there are no errors, the method `generate()` is called for all resources:
Here is some example code in Xtend for an application that reads in all YANG
files from a given directory. The files are parsed into our YANG EMF model, all
cross-references are resolved and all files are validated. If there are no
errors, the method `generate()` is called for all resources:

```Xtend
```xtend
package io.typefox.yang.example
import com.google.inject.Inject
Expand All @@ -20,66 +25,67 @@ import org.eclipse.xtext.util.CancelIndicator
import org.eclipse.xtext.validation.CheckMode
import org.eclipse.xtext.validation.IResourceValidator
class StandaloneExample {
def static void main(String... args) {
val injector = new YangStandaloneSetup().createInjectorAndDoEMFRegistration
injector.getInstance(StandaloneExample).run(args)
}
@Inject XtextResourceSet resourceSet
@Inject IResourceValidator validator
boolean hasErrors = false
def void run(String... args) {
addFile(new File(args.head))
resourceSet.resources.forEach [ resource |
EcoreUtil.resolveAll(resource)
val issues = validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl)
issues.forEach [ issue |
hasErrors = hasErrors || issue.severity === Severity.ERROR
System.err.println(issue)
]
]
if(!hasErrors) {
resourceSet.resources.forEach [
generate
]
}
}
def void addFile(File file) {
if(file.isDirectory)
file.listFiles.forEach[ addFile ]
else if(file.name.endsWith('.yang'))
resourceSet.getResource(URI.createURI(file.toURI.toString), true)
}
def generate(Resource resource) {
// do your own processing here
resource.allContents.filter(Module).forEach [ module |
println('''
Found module «module.name»
''')
]
}
class StandaloneExample {
def static void main(String... args) {
val injector = new YangStandaloneSetup().createInjectorAndDoEMFRegistration
injector.getInstance(StandaloneExample).run(args)
}
@Inject XtextResourceSet resourceSet
@Inject IResourceValidator validator
boolean hasErrors = false
def void run(String... args) {
addFile(new File(args.head))
resourceSet.resources.forEach [ resource |
EcoreUtil.resolveAll(resource)
val issues = validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl)
issues.forEach [ issue |
hasErrors = hasErrors || issue.severity === Severity.ERROR
System.err.println(issue)
]
]
if(!hasErrors) {
resourceSet.resources.forEach [
generate
]
}
}
def void addFile(File file) {
if(file.isDirectory)
file.listFiles.forEach[ addFile ]
else if(file.name.endsWith('.yang'))
resourceSet.getResource(URI.createURI(file.toURI.toString), true)
}
def generate(Resource resource) {
// do your own processing here
resource.allContents.filter(Module).forEach [ module |
println('''
Found module «module.name»
''')
]
}
}
```
A number of useful helper methods can be found in the [utils package](https://github.com/theia-ide/yang-lsp/tree/master/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/utils)

A number of useful helper methods can be found in the [utils package][1]

Here is sample `build.gradle` to build the above class:

```groovy
buildscript {
repositories.jcenter()
dependencies {
classpath 'org.xtext:xtext-gradle-plugin:1.0.19'
}
repositories.jcenter()
dependencies {
classpath 'org.xtext:xtext-gradle-plugin:1.0.19'
}
}
repositories {
jcenter()
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}
apply plugin: 'org.xtext.xtend'
Expand All @@ -90,10 +96,12 @@ apply plugin: 'maven'
group = 'io.typefox.yang'
version = '0.1.0-SNAPSHOT'
dependencies {
dependencies {
compile 'io.typefox.yang:io.typefox.yang:0.1.0-SNAPSHOT'
compile 'org.eclipse.xtext:org.eclipse.xtext:2.13.0'
compile 'org.eclipse.xtend:org.eclipse.xtend.lib:2.13.0'
compile 'com.google.inject:guice:3.0'
}
```

[1]: https://github.com/TypeFox/yang-lsp/tree/master/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/utils
Loading

0 comments on commit f88d537

Please sign in to comment.