-
Notifications
You must be signed in to change notification settings - Fork 47
Read "official" default API versions from spec readmes #3996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
thomas11
wants to merge
8
commits into
master
Choose a base branch
from
tkappler/default-versions-from-spec
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 5 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
525f3ec
Parse default version from a readme.md. Doesn't support composite pac…
thomas11 3d238d4
A bit of docs
thomas11 4b2212b
Read "official" default API versions from spec readmes
thomas11 92eb324
very dirty WIP
thomas11 b990681
Refactor to be a separate target of main. Find readme.md in both simp…
thomas11 2cd0aaf
Add autorest config extraction
danielrbradley dd49f59
Join autorest input files to module resources
danielrbradley 1a404e8
Fix unstable ordering
danielrbradley File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| package openapi | ||
|
|
||
| import ( | ||
| "bufio" | ||
| "io" | ||
| "strings" | ||
| ) | ||
|
|
||
| // # How to determine the default API version of a service? | ||
| // | ||
| // It's in the `readme.md` file of the service in azure-rest-api-specs, in a yaml code block with a `tag` field. | ||
| // | ||
| // Example: | ||
| // | ||
| // ```yaml | ||
| // openapi-type: arm | ||
| // tag: package-2025-03-01 | ||
| // ``` | ||
| // | ||
| // There will be other fields as well. | ||
| // | ||
| // The version can be just a year and month, in which case the API version is the only one released in that month. | ||
| // | ||
| // The version can also be a composite version like `tag: package-composite-v5`. I don't fully understand those yet. | ||
| // | ||
| // ## Spec version | ||
| // Since we're reading the readme.md files from the azure-rest-api-specs repo, we need to know which commit of the | ||
| // file to read. The `main` branch of the spec can be updated with new API versions that SDKs are not using yet. In | ||
| // case of stable versions, this is _probably_ ok, in case of preview versions it's more questionable. But we cannot | ||
| // simply use the latest stable version since some services barely release stable versions. | ||
|
|
||
| // TODO service groups | ||
| func ReadDefaultVersionFromReadme(readme io.Reader) (map[Service]ApiVersion, error) { | ||
| var version string | ||
| var inYamlBlock bool | ||
|
|
||
| scanner := bufio.NewScanner(readme) | ||
| for scanner.Scan() { | ||
| line := strings.TrimSpace(scanner.Text()) | ||
| if line == "```yaml" || line == "``` yaml" { | ||
| inYamlBlock = true | ||
| } | ||
| if inYamlBlock && line == "```" { | ||
| inYamlBlock = false | ||
| } | ||
|
|
||
| if inYamlBlock && strings.HasPrefix(line, "tag: package-") { | ||
| version = strings.TrimSpace(strings.TrimPrefix(line, "tag: package-")) | ||
| break | ||
| } | ||
| } | ||
|
|
||
| // if version == "" { | ||
| // return "", fmt.Errorf("no version found in readme") | ||
| // } | ||
|
|
||
| // Those occur in sql, security, and synapse | ||
| // if strings.HasPrefix(version, "composite-") { | ||
| // return "", fmt.Errorf("composite versions are not supported yet") | ||
| // } | ||
| return map[Service]ApiVersion{Service(""): ApiVersion(version)}, nil | ||
| } | ||
|
|
||
| // func ReadAllDefaultVersionsFromReadmes(specBaseDir string) (map[string]string, error) { | ||
| // versions := make(map[string]string) | ||
|
|
||
| // pattern := filepath.Join(specBaseDir, "specification", "*", "resource-manager", "readme.md") | ||
| // files, err := filepath.Glob(pattern) | ||
| // if err != nil { | ||
| // return nil, err | ||
| // } | ||
|
|
||
| // for _, file := range files { | ||
| // f, err := os.Open(file) | ||
| // if err != nil { | ||
| // return nil, err | ||
| // } | ||
| // defer f.Close() | ||
|
|
||
| // pathParts := strings.Split(file, string(filepath.Separator)) | ||
| // moduleFolder := pathParts[len(pathParts)-3] | ||
|
|
||
| // version, err := ReadDefaultVersionFromReadme(f) | ||
| // if err != nil { | ||
| // return nil, err | ||
| // } | ||
| // versions[moduleFolder] = version | ||
| // } | ||
|
|
||
| // return versions, nil | ||
| // } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package openapi | ||
|
|
||
| import ( | ||
| "os" | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| func TestReadSimpleDefaultVersionFromReadme(t *testing.T) { | ||
| f, err := os.Open("testdata/quota-readme.md") | ||
| require.NoError(t, err) | ||
|
|
||
| expectedVersion := ApiVersion("2025-03-01") | ||
| versions, err := ReadDefaultVersionFromReadme(f) | ||
| require.NoError(t, err) | ||
| require.Len(t, versions, 1) | ||
| require.Contains(t, versions, Service("")) | ||
| require.Equal(t, expectedVersion, versions[""]) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at some more readme files, I think we need to do at least one more step of processing to determine what the version selection is.
Where there's an initial code block such as:
The tag will correspond with other, conditional code blocks such as:
The tag can be somewhat arbitrary, but the
input-filelist is the ultimate output we need.Overall, I think the parsing approach for the data from a readme file is as follows (though we could possibly short-cut some of this, given we're not needing to support user inputs on the tag to use):
Worked example
With the two blocks defined above, after parsing the first block would result in a state of:
When evaluating the second block, the value of
$(tag)would bepackage-preview-2024-06and the condition evaluates to true. Therefore the state after parsing the second block is:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will probably need to turn the list of files back into a list of resources with version instead to produce a lockfile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/Azure/autorest/blob/e691282a8919f9c850c2f77e6ba180ed1635e8de/packages/libs/configuration/src/configuration-manager/configuration-file.ts#L33-L57 🥳