77 "net/http"
88 "os"
99 "strings"
10+ "time"
1011)
1112
1213type PackageListResponse struct {
@@ -23,14 +24,73 @@ type PackageDetailsResponse struct {
2324 } `json:"package"`
2425}
2526
26- type ShopwareExtension struct {
27- Store map [string ]interface {} `yaml:"store" json:"store"` // Use interface{} to maintain flexibility
28- Build map [string ]interface {} `yaml:"build" json:"build"`
27+ type ShopwareExtensionMetadata struct {
28+ RepositoryUrl string `json:"repositoryUrl"`
29+ Ref string `json:"ref"`
30+ LatestCommitTime int `json:"latestCommitTime"`
2931}
3032
31- type ShopwareExtensionMetadata struct {
32- RepositoryUrl string `json:"repositoryUrl"`
33- Ref string `json:"ref"`
33+ type ShopwareExtensionIndex struct {
34+ Extensions map [string ]* ShopwareExtensionMetadata `json:"extensions"`
35+ GeneratedAt int `json:"generatedAt"`
36+ }
37+
38+ type GitHubClient struct {
39+ HTTPClient * http.Client
40+ Token string
41+ }
42+
43+ func (c * GitHubClient ) FetchFile (owner , repo , filePath string ) (* http.Response , error ) {
44+ githubAPIURL := fmt .Sprintf ("https://api.github.com/repos/%s/%s/contents/%s" , owner , repo , filePath )
45+ req , _ := http .NewRequest ("GET" , githubAPIURL , nil )
46+
47+ if c .Token != "" {
48+ req .Header .Set ("Authorization" , "token " + c .Token )
49+ }
50+
51+ return c .HTTPClient .Do (req )
52+ }
53+
54+ func (c * GitHubClient ) FetchLatestCommitTime (owner , repo string ) (int , error ) {
55+ githubAPIURL := fmt .Sprintf ("https://api.github.com/repos/%s/%s/commits?per_page=1" , owner , repo )
56+ req , _ := http .NewRequest ("GET" , githubAPIURL , nil )
57+
58+ if c .Token != "" {
59+ req .Header .Set ("Authorization" , "token " + c .Token )
60+ }
61+
62+ resp , err := c .HTTPClient .Do (req )
63+ if err != nil {
64+ return 0 , err
65+ }
66+ defer resp .Body .Close ()
67+
68+ if resp .StatusCode != http .StatusOK {
69+ return 0 , fmt .Errorf ("failed to fetch commits: status code %d" , resp .StatusCode )
70+ }
71+
72+ var commits []struct {
73+ Commit struct {
74+ Author struct {
75+ Date string `json:"date"`
76+ } `json:"author"`
77+ } `json:"commit"`
78+ }
79+
80+ if err := json .NewDecoder (resp .Body ).Decode (& commits ); err != nil {
81+ return 0 , err
82+ }
83+
84+ if len (commits ) == 0 {
85+ return 0 , fmt .Errorf ("no commits found" )
86+ }
87+
88+ commitTime , err := time .Parse (time .RFC3339 , commits [0 ].Commit .Author .Date )
89+ if err != nil {
90+ return 0 , err
91+ }
92+
93+ return int (commitTime .Unix ()), nil
3494}
3595
3696func main () {
@@ -49,6 +109,11 @@ func main() {
49109 }
50110
51111 packageData := make (map [string ]* ShopwareExtensionMetadata )
112+ // Initialize the GitHub client
113+ githubClient := & GitHubClient {
114+ HTTPClient : & http.Client {},
115+ Token : os .Getenv ("GITHUB_TOKEN" ),
116+ }
52117 // Iterate through each package to get the repository URL
53118 for _ , packageName := range packageList .PackageNames {
54119 detailsURL := fmt .Sprintf ("https://packagist.org/packages/%s.json" , packageName )
@@ -68,11 +133,12 @@ func main() {
68133 for _ , version := range packageDetails .Package .Versions {
69134 log .Printf ("Package: %s, Repository: %s\n " , packageName , version .Source .URL )
70135 if strings .Contains (version .Source .URL , "github.com" ) {
71- extension := checkShopwareExtensionFile (version .Source .URL )
136+ extension , commitTime := checkShopwareExtensionFile (version .Source .URL , githubClient )
72137 if extension {
73138 packageData [packageName ] = & ShopwareExtensionMetadata {
74- RepositoryUrl : version .Source .URL ,
75- Ref : detailsURL ,
139+ RepositoryUrl : version .Source .URL ,
140+ Ref : detailsURL ,
141+ LatestCommitTime : commitTime ,
76142 }
77143 }
78144 }
@@ -89,51 +155,42 @@ func main() {
89155
90156 jsonEncoder := json .NewEncoder (file )
91157 jsonEncoder .SetIndent ("" , " " )
92- if err := jsonEncoder .Encode (packageData ); err != nil {
158+ if err := jsonEncoder .Encode (ShopwareExtensionIndex {
159+ Extensions : packageData ,
160+ GeneratedAt : int (time .Now ().Unix ()),
161+ }); err != nil {
93162 log .Fatalf ("Failed to write JSON to file: %v" , err )
94163 }
95164
96165 log .Println ("Shopware extensions data written to shopware_extensions.json" )
97166}
98167
99- func checkShopwareExtensionFile (repositoryURL string ) bool {
100- // Extract the owner and repo from the GitHub URL
168+ func checkShopwareExtensionFile (repositoryURL string , client * GitHubClient ) (bool , int ) {
101169 parts := strings .Split (repositoryURL , "/" )
102170 if len (parts ) < 5 {
103171 log .Printf ("Invalid GitHub URL: %s" , repositoryURL )
104- return false
172+ return false , 0
105173 }
106174
107175 owner := parts [3 ]
108- repo := parts [4 ]
109- // Ensure to remove '.git' if it's included in the URL
110- repo = strings .TrimSuffix (repo , ".git" )
176+ repo := strings .TrimSuffix (parts [4 ], ".git" )
111177
112- // Use the GitHub API to fetch the file details
113- githubAPIURL := fmt .Sprintf ("https://api.github.com/repos/%s/%s/contents/.shopware-extension.yml" , owner , repo )
114- req , _ := http .NewRequest ("GET" , githubAPIURL , nil )
115-
116- token , ok := os .LookupEnv ("GITHUB_TOKEN" )
117- if ok {
118- req .Header .Set ("Authorization" , "token " + token )
119- }
120-
121- client := & http.Client {}
122- resp , err := client .Do (req )
178+ resp , err := client .FetchFile (owner , repo , ".shopware-extension.yml" )
123179 if err != nil {
124180 log .Printf ("Failed to fetch .shopware-extension.yml file for %s/%s: %v" , owner , repo , err )
125- return false
181+ return false , 0
126182 }
127183 defer resp .Body .Close ()
128184
129- if resp .StatusCode == http .StatusOK {
130- log .Printf (".shopware-extension.yml found in %s/%s\n " , owner , repo )
131- return true
132- } else if resp .StatusCode == http .StatusNotFound {
133- log .Printf (".shopware-extension.yml not found in %s/%s\n " , owner , repo )
134- } else {
185+ exists := resp .StatusCode == http .StatusOK
186+ if ! exists && resp .StatusCode != http .StatusNotFound {
135187 log .Printf ("Failed to fetch .shopware-extension.yml for %s/%s: %v" , owner , repo , err )
136188 }
137189
138- return false
190+ commitTime , err := client .FetchLatestCommitTime (owner , repo )
191+ if err != nil {
192+ log .Printf ("Failed to fetch latest commit time for %s/%s: %v" , owner , repo , err )
193+ }
194+
195+ return exists , commitTime
139196}
0 commit comments