use of hudson.PluginWrapper in project blueocean-plugin by jenkinsci.
the class JenkinsJSExtensions method refreshCache.
private static synchronized void refreshCache(List<PluginWrapper> latestPlugins) {
if (!latestPlugins.equals(pluginCache)) {
pluginCache.clear();
pluginCache.addAll(latestPlugins);
refreshCache(pluginCache);
}
for (PluginWrapper pluginWrapper : pluginCache) {
// skip if not active
if (!pluginWrapper.isActive()) {
continue;
}
// skip probing plugin if already read
if (jsExtensionCache.get(pluginWrapper.getLongName()) != null) {
continue;
}
try {
Enumeration<URL> dataResources = pluginWrapper.classLoader.getResources("jenkins-js-extension.json");
boolean hasDefinedExtensions = false;
while (dataResources.hasMoreElements()) {
URL dataRes = dataResources.nextElement();
LOGGER.debug("Reading 'jenkins-js-extension.json' from '{}'.", dataRes);
try (InputStream dataResStream = dataRes.openStream()) {
Map<String, Object> extensionData = mapper.readValue(dataResStream, Map.class);
String pluginId = getGav(extensionData);
if (pluginId != null) {
// future/past iteration of this loop.
if (!pluginId.equals(pluginWrapper.getShortName())) {
continue;
}
} else {
LOGGER.error(String.format("Plugin %s JS extension has missing hpiPluginId", pluginWrapper.getLongName()));
continue;
}
List<Map> extensions = (List<Map>) extensionData.get(PLUGIN_EXT);
if (extensions != null) {
for (Map extension : extensions) {
try {
String type = (String) extension.get("type");
if (type != null) {
BlueExtensionClassContainer extensionClassContainer = Jenkins.getInstance().getExtensionList(BlueExtensionClassContainer.class).get(0);
Map classInfo = (Map) mergeObjects(extensionClassContainer.get(type));
List classInfoClasses = (List) classInfo.get("_classes");
classInfoClasses.add(0, type);
extension.put("_class", type);
extension.put("_classes", classInfoClasses);
}
} catch (Exception e) {
LOGGER.error("An error occurred when attempting to read type information from jenkins-js-extension.json from: " + dataRes, e);
}
}
}
extensionData.put(PLUGIN_VER, pluginWrapper.getVersion());
jsExtensionCache.put(pluginId, mergeObjects(extensionData));
hasDefinedExtensions = true;
}
}
if (!hasDefinedExtensions) {
// Manufacture an entry for all plugins that do not have any defined
// extensions. This adds some info about the plugin that the UI might
// need access to e.g. the plugin version.
Map<String, Object> extensionData = new LinkedHashMap<>();
extensionData.put(PLUGIN_ID, pluginWrapper.getShortName());
extensionData.put(PLUGIN_VER, pluginWrapper.getVersion());
extensionData.put(PLUGIN_EXT, Collections.emptyList());
jsExtensionCache.put(pluginWrapper.getShortName(), mergeObjects(extensionData));
}
} catch (IOException e) {
LOGGER.error(String.format("Error locating jenkins-js-extension.json for plugin %s", pluginWrapper.getLongName()));
}
}
}
use of hudson.PluginWrapper in project blueocean-plugin by jenkinsci.
the class RunBundleWatches method startBundleWatches.
@Initializer(after = InitMilestone.JOB_LOADED)
public static void startBundleWatches() {
if (!isEnabled || Boolean.getBoolean("blueocean.features.BUNDLE_WATCH_SKIP")) {
return;
}
System.out.println("Running in development mode, watching bundles...");
int buildNumber = 0;
List<PluginWrapper> plugins = Jenkins.getInstance().pluginManager.getPlugins();
;
for (final PluginWrapper p : plugins) {
try {
final File projectDir = findPluginWorkDir(new File(p.baseResourceURL.getPath()));
if (projectDir != null) {
final String path = projectDir.getCanonicalPath();
final File packageFile = new File(projectDir, "package.json");
final BundleBuild build = new BundleBuild();
build.name = p.getShortName();
System.out.println("---- Watching " + build.name + " in: " + path);
JSONObject packageJson = JSONObject.fromObject(FileUtils.readFileToString(packageFile));
final String[] npmCommand = { "mvnbuild", null };
if (packageJson.has("scripts")) {
JSONObject scripts = packageJson.getJSONObject("scripts");
if (scripts.has("mvnbuild:fast")) {
npmCommand[0] = "mvnbuild:fast";
}
if (scripts.has("watch")) {
npmCommand[1] = "watch";
}
if (scripts.has("bundle:watch")) {
npmCommand[1] = "bundle:watch";
}
}
// Leaving this code here because we may want to enable "watch" behavior
if ("watch".equals(npmCommand[1]) && Boolean.getBoolean("blueocean.features.NATIVE_NPM_WATCH")) {
build.thread = new Thread() {
public void run() {
long backOff = DEFAULT_BACK_OFF;
while (true) {
try {
Map<String, String> env = new HashMap<>(System.getenv());
String[] command;
if (SystemUtils.IS_OS_WINDOWS) {
command = new String[] { "cmd", "/C", "npm", "run", npmCommand[1] };
} else {
command = new String[] { "bash", "-c", "${0} ${1+\"$@\"}", "npm", "run", npmCommand[1] };
}
ProcessBuilder pb = new ProcessBuilder(Arrays.asList(command)).redirectErrorStream(true).directory(projectDir);
if (SystemUtils.IS_OS_WINDOWS) {
pb.environment().put("Path", new File(projectDir, "node").getCanonicalPath() + ";" + env.get("Path"));
} else {
pb.environment().put("PATH", new File(projectDir, "node").getCanonicalPath() + ":" + env.get("PATH"));
}
final Process process = pb.start();
build.destructor = new Destructor() {
@Override
public void destroy() {
if (process.isAlive()) {
try {
process.destroy();
process.destroyForcibly();
} catch (Exception e) {
// ignore
}
}
build.destructor = null;
}
};
InputStream in = process.getInputStream();
try (BufferedReader rdr = new BufferedReader(new InputStreamReader(in, "utf-8"))) {
String line;
long startMillis = 0;
while ((line = rdr.readLine()) != null) {
if (line.contains("Starting 'log-env'")) {
startMillis = System.currentTimeMillis();
build.buildCount.incrementAndGet();
build.logLines.clear();
System.out.println("---- Rebuilding: " + path);
}
// add here because we clear when starting a new build
build.logLines.add(new LogLine(System.currentTimeMillis(), line));
if (line.contains("missing script: bundle:watch")) {
System.out.println("---- Unable to find script 'bundle:watch' in: " + packageFile.getCanonicalPath());
// don't retry this case
build.thread = null;
return;
}
// if (line.contains("Finished 'bundle:watch'") || line.contains("Finished 'bundle'")) {
if (line.contains("Finished 'bundle'")) {
if (build.hasError) {
for (LogLine l : build.logLines) {
System.out.println(l.text);
}
build.hasError = false;
}
long time = System.currentTimeMillis() - startMillis;
build.lastBuildTimeMillis = time;
build.buildCount.decrementAndGet();
System.out.println("---- Rebuilt " + build.name + " in: " + time + "ms");
}
if (line.contains("Failed at the")) {
System.out.println("---- Failed to build: " + build.name);
build.buildCount.decrementAndGet();
for (LogLine l : build.logLines) {
System.out.println(l.text);
}
}
if (line.contains("error") || line.contains("Error") || line.contains("ERROR")) {
build.hasError = true;
}
}
}
} catch (RuntimeException e) {
// Thanks findbugs
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
build.destructor = null;
try {
Thread.sleep(backOff);
backOff = (long) Math.floor(backOff * 2);
} catch (InterruptedException e) {
// nothing to see here
backOff = DEFAULT_BACK_OFF;
}
}
}
};
build.thread.setDaemon(true);
build.thread.setName("Watching " + build.name + " for changes in: " + path);
build.thread.start();
} else {
// Might be better to be "/src/main"
// but JDL and core js currently have a different structure
// limiting the scope is handled with the PROJECT_PATH_FILTER and EXTENSIONS_TO_CAUSE_REBUILD
final File watchDir = projectDir;
final Path watchPath = watchDir.toPath();
// java nio watch, run `mvnbuild` instead
Thread fileWatchThread = new Thread() {
volatile Process buildProcess;
@Override
public void run() {
build.destructor = new Destructor() {
@Override
public void destroy() {
if (buildProcess != null && buildProcess.isAlive()) {
try {
buildProcess.destroy();
if (buildProcess != null && buildProcess.isAlive()) {
buildProcess.destroyForcibly();
}
} catch (Exception e) {
// ignore
e.printStackTrace();
}
}
buildProcess = null;
build.logLines.add(new LogLine("Process restarted."));
}
};
RecursivePathWatcher watcher = new RecursivePathWatcher(watchPath, PROJECT_PATH_FILTER);
watcher.start(new RecursivePathWatcher.PathEventHandler() {
@Override
public void accept(final RecursivePathWatcher.Event event, final Path modified) {
// only rebuild for certain types of files
if (!EXTENSIONS_TO_CAUSE_REBUILD.matcher(modified.toString()).matches()) {
return;
}
// kill any currently running builds
build.destructor.destroy();
// run in a separate thread so we can pick up changes and kill any existing
// running processes
build.thread = new Thread() {
@Override
public void run() {
build.buildCount.incrementAndGet();
long startMillis = System.currentTimeMillis();
try {
Map<String, String> env = new HashMap<>(System.getenv());
String[] command;
if (SystemUtils.IS_OS_WINDOWS) {
command = new String[] { "cmd", "/C", "npm", "run", npmCommand[0] };
} else {
command = new String[] { "bash", "-c", "${0} ${1+\"$@\"}", "npm", "run", npmCommand[0] };
}
System.out.println("---- Rebuilding: " + build.name + " due to change in: " + watchPath.relativize(modified));
ProcessBuilder pb = new ProcessBuilder(Arrays.asList(command)).redirectErrorStream(true).directory(projectDir);
if (SystemUtils.IS_OS_WINDOWS) {
pb.environment().put("Path", new File(projectDir, "node").getCanonicalPath() + ";" + env.get("Path"));
} else {
pb.environment().put("PATH", new File(projectDir, "node").getCanonicalPath() + ":" + env.get("PATH"));
}
buildProcess = pb.start();
InputStream in = buildProcess.getInputStream();
try (BufferedReader rdr = new BufferedReader(new InputStreamReader(in, "utf-8"))) {
String line;
while ((line = rdr.readLine()) != null) {
build.logLines.add(new LogLine(System.currentTimeMillis(), line));
if (line.contains("missing script: mvnbuild")) {
build.hasError = true;
}
if (line.contains("Failed at the")) {
build.hasError = true;
}
if (line.contains("error") || line.contains("Error") || line.contains("ERROR")) {
build.hasError = true;
}
}
}
// If process wasn't killed or error, output the rebuild info
if (buildProcess != null && buildProcess.waitFor() == 0) {
build.lastBuildTimeMillis = System.currentTimeMillis() - startMillis;
System.out.println("---- Rebuilt " + build.name + " in: " + build.lastBuildTimeMillis + "ms");
}
} catch (RuntimeException e) {
// Thanks findbugs
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
buildProcess = null;
build.buildCount.decrementAndGet();
if (build.hasError) {
for (LogLine l : build.logLines) {
System.out.println(l.text);
}
build.hasError = false;
}
// Don't use excessive memory:
build.logLines.clear();
}
}
};
build.thread.setDaemon(true);
build.thread.setName("Building: " + path);
build.thread.start();
}
});
}
};
fileWatchThread.setDaemon(true);
fileWatchThread.setName("Watching " + build.name + " for changes in: " + path);
fileWatchThread.start();
}
builds.add(build);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
use of hudson.PluginWrapper in project badge-plugin by jenkinsci.
the class BadgeAction method getIconPath.
public static String getIconPath(String icon) {
if (icon == null)
return null;
if (icon.startsWith("/"))
return icon;
// Try plugin images dir, fallback to Hudson images dir
Jenkins jenkins = Jenkins.getInstance();
PluginWrapper wrapper = jenkins.getPluginManager().getPlugin(BadgePlugin.class);
boolean pluginIconExists = (wrapper != null) && new File(wrapper.baseResourceURL.getPath() + "/images/" + icon).exists();
return pluginIconExists ? "/plugin/" + wrapper.getShortName() + "/images/" + icon : Hudson.RESOURCE_PATH + "/images/16x16/" + icon;
}
use of hudson.PluginWrapper in project phabricator-jenkins-plugin by uber.
the class PhabricatorPlugin method getIconPath.
public static String getIconPath(String icon) {
if (icon == null) {
return null;
}
if (icon.startsWith("/")) {
return icon;
}
// Try plugin images dir, fallback to Hudson images dir
PluginWrapper wrapper = Jenkins.getInstance().getPluginManager().getPlugin(PhabricatorPlugin.class);
boolean pluginIconExists = (wrapper != null) && new File(wrapper.baseResourceURL.getPath() + "/images/" + icon).exists();
return pluginIconExists ? "/plugin/" + wrapper.getShortName() + "/images/" + icon : Jenkins.RESOURCE_PATH + "/images/16x16/" + icon;
}
use of hudson.PluginWrapper in project blueocean-plugin by jenkinsci.
the class BlueI18nTest method test_200_response_caching.
@Test
public void test_200_response_caching() {
PluginWrapper plugin = BlueI18n.getPlugin("blueocean-dashboard");
if (plugin == null) {
// Skip. See waitForPluginLoaded() above.
return;
}
String dashboardVersion = plugin.getVersion();
Map<String, Object> response1 = get("/blue/rest/i18n/blueocean-dashboard/" + dashboardVersion + "/jenkins.plugins.blueocean.dashboard.Messages/de", HttpServletResponse.SC_OK, Map.class);
Map<String, Object> response2 = get("/blue/rest/i18n/blueocean-dashboard/" + dashboardVersion + "/jenkins.plugins.blueocean.dashboard.Messages/de", HttpServletResponse.SC_OK, Map.class);
// Make sure the second comes from the cache. The "cache-timestamp" field
// will be different if it didn't, resulting in an assert failure.
Assert.assertEquals(response1, response2);
}
Aggregations